From d3a02f416aaa1eda89ce6bec2242ea8254ccfa46 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Sun, 24 Apr 2022 17:38:48 +0800 Subject: [PATCH] executor: flush statement should trigger implicit commit (#34134) close pingcap/tidb#34180 --- executor/simple.go | 14 +++++++++++++- executor/simple_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/executor/simple.go b/executor/simple.go index 8fbe8ee404..88cf258f13 100644 --- a/executor/simple.go +++ b/executor/simple.go @@ -1608,8 +1608,20 @@ func (e *SimpleExec) executeDropStats(s *ast.DropStatsStmt) (err error) { } func (e *SimpleExec) autoNewTxn() bool { + // Some statements cause an implicit commit + // See https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html switch e.Statement.(type) { - case *ast.CreateUserStmt, *ast.AlterUserStmt, *ast.DropUserStmt, *ast.RenameUserStmt: + // Data definition language (DDL) statements that define or modify database objects. + // (handled in DDL package) + // Statements that implicitly use or modify tables in the mysql database. + case *ast.CreateUserStmt, *ast.AlterUserStmt, *ast.DropUserStmt, *ast.RenameUserStmt, *ast.RevokeRoleStmt, *ast.GrantRoleStmt: + return true + // Transaction-control and locking statements. BEGIN, LOCK TABLES, SET autocommit = 1 (if the value is not already 1), START TRANSACTION, UNLOCK TABLES. + // (handled in other place) + // Data loading statements. LOAD DATA + // (handled in other place) + // Administrative statements. TODO: ANALYZE TABLE, CACHE INDEX, CHECK TABLE, FLUSH, LOAD INDEX INTO CACHE, OPTIMIZE TABLE, REPAIR TABLE, RESET (but not RESET PERSIST). + case *ast.FlushStmt: return true } return false diff --git a/executor/simple_test.go b/executor/simple_test.go index 8cb304e2ef..25e769ca68 100644 --- a/executor/simple_test.go +++ b/executor/simple_test.go @@ -1049,3 +1049,29 @@ func TestUserWithSetNames(t *testing.T) { tk.MustExec("drop user '\xd2\xbb';") } + +func TestStatementsCauseImplicitCommit(t *testing.T) { + // Test some of the implicit commit statements. + // See https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test;") + tk.MustExec("create table ic (id int primary key)") + + cases := []string{ + "create table xx (id int)", + "create user 'xx'@'127.0.0.1'", + "grant SELECT on test.ic to 'xx'@'127.0.0.1'", + "flush privileges", + "analyze table ic", + } + for i, sql := range cases { + tk.MustExec("begin") + tk.MustExec("insert into ic values (?)", i) + tk.MustExec(sql) + tk.MustQuery("select * from ic where id = ?", i).Check(testkit.Rows(strconv.FormatInt(int64(i), 10))) + // Clean up data + tk.MustExec("delete from ic") + } +}