Skip to content

Commit

Permalink
executor: fix select wrong partition for hash partition table (#50430)
Browse files Browse the repository at this point in the history
close #50427
  • Loading branch information
Defined2014 authored Jan 16, 2024
1 parent ac71239 commit 9fb89b0
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
5 changes: 1 addition & 4 deletions pkg/planner/core/rule_partition_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,30 +181,27 @@ func (s *partitionProcessor) getUsedHashPartitions(ctx sessionctx.Context,
}

var rangeScalar uint64
var offset int64
if mysql.HasUnsignedFlag(col.RetType.GetFlag()) {
// Avoid integer overflow
if uint64(posHigh) < uint64(posLow) {
rangeScalar = 0
} else {
rangeScalar = uint64(posHigh) - uint64(posLow)
offset = int64(uint64(posLow) % uint64(numPartitions))
}
} else {
// Avoid integer overflow
if posHigh < posLow {
rangeScalar = 0
} else {
rangeScalar = uint64(posHigh - posLow)
offset = posLow % int64(numPartitions)
}
}

// if range is less than the number of partitions, there will be unused partitions we can prune out.
if rangeScalar < uint64(numPartitions) && !highIsNull && !lowIsNull {
var i int64
for i = 0; i <= int64(rangeScalar); i++ {
idx := mathutil.Abs(offset+i) % int64(numPartitions)
idx := mathutil.Abs((posLow + i) % int64(numPartitions))
if len(partitionNames) > 0 && !s.findByName(partitionNames, pi.Definitions[idx].Name.L) {
continue
}
Expand Down
18 changes: 17 additions & 1 deletion tests/integrationtest/r/executor/partition/issues.result
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ CREATE TABLE `t` (
PRIMARY KEY (`col_51`) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY HASH (`col_51`) PARTITIONS 5;
insert into t values (9223372036854775807), (9223372036854775808), (9223372036854775809);
insert into t values (9223372036854775807), (9223372036854775808), (9223372036854775809), (9223372036854775812), (9223372036854775813);
analyze table t;
desc SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN 9223372036854775807 AND 9223372036854775808;
id estRows task access object operator info
Expand All @@ -475,6 +475,14 @@ SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN 9223372036854775807 AND 92233720368
col_51
9223372036854775807
9223372036854775808
explain select * from t where col_51 between 9223372036854775812 and 9223372036854775813;
id estRows task access object operator info
TableReader_6 2.00 root partition:p3,p4 data:TableRangeScan_5
└─TableRangeScan_5 2.00 cop[tikv] table:t range:[9223372036854775812,9223372036854775813], keep order:false
select * from t where col_51 between 9223372036854775812 and 9223372036854775813;
col_51
9223372036854775812
9223372036854775813
drop table if exists t;
CREATE TABLE `t` (
`col_51` bigint(20) NOT NULL,
Expand Down Expand Up @@ -557,3 +565,11 @@ col_29
-1
0
1
explain select * from t where col_29 between -7 and -6;
id estRows task access object operator info
TableReader_7 1.00 root partition:p0,p6 data:Selection_6
└─Selection_6 1.00 cop[tikv] ge(executor__partition__issues.t.col_29, -7), le(executor__partition__issues.t.col_29, -6)
└─TableFullScan_5 48.00 cop[tikv] table:t keep order:false
select * from t where col_29 between -7 and -6;
col_29
-6
11 changes: 10 additions & 1 deletion tests/integrationtest/t/executor/partition/issues.test
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,16 @@ CREATE TABLE `t` (
PRIMARY KEY (`col_51`) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY HASH (`col_51`) PARTITIONS 5;
insert into t values (9223372036854775807), (9223372036854775808), (9223372036854775809);
insert into t values (9223372036854775807), (9223372036854775808), (9223372036854775809), (9223372036854775812), (9223372036854775813);
analyze table t;
desc SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN 9223372036854775807 AND 9223372036854775808;
--sorted_result
SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN 9223372036854775807 AND 9223372036854775808;

explain select * from t where col_51 between 9223372036854775812 and 9223372036854775813;
--sorted_result
select * from t where col_51 between 9223372036854775812 and 9223372036854775813;

drop table if exists t;
CREATE TABLE `t` (
`col_51` bigint(20) NOT NULL,
Expand Down Expand Up @@ -328,3 +332,8 @@ explain select * from t where col_29 between -2 and 1;
--sorted_result
select * from t where col_29 between -2 and 1;

# TestIssue50427
explain select * from t where col_29 between -7 and -6;
--sorted_result
select * from t where col_29 between -7 and -6;

0 comments on commit 9fb89b0

Please sign in to comment.