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: update the non-prep cacheable checker #40446

Merged
merged 13 commits into from
Jan 10, 2023
19 changes: 19 additions & 0 deletions planner/core/plan_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,25 @@ func TestInitLRUWithSystemVar(t *testing.T) {
require.NotNil(t, lru)
}

func TestIssue40296(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec(`CREATE TABLE IDT_MULTI15880STROBJSTROBJ (
COL1 enum('aa','bb','cc','dd','ff','gg','kk','ll','mm','ee') DEFAULT NULL,
COL2 decimal(20,0) DEFAULT NULL,
COL3 date DEFAULT NULL,
KEY U_M_COL4 (COL1,COL2),
KEY U_M_COL5 (COL3,COL2))`)
tk.MustExec(`insert into IDT_MULTI15880STROBJSTROBJ values("ee", -9605492323393070105, "0850-03-15")`)
tk.MustExec(`set tidb_enable_non_prepared_plan_cache=on`)
tk.MustQuery(`select * from IDT_MULTI15880STROBJSTROBJ where col1 in ("dd", "dd") or col2 = 9923875910817805958 or col3 = "9994-11-11"`).Check(
testkit.Rows())
tk.MustQuery(`select * from IDT_MULTI15880STROBJSTROBJ where col1 in ("aa", "aa") or col2 = -9605492323393070105 or col3 = "0005-06-22"`).Check(
testkit.Rows("ee -9605492323393070105 0850-03-15"))
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // unary operator '-' is not supported now.
}

func TestNonPreparedPlanCacheWithExplain(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
Expand Down
15 changes: 7 additions & 8 deletions planner/core/plan_cacheable_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,31 +252,30 @@ type nonPreparedPlanCacheableChecker struct {
// Enter implements Visitor interface.
func (checker *nonPreparedPlanCacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren bool) {
switch node := in.(type) {
case *ast.SelectStmt, *ast.FieldList, *ast.SelectField, *ast.TableRefsClause, *ast.Join,
*ast.TableSource, *ast.ColumnNameExpr, *ast.ColumnName, *driver.ValueExpr, *ast.PatternInExpr:
return in, !checker.cacheable // skip child if un-cacheable
case *ast.BinaryOperationExpr:
if _, found := expression.NonPreparedPlanCacheableOp[node.Op.String()]; !found {
checker.cacheable = false
return in, true
}
case *ast.FuncCallExpr:
checker.cacheable = false
return in, true
return in, !checker.cacheable
case *ast.TableName:
if checker.schema != nil {
if isPartitionTable(checker.schema, node) {
checker.cacheable = false
return in, true
}
if hasGeneratedCol(checker.schema, node) {
checker.cacheable = false
return in, true
}
if isTempTable(checker.schema, node) {
checker.cacheable = false
return in, true
}
}
return in, !checker.cacheable
}
return in, false
checker.cacheable = false // unexpected cases
return in, !checker.cacheable
}

// Leave implements Visitor interface.
Expand Down