Skip to content

Commit

Permalink
planner: fix stmt for partition table
Browse files Browse the repository at this point in the history
  • Loading branch information
Defined2014 committed Dec 27, 2023
1 parent 75b451c commit eb2fd01
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 12 deletions.
59 changes: 47 additions & 12 deletions pkg/planner/core/rule_partition_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,31 @@ func (s *partitionProcessor) getUsedHashPartitions(ctx sessionctx.Context,
posHigh--
}

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

// if range is less than the number of partitions, there will be unused partitions we can prune out.
if rangeScalar < float64(numPartitions) && !highIsNull && !lowIsNull {
for i := posLow; i <= posHigh; i++ {
idx := mathutil.Abs(i % int64(pi.Num))
if rangeScalar < uint64(numPartitions) && !highIsNull && !lowIsNull {
var i int64
for i = 0; i <= int64(rangeScalar); i++ {
idx := (offset + i) % int64(numPartitions)
if len(partitionNames) > 0 && !s.findByName(partitionNames, pi.Definitions[idx].Name.L) {
continue
}
Expand Down Expand Up @@ -280,26 +294,47 @@ func (s *partitionProcessor) getUsedKeyPartitions(ctx sessionctx.Context,
posHigh--
}

var rangeScalar float64
var rangeScalar uint64
if mysql.HasUnsignedFlag(col.RetType.GetFlag()) {
rangeScalar = float64(uint64(posHigh)) - float64(uint64(posLow)) // use float64 to avoid integer overflow
// Avoid integer overflow
if uint64(posHigh) < uint64(posLow) {
rangeScalar = 0
} else {
rangeScalar = uint64(posHigh) - uint64(posLow)
}
} else {
rangeScalar = float64(posHigh) - float64(posLow) // use float64 to avoid integer overflow
// Avoid integer overflow
if posHigh < posLow {
rangeScalar = 0
} else {
rangeScalar = uint64(posHigh-posLow)
}
}

// if range is less than the number of partitions, there will be unused partitions we can prune out.
if rangeScalar < float64(pi.Num) && !highIsNull && !lowIsNull {
for i := posLow; i <= posHigh; i++ {
d := types.NewIntDatum(i)
if rangeScalar < pi.Num && !highIsNull && !lowIsNull {
m := make(map[int]struct{})
for i := 0; i <= int(rangeScalar); i++ {
var d types.Datum
if mysql.HasUnsignedFlag(col.RetType.GetFlag()) {
d = types.NewUintDatum(uint64(posLow) + uint64(i))
} else {
d = types.NewIntDatum(posLow + int64(i))
}
idx, err := pe.LocateKeyPartition(pi.Num, []types.Datum{d})
if err != nil {
// If we failed to get the point position, we can just skip and ignore it.
continue
}
if _, ok := m[idx]; ok {
// Keys maybe in a same partition, we should skip.
continue
}
if len(partitionNames) > 0 && !s.findByName(partitionNames, pi.Definitions[idx].Name.L) {
continue
}
used = append(used, idx)
m[idx] = struct{}{}
}
continue
}
Expand Down
76 changes: 76 additions & 0 deletions tests/integrationtest/r/executor/partition/issues.result
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,79 @@ IndexJoin_20 0.80 root inner join, inner:TableReader_19, outer key:executor__pa
└─TableRangeScan_17 0.80 cop[tikv] table:c range: decided by [eq(executor__partition__issues.c.txt_account_id, executor__partition__issues.t.txn_account_id) eq(executor__partition__issues.c.serial_id, executor__partition__issues.t.serial_id) eq(executor__partition__issues.c.occur_trade_date, 2022-11-17 00:00:00.000000)], keep order:false
set @@tidb_opt_advanced_join_hint=default;
set tidb_partition_prune_mode=default;
drop table if exists t;
CREATE TABLE `t` (
`col_51` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`col_51`) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY `idx_28` (`col_51`),
KEY `idx_29` (`col_51`),
KEY `idx_31` (`col_51`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY HASH (`col_51`) PARTITIONS 5;
insert into t values (9223372036854775807), (9223372036854775808), (9223372036854775809);
analyze table t;
desc SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN 9223372036854775807 AND 9223372036854775808;
id estRows task access object operator info
TableReader_6 2.00 root partition:p2,p3 data:TableRangeScan_5
└─TableRangeScan_5 2.00 cop[tikv] table:t range:[9223372036854775807,9223372036854775808], keep order:false
SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN 9223372036854775807 AND 9223372036854775808;
col_51
9223372036854775807
9223372036854775808
drop table if exists t;
CREATE TABLE `t` (
`col_51` bigint(20) NOT NULL,
PRIMARY KEY (`col_51`) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY `idx_28` (`col_51`),
KEY `idx_29` (`col_51`),
KEY `idx_31` (`col_51`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY HASH (`col_51`) PARTITIONS 5;
insert into t values (9223372036854775807), (-9223372036854775808);
analyze table t;
desc SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN -9223372036854775808 AND 9223372036854775807;
id estRows task access object operator info
TableReader_6 2.00 root partition:all data:TableFullScan_5
└─TableFullScan_5 2.00 cop[tikv] table:t keep order:false
SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN -9223372036854775808 AND 9223372036854775807;
col_51
-9223372036854775808
9223372036854775807
drop table if exists t;
CREATE TABLE `t` (
`col_51` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`col_51`) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY `idx_28` (`col_51`),
KEY `idx_29` (`col_51`),
KEY `idx_31` (`col_51`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY KEY (`col_51`) PARTITIONS 5;
insert into t values (9223372036854775807), (9223372036854775808), (9223372036854775809);
analyze table t;
desc SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN 9223372036854775807 AND 9223372036854775808;
id estRows task access object operator info
TableReader_6 2.00 root partition:p2 data:TableRangeScan_5
└─TableRangeScan_5 2.00 cop[tikv] table:t range:[9223372036854775807,9223372036854775808], keep order:false
SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN 9223372036854775807 AND 9223372036854775808;
col_51
9223372036854775807
9223372036854775808
drop table if exists t;
CREATE TABLE `t` (
`col_51` bigint(20) NOT NULL,
PRIMARY KEY (`col_51`) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY `idx_28` (`col_51`),
KEY `idx_29` (`col_51`),
KEY `idx_31` (`col_51`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY KEY (`col_51`) PARTITIONS 5;
insert into t values (9223372036854775807), (-9223372036854775808);
analyze table t;
desc SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN -9223372036854775808 AND 9223372036854775807;
id estRows task access object operator info
TableReader_6 2.00 root partition:all data:TableFullScan_5
└─TableFullScan_5 2.00 cop[tikv] table:t keep order:false
SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN -9223372036854775808 AND 9223372036854775807;
col_51
-9223372036854775808
9223372036854775807
64 changes: 64 additions & 0 deletions tests/integrationtest/t/executor/partition/issues.test
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,67 @@ from
and c.occur_trade_date = '2022-11-17' and c.serial_id = t.serial_id;
set @@tidb_opt_advanced_join_hint=default;
set tidb_partition_prune_mode=default;


# TestIssue49842
## For Hash partition
drop table if exists t;
CREATE TABLE `t` (
`col_51` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`col_51`) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY `idx_28` (`col_51`),
KEY `idx_29` (`col_51`),
KEY `idx_31` (`col_51`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY HASH (`col_51`) PARTITIONS 5;
insert into t values (9223372036854775807), (9223372036854775808), (9223372036854775809);
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;

drop table if exists t;
CREATE TABLE `t` (
`col_51` bigint(20) NOT NULL,
PRIMARY KEY (`col_51`) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY `idx_28` (`col_51`),
KEY `idx_29` (`col_51`),
KEY `idx_31` (`col_51`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY HASH (`col_51`) PARTITIONS 5;
insert into t values (9223372036854775807), (-9223372036854775808);
analyze table t;
desc SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN -9223372036854775808 AND 9223372036854775807;
--sorted_result
SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN -9223372036854775808 AND 9223372036854775807;

## For Key partition
drop table if exists t;
CREATE TABLE `t` (
`col_51` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`col_51`) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY `idx_28` (`col_51`),
KEY `idx_29` (`col_51`),
KEY `idx_31` (`col_51`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY KEY (`col_51`) PARTITIONS 5;
insert into t values (9223372036854775807), (9223372036854775808), (9223372036854775809);
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;

drop table if exists t;
CREATE TABLE `t` (
`col_51` bigint(20) NOT NULL,
PRIMARY KEY (`col_51`) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY `idx_28` (`col_51`),
KEY `idx_29` (`col_51`),
KEY `idx_31` (`col_51`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY KEY (`col_51`) PARTITIONS 5;
insert into t values (9223372036854775807), (-9223372036854775808);
analyze table t;
desc SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN -9223372036854775808 AND 9223372036854775807;
--sorted_result
SELECT * FROM `t` WHERE `t`.`col_51` BETWEEN -9223372036854775808 AND 9223372036854775807;

0 comments on commit eb2fd01

Please sign in to comment.