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

planner: fix the problem of using enum like 'x%' to build the wrong range (#27267) #27289

Merged
merged 7 commits into from
Aug 17, 2021
Merged
2 changes: 1 addition & 1 deletion ddl/db_partition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ func (s *testIntegrationSuite5) TestAlterTableDropPartitionByList(c *C) {
);`)
tk.MustExec(`insert into t values (1),(3),(5),(null)`)
tk.MustExec(`alter table t drop partition p1`)
tk.MustQuery("select * from t").Check(testkit.Rows("1", "5", "<nil>"))
tk.MustQuery("select * from t").Sort().Check(testkit.Rows("1", "5", "<nil>"))
ctx := tk.Se.(sessionctx.Context)
is := domain.GetDomain(ctx).InfoSchema()
tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
Expand Down
39 changes: 39 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4201,3 +4201,42 @@ func (s *testIntegrationSuite) TestOutputSkylinePruningInfo(c *C) {
tk.MustQuery("show warnings").Check(testkit.Rows(output[i].Warnings...))
}
}

func (s *testIntegrationSuite) TestIssues27130(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")

tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1( a enum('y','b','Abc','null'),b enum('y','b','Abc','null'),key(a));")
tk.MustQuery(`explain format=brief select * from t1 where a like "A%"`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
"└─Selection 8000.00 cop[tikv] like(test.t1.a, \"A%\", 92)",
" └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
))
tk.MustQuery(`explain format=brief select * from t1 where b like "A%"`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
"└─Selection 8000.00 cop[tikv] like(test.t1.b, \"A%\", 92)",
" └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
))

tk.MustExec("drop table if exists t2")
tk.MustExec("create table t2( a enum('y','b','Abc','null'),b enum('y','b','Abc','null'),key(a, b));")
tk.MustQuery(`explain format=brief select * from t2 where a like "A%"`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
"└─Selection 8000.00 cop[tikv] like(test.t2.a, \"A%\", 92)",
" └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
))
tk.MustQuery(`explain format=brief select * from t2 where a like "A%" and b like "A%"`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
"└─Selection 8000.00 cop[tikv] like(test.t2.a, \"A%\", 92), like(test.t2.b, \"A%\", 92)",
" └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
))

tk.MustExec("drop table if exists t3")
tk.MustExec("create table t3( a int,b enum('y','b','Abc','null'), c enum('y','b','Abc','null'),key(a, b, c));")
tk.MustQuery(`explain format=brief select * from t3 where a = 1 and b like "A%"`).Check(testkit.Rows(
"IndexReader 8.00 root index:Selection",
"└─Selection 8.00 cop[tikv] like(test.t3.b, \"A%\", 92)",
" └─IndexRangeScan 10.00 cop[tikv] table:t3, index:a(a, b, c) range:[1,1], keep order:false, stats:pseudo",
))
}
11 changes: 11 additions & 0 deletions util/ranger/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package ranger

import (
"github.com/pingcap/parser/ast"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb/expression"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/collate"
Expand Down Expand Up @@ -144,12 +145,22 @@ func (c *conditionChecker) checkLikeFunc(scalar *expression.ScalarFunction) bool
return false
}
if patternStr[i] == '%' {
// We currently do not support using `enum like 'xxx%'` to build range
// see https://github.com/pingcap/tidb/issues/27130 for more details
if scalar.GetArgs()[0].GetType().Tp == mysql.TypeEnum {
return false
}
if i != len(patternStr)-1 {
c.shouldReserve = true
}
break
}
if patternStr[i] == '_' {
// We currently do not support using `enum like 'xxx_'` to build range
// see https://github.com/pingcap/tidb/issues/27130 for more details
if scalar.GetArgs()[0].GetType().Tp == mysql.TypeEnum {
return false
}
c.shouldReserve = true
break
}
Expand Down