planner: fix the wrong partition pruning when some conditions is out of range (#28296)

This commit is contained in:
Chengpeng Yan
2021-10-14 15:57:28 +08:00
committed by GitHub
parent bd68045ffb
commit fdcf122f01
2 changed files with 15 additions and 7 deletions

View File

@ -489,13 +489,21 @@ func (s *testPartitionPruneSuit) TestRangePartitionPredicatePruner(c *C) {
}
}
func (s *testPartitionPruneSuit) TestIssue26551(c *C) {
func (s *testPartitionPruneSuit) TestHashPartitionPruning(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("set @@tidb_partition_prune_mode='static'")
tk.MustExec("USE test;")
tk.MustExec("DROP TABLE IF EXISTS t;")
tk.MustExec("CREATE TABLE t (`COL1` int, `COL3` bigint) PARTITION BY HASH ((`COL1` * `COL3`))PARTITIONS 13;")
tk.MustQuery("explain format = 'brief' SELECT * FROM t WHERE col3 =2659937067964964513 and col1 = 783367513002;").Check(testkit.Rows(
"TableDual 0.00 root rows:0"))
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1690 BIGINT value is out of range in '(test.t.col1 * test.t.col3)'"))
tk.MustQuery("SELECT * FROM t WHERE col3 =2659937067964964513 and col1 = 783367513002;").Check(testkit.Rows())
tk.MustExec("drop table if exists t;")
tk.MustExec("CREATE TABLE `t` (" +
"`COL1` int NOT NULL DEFAULT '25' COMMENT 'NUMERIC PK'," +
"`COL3` bigint NOT NULL," +
"PRIMARY KEY (`COL1`,`COL3`)" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin " +
"PARTITION BY HASH ((`COL1` * `COL3`))" +
"PARTITIONS 13;")
tk.MustExec("insert into t(col1, col3) values(0, 3522101843073676459);")
tk.MustQuery("SELECT col1, COL3 FROM t WHERE COL1 IN (0,14158354938390,0) AND COL3 IN (3522101843073676459,-2846203247576845955,838395691793635638);").Check(testkit.Rows("0 3522101843073676459"))
}

View File

@ -151,7 +151,8 @@ func (s *partitionProcessor) findUsedPartitions(ctx sessionctx.Context, tbl tabl
highLowVals = append(highLowVals, r.LowVal...)
pos, isNull, err := pe.EvalInt(ctx, chunk.MutRowFromDatums(highLowVals).ToRow())
if err != nil {
return nil, nil, err
// If we failed to get the point position, we can just skip and ignore it.
continue
}
if isNull {
pos = 0
@ -329,8 +330,7 @@ func (s *partitionProcessor) processHashPartition(ds *DataSource, pi *model.Part
}
used, err := s.pruneHashPartition(ds.SCtx(), ds.table, ds.partitionNames, ds.allConds, ds.TblCols, names)
if err != nil {
// Just report warning and generate the tableDual
ds.SCtx().GetSessionVars().StmtCtx.AppendWarning(err)
return nil, err
}
if used != nil {
return s.makeUnionAllChildren(ds, pi, convertToRangeOr(used, pi))