From f029eaee508d6a98f7baa6494b0593ce9436b56f Mon Sep 17 00:00:00 2001 From: Lynn Date: Mon, 5 Nov 2018 10:52:17 +0800 Subject: [PATCH] executor, sessionctx: add a variable --- executor/rowid_test.go | 43 ++++++++++++++++------------ executor/write.go | 11 ++++--- sessionctx/variable/session.go | 6 ++++ sessionctx/variable/sysvar.go | 1 + sessionctx/variable/tidb_vars.go | 4 +++ sessionctx/variable/varsutil_test.go | 1 + 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/executor/rowid_test.go b/executor/rowid_test.go index f42c25972acc7..9aca3132a28ba 100644 --- a/executor/rowid_test.go +++ b/executor/rowid_test.go @@ -18,12 +18,12 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -/* -Insert, update and replace statements for _tidb_rowid are not supported now. -After we support it, the following operations can be passed. func (s *testSuite) TestExportRowID(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") + tk := testkit.NewTestKitWithInit(c, s.store) + tk.Se.GetSessionVars().AllowWriteRowID = true + defer func() { + tk.Se.GetSessionVars().AllowWriteRowID = false + }() tk.MustExec("drop table if exists t") tk.MustExec("create table t (a int, b int)") tk.MustExec("insert t values (1, 7), (1, 8), (1, 9)") @@ -41,21 +41,26 @@ func (s *testSuite) TestExportRowID(c *C) { tk.MustQuery("select *, _tidb_rowid from t"). Check(testkit.Rows("1 7 1", "2 2 2", "1 9 3", "5 5 5")) - // If PK is handle, _tidb_rowid is unknown column. - tk.MustExec("create table s (a int primary key)") - tk.MustExec("insert s values (1)") - _, err := tk.Exec("insert s (a, _tidb_rowid) values (1, 2)") - c.Assert(err, NotNil) - _, err = tk.Exec("select _tidb_rowid from s") - c.Assert(err, NotNil) - _, err = tk.Exec("update s set a = 2 where _tidb_rowid = 1") - c.Assert(err, NotNil) - _, err = tk.Exec("delete from s where _tidb_rowid = 1") - c.Assert(err, NotNil) + // If PK is handle, _tidb_rowid is unknown column. + tk.MustExec("create table s (a int primary key)") + tk.MustExec("insert s values (1)") + _, err := tk.Exec("insert s (a, _tidb_rowid) values (1, 2)") + c.Assert(err, NotNil) + _, err = tk.Exec("select _tidb_rowid from s") + c.Assert(err, NotNil) + _, err = tk.Exec("update s set a = 2 where _tidb_rowid = 1") + c.Assert(err, NotNil) + _, err = tk.Exec("delete from s where _tidb_rowid = 1") + c.Assert(err, NotNil) + + // Make sure "AllowWriteRowID" is a session variable. + tk1 := testkit.NewTestKit(c, s.store) + tk1.MustExec("use test") + _, err = tk1.Exec("insert into t (a, _tidb_rowid) values(10,1);") + c.Assert(err.Error(), Equals, "insert, update and replace statements for _tidb_rowid are not supported.") } -*/ -func (s *testSuite) TestRowID(c *C) { +func (s *testSuite) TestNotAllowWriteRowID(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table tt(id binary(10), c int, primary key(id));") @@ -78,7 +83,7 @@ func (s *testSuite) TestRowID(c *C) { tk.MustExec("admin check table tt;") tk.MustExec("drop table tt") - // Insert, update and replace statements for _tidb_rowid are not supported now. + // There is currently no real support for inserting, updating, and replacing _tidb_rowid statements. // After we support it, the following operations must be passed. // tk.MustExec("insert into tt (id, c, _tidb_rowid) values(30000,10,1);") // tk.MustExec("admin check table tt;") diff --git a/executor/write.go b/executor/write.go index 9f9e7a013a1d3..83df7c570efb6 100644 --- a/executor/write.go +++ b/executor/write.go @@ -1370,8 +1370,11 @@ func (e *InsertValues) getColumns(tableCols []*table.Column) ([]*table.Column, e } for _, col := range cols { if col.Name.L == model.ExtraHandleName.L { + if !e.ctx.GetSessionVars().AllowWriteRowID { + return nil, errors.Errorf("insert, update and replace statements for _tidb_rowid are not supported.") + } e.hasExtraHandle = true - return nil, errors.Errorf("insert, update and replace statements for _tidb_rowid are not supported.") + break } } @@ -1919,7 +1922,7 @@ type UpdateExec struct { } func (e *UpdateExec) exec(ctx context.Context, schema *expression.Schema) (types.DatumRow, error) { - assignFlag, err := getUpdateColumns(e.OrderedList, schema.Len()) + assignFlag, err := getUpdateColumns(e.ctx, e.OrderedList, schema.Len()) if err != nil { return nil, errors.Trace(err) } @@ -1995,10 +1998,10 @@ func (e *UpdateExec) Next(ctx context.Context, chk *chunk.Chunk) error { return nil } -func getUpdateColumns(assignList []*expression.Assignment, schemaLen int) ([]bool, error) { +func getUpdateColumns(ctx sessionctx.Context, assignList []*expression.Assignment, schemaLen int) ([]bool, error) { assignFlag := make([]bool, schemaLen) for _, v := range assignList { - if v.Col.ColName.L == model.ExtraHandleName.L { + if !ctx.GetSessionVars().AllowWriteRowID && v.Col.ColName.L == model.ExtraHandleName.L { return nil, errors.Errorf("insert, update and replace statements for _tidb_rowid are not supported.") } idx := v.Col.Index diff --git a/sessionctx/variable/session.go b/sessionctx/variable/session.go index a9c8081bdf5c6..9be2fd2173dd9 100644 --- a/sessionctx/variable/session.go +++ b/sessionctx/variable/session.go @@ -238,6 +238,10 @@ type SessionVars struct { // AllowAggPushDown can be set to false to forbid aggregation push down. AllowAggPushDown bool + // AllowWriteRowID can be set to false to forbid write data to _tidb_rowid. + // This variable is currently not recommended to be turned on. + AllowWriteRowID bool + // AllowInSubqueryUnFolding can be set to true to fold in subquery AllowInSubqueryUnFolding bool @@ -517,6 +521,8 @@ func (s *SessionVars) SetSystemVar(name string, val string) error { s.SkipUTF8Check = TiDBOptOn(val) case TiDBOptAggPushDown: s.AllowAggPushDown = TiDBOptOn(val) + case TiDBOptWriteRowID: + s.AllowWriteRowID = TiDBOptOn(val) case TiDBOptInSubqUnFolding: s.AllowInSubqueryUnFolding = TiDBOptOn(val) case TiDBIndexLookupConcurrency: diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 9dd1e3f9027c6..5cfa461a08915 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -610,6 +610,7 @@ var defaultSysVars = []*SysVar{ {ScopeSession, TiDBImportingData, "0"}, {ScopeSession, TiDBOptAggPushDown, boolToIntStr(DefOptAggPushDown)}, {ScopeSession, TiDBOptInSubqUnFolding, boolToIntStr(DefOptInSubqUnfolding)}, + {ScopeSession, TiDBOptWriteRowID, boolToIntStr(DefOptWriteRowID)}, {ScopeSession, TiDBBuildStatsConcurrency, strconv.Itoa(DefBuildStatsConcurrency)}, {ScopeGlobal, TiDBAutoAnalyzeRatio, strconv.FormatFloat(DefAutoAnalyzeRatio, 'f', -1, 64)}, {ScopeSession, TiDBChecksumTableConcurrency, strconv.Itoa(DefChecksumTableConcurrency)}, diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index 9c5e61f98ff70..74ae0379b9667 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -39,6 +39,9 @@ const ( // tidb_opt_agg_push_down is used to enable/disable the optimizer rule of aggregation push down. TiDBOptAggPushDown = "tidb_opt_agg_push_down" + // tidb_opt_write_row_id is used to enable/disable the operations of insert、replace and update to _tidb_rowid. + TiDBOptWriteRowID = "tidb_opt_write_row_id" + // tidb_opt_insubquery_unfold is used to enable/disable the optimizer rule of in subquery unfold. TiDBOptInSubqUnFolding = "tidb_opt_insubquery_unfold" @@ -172,6 +175,7 @@ const ( DefSkipUTF8Check = false DefOptAggPushDown = false DefOptInSubqUnfolding = false + DefOptWriteRowID = false DefBatchInsert = false DefBatchDelete = false DefCurretTS = 0 diff --git a/sessionctx/variable/varsutil_test.go b/sessionctx/variable/varsutil_test.go index f899ea15d1b03..c7543eb13d597 100644 --- a/sessionctx/variable/varsutil_test.go +++ b/sessionctx/variable/varsutil_test.go @@ -74,6 +74,7 @@ func (s *testVarsutilSuite) TestNewSessionVars(c *C) { c.Assert(vars.MemQuotaIndexLookupReader, Equals, int64(DefTiDBMemQuotaIndexLookupReader)) c.Assert(vars.MemQuotaIndexLookupJoin, Equals, int64(DefTiDBMemQuotaIndexLookupJoin)) c.Assert(vars.MemQuotaNestedLoopApply, Equals, int64(DefTiDBMemQuotaNestedLoopApply)) + c.Assert(vars.AllowWriteRowID, Equals, DefOptWriteRowID) } func (s *testVarsutilSuite) TestVarsutil(c *C) {