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 plan cache rebuild range error #42220

Merged
merged 6 commits into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions planner/core/plan_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,14 @@ func buildRangeForTableScan(sctx sessionctx.Context, ts *PhysicalTableScan) (err
}

func buildRangeForIndexScan(sctx sessionctx.Context, is *PhysicalIndexScan) (err error) {
if len(is.IdxCols) == 0 {
if ranger.HasFullRange(is.Ranges, false) { // the original range is already a full-range.
is.Ranges = ranger.FullRange()
return
}
return errors.New("unexpected range for PhysicalIndexScan")
}

res, err := ranger.DetachCondAndBuildRangeForIndex(sctx, is.AccessCondition, is.IdxCols, is.IdxColLens, 0)
if err != nil {
return err
Expand Down
25 changes: 25 additions & 0 deletions planner/core/plan_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1443,3 +1443,28 @@ func TestNonPreparedPlanExplainWarning(t *testing.T) {
require.Equal(t, reasons[idx], warn[2])
}
}

func TestIssue42150(t *testing.T) {
fzzf678 marked this conversation as resolved.
Show resolved Hide resolved
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec("drop table if exists t1, t2")
tk.MustExec("CREATE TABLE `t1` (`c_int` int(11) NOT NULL, `c_str` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, `c_datetime` datetime DEFAULT NULL, `c_timestamp` timestamp NULL DEFAULT NULL, `c_double` double DEFAULT NULL, `c_decimal` decimal(12,6) DEFAULT NULL, `c_enum` enum('blue','green','red','yellow','white','orange','purple') NOT NULL, PRIMARY KEY (`c_int`,`c_enum`) /*T![clustered_index] CLUSTERED */, KEY `c_decimal` (`c_decimal`), UNIQUE KEY `c_datetime` (`c_datetime`), UNIQUE KEY `c_timestamp` (`c_timestamp`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
tk.MustExec("CREATE TABLE `t2` (`c_int` int(11) NOT NULL, `c_str` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, `c_datetime` datetime DEFAULT NULL, `c_timestamp` timestamp NULL DEFAULT NULL, `c_double` double DEFAULT NULL, `c_decimal` decimal(12,6) DEFAULT NULL, `c_enum` enum('blue','green','red','yellow','white','orange','purple') NOT NULL, PRIMARY KEY (`c_int`,`c_enum`) /*T![clustered_index] CLUSTERED */, KEY `c_decimal` (`c_decimal`), UNIQUE KEY `c_datetime` (`c_datetime`), UNIQUE KEY `c_timestamp` (`c_timestamp`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
tk.MustExec("create table t (a int, b int, primary key(a), key(b))")
tk.MustExec("set @v0 = 'nice hellman', @v1 = 'flamboyant booth', @v2 = 'quirky brahmagupta'")
tk.MustExec("prepare stmt16 from 'select * from t1 where c_enum in (select c_enum from t2 where t1.c_str in (?, ?, ?))'")
tk.MustExec("execute stmt16 using @v0, @v1, @v2;")
tk.MustExec("execute stmt16 using @v0, @v1, @v2;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("prepare stmt from 'select c_enum from t1'")
tk.MustExec("execute stmt;")
tk.MustExec("execute stmt;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("prepare st from 'select a from t use index(b)'")
tk.MustExec("execute st")
tk.MustExec("execute st")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
}