Skip to content

Commit

Permalink
planner: skip plan-cache for prepared queries with `INT in (Decimals.…
Browse files Browse the repository at this point in the history
…..)` (#40312) (#42650)

close #40224
  • Loading branch information
qw4990 authored Mar 29, 2023
1 parent c585770 commit cc95a63
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 9 deletions.
32 changes: 32 additions & 0 deletions executor/prepared_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,38 @@ func TestIssue38533(t *testing.T) {
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
}

func TestIssue40224(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()

orgEnable := plannercore.PreparedPlanCacheEnabled()
defer func() {
plannercore.SetPreparedPlanCache(orgEnable)
}()
plannercore.SetPreparedPlanCache(true)
tk := testkit.NewTestKit(t, store)

tk.MustExec("use test")
tk.MustExec("create table t (a int, key(a))")
tk.MustExec("prepare st from 'select a from t where a in (?, ?)'")
tk.MustExec("set @a=1.0, @b=2.0")
tk.MustExec("execute st using @a, @b")
tk.MustExec("execute st using @a, @b")
tkProcess := tk.Session().ShowProcess()
ps := []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
rs := tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID))
require.True(t, strings.Contains(rs.Rows()[1][0].(string), "RangeScan")) // range-scan instead of full-scan

tk.MustExec("set @a=1, @b=2")
tk.MustExec("execute st using @a, @b")
tk.MustExec("execute st using @a, @b")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) // cacheable for INT
tk.MustExec("execute st using @a, @b")
rs = tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID))
require.True(t, strings.Contains(rs.Rows()[1][0].(string), "RangeScan")) // range-scan instead of full-scan
}

func TestIssue29850(t *testing.T) {
store, dom, err := newStoreWithBootstrap()
require.NoError(t, err)
Expand Down
12 changes: 3 additions & 9 deletions planner/core/expression_rewriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -1473,16 +1473,10 @@ func (er *expressionRewriter) inToExpression(lLen int, not bool, tp *types.Field
if c, ok := args[i].(*expression.Constant); ok {
var isExceptional bool
if expression.MaybeOverOptimized4PlanCache(er.sctx, []expression.Expression{c}) {
if c.GetType().EvalType() == types.ETString {
// To keep the result be compatible with MySQL, refine `int non-constant <cmp> str constant`
// here and skip this refine operation in all other cases for safety.
er.sctx.GetSessionVars().StmtCtx.SkipPlanCache = true
expression.RemoveMutableConst(er.sctx, []expression.Expression{c})
} else {
continue
if c.GetType().EvalType() == types.ETInt {
continue // no need to refine it
}
} else if er.sctx.GetSessionVars().StmtCtx.SkipPlanCache {
// We should remove the mutable constant for correctness, because its value may be changed.
er.sctx.GetSessionVars().StmtCtx.SkipPlanCache = true
expression.RemoveMutableConst(er.sctx, []expression.Expression{c})
}
args[i], isExceptional = expression.RefineComparedConstant(er.sctx, *leftFt, c, opcode.EQ)
Expand Down

0 comments on commit cc95a63

Please sign in to comment.