From 4dd328b1f6eec764e8876640ba33960a50a8619c Mon Sep 17 00:00:00 2001 From: Kenan Yao Date: Thu, 22 Nov 2018 17:22:35 +0800 Subject: [PATCH] plan: disable plan cache for query containing `SubqueryExpr` (#8395) --- executor/prepared_test.go | 20 ++++++++++++++++++++ plan/cacheable_checker.go | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/executor/prepared_test.go b/executor/prepared_test.go index 75f888c657515..13b52c9aaf23f 100644 --- a/executor/prepared_test.go +++ b/executor/prepared_test.go @@ -88,6 +88,26 @@ func (s *testSuite) TestPrepared(c *C) { c.Assert(err, IsNil) tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("3")) + tk.MustExec("delete from prepare_test") + query = "select c1 from prepare_test where c1 = (select c1 from prepare_test where c1 = ?)" + stmtId, _, _, err = tk.Se.PrepareStmt(query) + _, err = tk.Se.ExecutePreparedStmt(ctx, stmtId, 3) + c.Assert(err, IsNil) + tk1.MustExec("insert prepare_test (c1) values (3)") + rs, err = tk.Se.ExecutePreparedStmt(ctx, stmtId, 3) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("3")) + + tk.MustExec("delete from prepare_test") + query = "select c1 from prepare_test where c1 in (select c1 from prepare_test where c1 = ?)" + stmtId, _, _, err = tk.Se.PrepareStmt(query) + _, err = tk.Se.ExecutePreparedStmt(ctx, stmtId, 3) + c.Assert(err, IsNil) + tk1.MustExec("insert prepare_test (c1) values (3)") + rs, err = tk.Se.ExecutePreparedStmt(ctx, stmtId, 3) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("3")) + tk.MustExec("begin") tk.MustExec("insert prepare_test (c1) values (4)") query = "select c1, c2 from prepare_test where c1 = ?" diff --git a/plan/cacheable_checker.go b/plan/cacheable_checker.go index 03ab4008c5ade..f2764ffc81a27 100644 --- a/plan/cacheable_checker.go +++ b/plan/cacheable_checker.go @@ -42,7 +42,7 @@ type cacheableChecker struct { // Enter implements Visitor interface. func (checker *cacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren bool) { switch node := in.(type) { - case *ast.VariableExpr, *ast.ExistsSubqueryExpr: + case *ast.VariableExpr, *ast.ExistsSubqueryExpr, *ast.SubqueryExpr: checker.cacheable = false return in, true case *ast.FuncCallExpr: