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 11 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
96 changes: 96 additions & 0 deletions executor/prepared_serial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,102 @@ func TestPreparePlanCache4Blacklist(t *testing.T) {
tk.MustExec("ADMIN reload expr_pushdown_blacklist;")
}

func TestIssue29993(t *testing.T) {
store, dom, err := newStoreWithBootstrap()
require.NoError(t, err)
orgEnable := plannercore.PreparedPlanCacheEnabled()
defer func() {
plannercore.SetPreparedPlanCache(orgEnable)
}()
plannercore.SetPreparedPlanCache(true)
tk := testkit.NewTestKit(t, store)
defer func() {
dom.Close()
require.NoError(t, store.Close())
}()
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())
tkProcess := tk.Session().ShowProcess()
ps := []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
// The plan should be tableDual.
tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).Check(testkit.Rows(
"Projection_4 0.00 root test.t.col1",
"└─TableDual_5 0.00 root rows:0"))

// 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())
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).Check(testkit.Rows(
"Batch_Point_Get_1 1.00 root table:t, clustered index:PRIMARY(COL1, col2) keep order:false, desc:false"))

// 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())
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
// The plan should be tableDual.
tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).Check(testkit.Rows(
"Projection_4 0.00 root test.t.col1",
"└─TableDual_5 0.00 root rows:0"))

// 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())
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).Check(testkit.Rows(
"Batch_Point_Get_1 1.00 root table:t, index:PRIMARY(COL1, col2) keep order:false, desc:false"))
}

func TestPlanCacheClusterIndex(t *testing.T) {
store, dom, err := newStoreWithBootstrap()
require.NoError(t, err)
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
5 changes: 4 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