Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

executor: fix select wrong partition for hash partition table #50430

Merged
merged 4 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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))
Copy link
Contributor Author

@Defined2014 Defined2014 Jan 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ref https://github.com/pingcap/tidb/pull/49853/files#diff-4990f33f249ec8823358eef763ccfccd9284b58d4942eba35b7b4e22c16b1a33L193, let it same as before.

Although I think the behaviour of hash function is strange, it already works for a long time. Just change it back.

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;