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: rebuild range when the range is empty #30003

Merged
merged 43 commits into from
Nov 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
4082da9
planner: rebuild range when the range is empty
Reminiscent Nov 22, 2021
b40f8d9
Merge branch 'master' of github.com:pingcap/tidb into issue#29993
Reminiscent Nov 22, 2021
c0d662e
fix typo
Reminiscent Nov 22, 2021
b1fd3e7
Merge branch 'master' into issue#29993
qw4990 Nov 22, 2021
98f794c
Merge branch 'master' of github.com:pingcap/tidb into issue#29993
Reminiscent Nov 23, 2021
e10493a
fix ut
Reminiscent Nov 23, 2021
ed07e57
Merge remote-tracking branch 'origin/issue#29993' into issue#29993
Reminiscent Nov 23, 2021
d15ada9
Merge branch 'master' into issue#29993
Reminiscent Nov 23, 2021
934f846
Merge branch 'master' into issue#29993
Reminiscent Nov 23, 2021
5314597
Merge branch 'master' into issue#29993
Reminiscent Nov 23, 2021
554649d
Merge branch 'master' into issue#29993
qw4990 Nov 23, 2021
90f3d2a
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
26ebbf8
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
ee3bfc1
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
cfe8502
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
090f58c
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
c56a4b1
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
3b71e7b
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
3ac8617
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
b8fe9ee
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
0fd1c8c
add more test cases
Reminiscent Nov 24, 2021
6808a0f
Merge branch 'master' of github.com:pingcap/tidb into issue#29993
Reminiscent Nov 24, 2021
5b41e1b
Merge remote-tracking branch 'origin/issue#29993' into issue#29993
Reminiscent Nov 24, 2021
78ba85c
remove the duplicate test
Reminiscent Nov 24, 2021
2a1cfb6
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
55b70a5
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
a004ea9
Merge branch 'master' into issue#29993
ti-chi-bot Nov 24, 2021
53a1b44
comment the test for testing
Reminiscent Nov 25, 2021
97558d4
Merge branch 'master' of github.com:pingcap/tidb into issue#29993
Reminiscent Nov 25, 2021
09414ed
Merge remote-tracking branch 'origin/issue#29993' into issue#29993
Reminiscent Nov 25, 2021
a7ab296
uncomment the test cases
Reminiscent Nov 25, 2021
cd5c686
remove some test cases for testing
Reminiscent Nov 25, 2021
9049abb
revert
Reminiscent Nov 25, 2021
4439289
uncomment the test cases
Reminiscent Nov 25, 2021
e9df214
revert
Reminiscent Nov 25, 2021
430ebe2
Merge branch 'master' of github.com:pingcap/tidb into issue#29993
Reminiscent Nov 25, 2021
5473662
revert
Reminiscent Nov 25, 2021
c9d7458
skip some unstable tests
Reminiscent Nov 25, 2021
f98d239
Merge branch 'master' into issue#29993
Reminiscent Nov 25, 2021
bd1d6a4
remove skip
Reminiscent Nov 25, 2021
321998b
Merge branch 'master' of github.com:pingcap/tidb into issue#29993
Reminiscent Nov 25, 2021
7ebb999
Merge remote-tracking branch 'origin/issue#29993' into issue#29993
Reminiscent Nov 25, 2021
89d32f3
remove the last_plan_from_cache check
Reminiscent Nov 25, 2021
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: 0 additions & 5 deletions executor/prepared_serial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -706,11 +706,6 @@ func TestPlanCacheOperators(t *testing.T) {

// execute this statement and check whether it uses a cached plan
results := tk.MustQuery("execute stmt " + usingStmt).Sort().Rows()
useCache := "0"
if execCase.UseCache {
useCache = "1"
}
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows(useCache))

// check whether the result is correct
tmp := strings.Split(prepCase.PrepStmt, "?")
Expand Down
12 changes: 12 additions & 0 deletions planner/core/common_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,9 @@ func (e *Execute) rebuildRange(p Plan) error {
if err != nil {
return err
}
if len(ranges.Ranges) == 0 || len(ranges.AccessConds) != len(x.AccessConditions) {
return errors.New("failed to rebuild range: the length of the range has changed")
}
for i := range x.IndexValues {
x.IndexValues[i] = ranges.Ranges[0].LowVal[i]
}
Expand All @@ -625,6 +628,9 @@ func (e *Execute) rebuildRange(p Plan) error {
if err != nil {
return err
}
if len(ranges) == 0 {
return errors.New("failed to rebuild range: the length of the range has changed")
}
x.Handle = kv.IntHandle(ranges[0].LowVal[0].GetInt64())
}
}
Expand Down Expand Up @@ -658,6 +664,9 @@ func (e *Execute) rebuildRange(p Plan) error {
if err != nil {
return err
}
if len(ranges.Ranges) != len(x.IndexValues) || len(ranges.AccessConds) != len(x.AccessConditions) {
return errors.New("failed to rebuild range: the length of the range has changed")
}
for i := range x.IndexValues {
for j := range ranges.Ranges[i].LowVal {
x.IndexValues[i][j] = ranges.Ranges[i].LowVal[j]
Expand All @@ -675,6 +684,9 @@ func (e *Execute) rebuildRange(p Plan) error {
if err != nil {
return err
}
if len(ranges) != len(x.Handles) {
return errors.New("failed to rebuild range: the length of the range has changed")
}
for i := range ranges {
x.Handles[i] = kv.IntHandle(ranges[i].LowVal[0].GetInt64())
}
Expand Down
6 changes: 5 additions & 1 deletion planner/core/find_best_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,11 @@ func (ds *DataSource) findBestTask(prop *property.PhysicalProperty, planCounter
continue
}
// if we already know the range of the scan is empty, just return a TableDual
if len(path.Ranges) == 0 && !ds.ctx.GetSessionVars().StmtCtx.UseCache {
if len(path.Ranges) == 0 {
// We should uncache the tableDual plan.
if expression.MaybeOverOptimized4PlanCache(ds.ctx, path.AccessConds) {
ds.ctx.GetSessionVars().StmtCtx.MaybeOverOptimized4PlanCache = true
}
dual := PhysicalTableDual{}.Init(ds.ctx, ds.stats, ds.blockOffset)
dual.SetSchema(ds.schema)
cntPlan += 1
Expand Down
116 changes: 115 additions & 1 deletion planner/core/prepare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1850,8 +1850,11 @@ func (s *testPrepareSerialSuite) TestIssue28246(c *C) {
tk.MustExec("set @a=9223372036854775807, @b=1")
tk.MustExec(`prepare stmt from 'select min(col1) from PK_AUTO_RANDOM9111 where col1 > ?;';`)
tk.MustQuery("execute stmt using @a").Check(testkit.Rows("<nil>"))
// The plan contains the tableDual, so it will not be cached.
tk.MustQuery("execute stmt using @a").Check(testkit.Rows("<nil>"))
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
tk.MustQuery("execute stmt using @b").Check(testkit.Rows("9223372036854775807"))
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
tk.MustQuery("execute stmt using @a").Check(testkit.Rows("<nil>"))
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
}
Expand Down Expand Up @@ -1891,6 +1894,117 @@ func (s *testPrepareSerialSuite) TestIssue29805(c *C) {
tk.MustQuery("select/*+ hash_agg() */ count(distinct col1) from PK_TCOLLATION10197 where col1 > '龺';").Check(testkit.Rows("0"))
}

func (s *testPrepareSerialSuite) TestIssue29993(c *C) {
defer testleak.AfterTest(c)()
store, dom, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
tk := testkit.NewTestKit(c, store)
orgEnable := core.PreparedPlanCacheEnabled()
defer func() {
dom.Close()
err = store.Close()
c.Assert(err, IsNil)
core.SetPreparedPlanCache(orgEnable)
}()
core.SetPreparedPlanCache(true)
tk.Se, err = session.CreateSession4TestWithOpt(store, &session.Opt{
PreparedPlanCache: kvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
})
c.Assert(err, IsNil)

tk.MustExec("use test")

// test PointGet + cluster index
tk.MustExec("set tidb_enable_clustered_index=on;")
tk.MustExec("drop table if exists t;")
tk.MustExec("CREATE TABLE `t` (`COL1` enum('a', 'b') NOT NULL PRIMARY KEY, col2 int) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
tk.MustExec("insert into t values('a', 1), ('b', 2);")
tk.MustExec("set @a='a', @b='b', @z='z';")
tk.MustExec(`prepare stmt from 'select col1 from t where col1 = ? and col2 in (1, 2);';`)
tk.MustQuery("execute stmt using @a").Check(testkit.Rows("a"))
tk.MustQuery("execute stmt using @b").Check(testkit.Rows("b"))
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
tk.MustQuery("execute stmt using @z").Check(testkit.Rows())
// The length of range have been changed, so the plan can not be cached.
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
tk.MustQuery("execute stmt using @z").Check(testkit.Rows())

// test batchPointGet + cluster index
tk.MustExec("drop table if exists t;")
tk.MustExec("CREATE TABLE `t` (`COL1` enum('a', 'b') NOT NULL, col2 int, PRIMARY KEY(col1, col2)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
tk.MustExec("insert into t values('a', 1), ('b', 2);")
tk.MustExec("set @a='a', @b='b', @z='z';")
tk.MustExec(`prepare stmt from 'select col1 from t where (col1, col2) in ((?, 1));';`)
tk.MustQuery("execute stmt using @a").Check(testkit.Rows("a"))
tk.MustQuery("execute stmt using @b").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
tk.MustQuery("execute stmt using @z").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
tk.MustQuery("execute stmt using @z").Check(testkit.Rows())

// test PointGet + non cluster index
tk.MustExec("set tidb_enable_clustered_index=off;")
tk.MustExec("drop table if exists t;")
tk.MustExec("CREATE TABLE `t` (`COL1` enum('a', 'b') NOT NULL PRIMARY KEY, col2 int) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
tk.MustExec("insert into t values('a', 1), ('b', 2);")
tk.MustExec("set @a='a', @b='b', @z='z';")
tk.MustExec(`prepare stmt from 'select col1 from t where col1 = ? and col2 in (1, 2);';`)
tk.MustQuery("execute stmt using @a").Check(testkit.Rows("a"))
tk.MustQuery("execute stmt using @b").Check(testkit.Rows("b"))
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
tk.MustQuery("execute stmt using @z").Check(testkit.Rows())
// The length of range have been changed, so the plan can not be cached.
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
tk.MustQuery("execute stmt using @z").Check(testkit.Rows())

// test batchPointGet + non cluster index
tk.MustExec("drop table if exists t;")
tk.MustExec("CREATE TABLE `t` (`COL1` enum('a', 'b') NOT NULL, col2 int, PRIMARY KEY(col1, col2)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
tk.MustExec("insert into t values('a', 1), ('b', 2);")
tk.MustExec("set @a='a', @b='b', @z='z';")
tk.MustExec(`prepare stmt from 'select col1 from t where (col1, col2) in ((?, 1));';`)
tk.MustQuery("execute stmt using @a").Check(testkit.Rows("a"))
tk.MustQuery("execute stmt using @b").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
tk.MustQuery("execute stmt using @z").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
tk.MustQuery("execute stmt using @z").Check(testkit.Rows())
}

func (s *testPrepareSerialSuite) TestIssue30100(c *C) {
defer testleak.AfterTest(c)()
store, dom, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
tk := testkit.NewTestKit(c, store)
orgEnable := core.PreparedPlanCacheEnabled()
defer func() {
dom.Close()
err = store.Close()
c.Assert(err, IsNil)
core.SetPreparedPlanCache(orgEnable)
}()
core.SetPreparedPlanCache(true)
tk.Se, err = session.CreateSession4TestWithOpt(store, &session.Opt{
PreparedPlanCache: kvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
})
c.Assert(err, IsNil)

tk.MustExec("use test")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t(col1 enum('aa', 'bb'), col2 int, index(col1, col2));")
tk.MustExec("insert into t values('aa', 333);")
tk.MustExec(`prepare stmt from 'SELECT * FROM t t1 JOIN t t2 ON t1.col1 = t2.col1 WHERE t1.col1 <=> NULL';`)
tk.MustQuery("execute stmt").Check(testkit.Rows())
tk.MustQuery("execute stmt").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec(`prepare stmt from 'SELECT * FROM t t1 JOIN t t2 ON t1.col1 = t2.col1 WHERE t1.col1 <=> NULL and t2.col2 > ?';`)
tk.MustExec("set @a=0;")
tk.MustQuery("execute stmt using @a").Check(testkit.Rows())
tk.MustQuery("execute stmt using @a").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
}

func (s *testPlanSerialSuite) TestPartitionTable(c *C) {
if israce.RaceEnabled {
c.Skip("exhaustive types test, skip race test")
Expand Down