From daf87da0eb26eb301e788d90a06e45671f7ca754 Mon Sep 17 00:00:00 2001 From: cfzjywxk Date: Wed, 19 May 2021 15:43:48 +0800 Subject: [PATCH] fix the incorrect use of cached plan for point get Signed-off-by: cfzjywxk --- session/session.go | 2 +- session/session_test.go | 58 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/session/session.go b/session/session.go index efd6706c4ffb3..abab19c4d134a 100644 --- a/session/session.go +++ b/session/session.go @@ -1821,7 +1821,7 @@ func (s *session) IsCachedExecOk(ctx context.Context, preparedStmt *plannercore. return false, nil } // check auto commit - if !s.GetSessionVars().IsAutocommit() { + if !plannercore.IsAutoCommitTxn(s) { return false, nil } // check schema version diff --git a/session/session_test.go b/session/session_test.go index df2a167921e56..839ff9f40ec82 100644 --- a/session/session_test.go +++ b/session/session_test.go @@ -4486,3 +4486,61 @@ func (s *testSessionSuite) TestReadDMLBatchSize(c *C) { _, _ = se.Execute(context.TODO(), "select 1") c.Assert(se.GetSessionVars().DMLBatchSize, Equals, 1000) } + +func (s *testSessionSuite) TestInTxnPSProtoPointGet(c *C) { + ctx := context.Background() + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("create table t1(c1 int primary key, c2 int, c3 int)") + tk.MustExec("insert into t1 values(1, 10, 100)") + + // Generate the ps statement and make the prepared plan cached for point get. + id, _, _, err := tk.Se.PrepareStmt("select c1, c2 from t1 where c1 = ?") + c.Assert(err, IsNil) + idForUpdate, _, _, err := tk.Se.PrepareStmt("select c1, c2 from t1 where c1 = ? for update") + c.Assert(err, IsNil) + params := []types.Datum{types.NewDatum(1)} + rs, err := tk.Se.ExecutePreparedStmt(ctx, id, params) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1 10")) + rs, err = tk.Se.ExecutePreparedStmt(ctx, idForUpdate, params) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1 10")) + + // Query again the cached plan will be used. + rs, err = tk.Se.ExecutePreparedStmt(ctx, id, params) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1 10")) + rs, err = tk.Se.ExecutePreparedStmt(ctx, idForUpdate, params) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1 10")) + + // Start a transaction, now the in txn flag will be added to the session vars. + _, err = tk.Se.Execute(ctx, "start transaction") + c.Assert(err, IsNil) + rs, err = tk.Se.ExecutePreparedStmt(ctx, id, params) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1 10")) + txn, err := tk.Se.Txn(false) + c.Assert(err, IsNil) + c.Assert(txn.Valid(), IsTrue) + rs, err = tk.Se.ExecutePreparedStmt(ctx, idForUpdate, params) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1 10")) + txn, err = tk.Se.Txn(false) + c.Assert(err, IsNil) + c.Assert(txn.Valid(), IsTrue) + _, err = tk.Se.Execute(ctx, "update t1 set c2 = c2 + 1") + c.Assert(err, IsNil) + // Check the read result after in-transaction update. + rs, err = tk.Se.ExecutePreparedStmt(ctx, id, params) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1 11")) + rs, err = tk.Se.ExecutePreparedStmt(ctx, idForUpdate, params) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1 11")) + txn, err = tk.Se.Txn(false) + c.Assert(err, IsNil) + c.Assert(txn.Valid(), IsTrue) + tk.MustExec("commit") +}