diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go index e2bbff37e0b0a..ccd5ab7ae3c81 100644 --- a/ddl/db_integration_test.go +++ b/ddl/db_integration_test.go @@ -82,6 +82,7 @@ func (s *testIntegrationSuite) SetUpSuite(c *C) { session.SetSchemaLease(s.lease) session.SetStatsLease(0) s.dom, err = session.BootstrapSession(s.store) + c.Assert(err, IsNil) se, err := session.CreateSession4Test(s.store) c.Assert(err, IsNil) diff --git a/ddl/ddl_worker_test.go b/ddl/ddl_worker_test.go index caaba53b74a10..4982efb17c3c5 100644 --- a/ddl/ddl_worker_test.go +++ b/ddl/ddl_worker_test.go @@ -504,6 +504,7 @@ func (s *testDDLSuite) TestCancelJob(c *C) { Options: []*ast.ColumnOption{}, } col, _, err := buildColumnAndConstraint(ctx, 2, newColumnDef, nil) + c.Assert(err, IsNil) addColumnArgs := []interface{}{col, &ast.ColumnPosition{Tp: ast.ColumnPositionNone}, 0} doDDLJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, model.ActionAddColumn, addColumnArgs, &cancelState) c.Check(errors.ErrorStack(checkErr), Equals, "") diff --git a/docs/tidb_http_api.md b/docs/tidb_http_api.md index 26af33b9d17ac..5f8f0450f3fd0 100644 --- a/docs/tidb_http_api.md +++ b/docs/tidb_http_api.md @@ -7,6 +7,14 @@ ```shell curl http://{TiDBIP}:10080/status ``` + ```shell + $curl http://127.0.0.1:10080/status + { + "connections": 0, + "git_hash": "f572e33854e1c0f942f031e9656d0004f99995c6", + "version": "5.7.10-TiDB-v2.1.0-rc.3-355-gf572e3385-dirty" + } + ``` 1. Get all metrics of TiDB @@ -19,30 +27,131 @@ ```shell curl http://{TiDBIP}:10080/regions/meta ``` + ```shell + $curl http://127.0.0.1:10080/regions/meta + [ + { + "leader": { + "id": 5, + "store_id": 1 + }, + "peers": [ + { + "id": 5, + "store_id": 1 + } + ], + "region_epoch": { + "conf_ver": 1, + "version": 2 + }, + "region_id": 4 + } + ] + ``` 1. Get the table/index of hot regions ```shell curl http://{TiDBIP}:10080/regions/hot ``` + ```shell + $curl http://127.0.0.1:10080/regions/hot + { + "read": [ + + ], + "write": [ + { + "db_name": "sbtest1", + "table_name": "sbtest13", + "index_name": "", + "flow_bytes": 220718, + "max_hot_degree": 12, + "region_count": 1 + } + ] + } + ``` 1. Get the information of a specific region by ID ```shell curl http://{TiDBIP}:10080/regions/{regionID} ``` + ```shell + $curl http://127.0.0.1:10080/regions/4001 + { + "end_key": "dIAAAAAAAAEk", + "frames": [ + { + "db_name": "test", + "is_record": true, + "table_id": 286, + "table_name": "t1" + } + ], + "region_id": 4001, + "start_key": "dIAAAAAAAAEe" + } + ``` 1. Get regions Information from db.table ```shell curl http://{TiDBIP}:10080/tables/{db}/{table}/regions ``` + ```shell + $curl http://127.0.0.1:10080/tables/test/t1/regions + { + "id": 286, + "indices": [], + "name": "t1", + "record_regions": [ + { + "leader": { + "id": 4002, + "store_id": 1 + }, + "peers": [ + { + "id": 4002, + "store_id": 1 + } + ], + "region_epoch": { + "conf_ver": 1, + "version": 83 + }, + "region_id": 4001 + } + ] + } + ``` 1. Get schema Information about all db ```shell curl http://{TiDBIP}:10080/schema ``` + ```shell + $curl http://127.0.0.1:10080/schema + [ + { + "charset": "utf8mb4", + "collate": "utf8mb4_bin", + "db_name": { + "L": "test", + "O": "test" + }, + "id": 266, + "state": 5 + }, + . + . + . + ] + ``` 1. Get schema Information about db @@ -75,12 +184,41 @@ ```shell curl http://{TiDBIP}:10080/mvcc/key/{db}/{table}/{handle} ``` + ```shell + $curl http://127.0.0.1:10080/mvcc/key/test/t1/1 + { + "info": { + "writes": [ + { + "commit_ts": 405179368526053380, + "short_value": "CAICAkE=", + "start_ts": 405179368526053377 + } + ] + } + } + ``` 1. Get MVCC Information of the first key in the table with a specified start ts ```shell curl http://{TiDBIP}:10080/mvcc/txn/{startTS}/{db}/{table} ``` + ```shell + $curl http://127.0.0.1:10080/mvcc/txn/405179368526053377/test/t1 + { + "info": { + "writes": [ + { + "commit_ts": 405179368526053380, + "short_value": "CAICAkE=", + "start_ts": 405179368526053377 + } + ] + }, + "key": "dIAAAAAAAAEzX3KAAAAAAAAAAQ==" + } + ``` 1. Get MVCC Information by a hex value @@ -95,6 +233,20 @@ ``` *Hint: For the index column which column type is timezone dependent, e.g. `timestamp`, convert its value to UTC timezone.* + ```shell + $curl http://127.0.0.1:10080/mvcc/index/test/t1/idx/1\?a\=A + { + "info": { + "writes": [ + { + "commit_ts": 405179523374252037, + "short_value": "MA==", + "start_ts": 405179523374252036 + } + ] + } + } + ``` 1. Scatter regions of the specified table, add a `scatter-range` scheduler for the PD and the range is same as the table range. @@ -121,12 +273,53 @@ timezone.* ```shell curl http://{TiDBIP}:10080/info ``` + ```shell + $curl http://127.0.0.1:10080/info + { + "ddl_id": "f7e73ed5-63b4-4cb4-ba7c-42b32dc74e77", + "git_hash": "f572e33854e1c0f942f031e9656d0004f99995c6", + "ip": "", + "is_owner": true, + "lease": "45s", + "listening_port": 4000, + "status_port": 10080, + "version": "5.7.10-TiDB-v2.1.0-rc.3-355-gf572e3385-dirty" + } + ``` 1. Get TiDB cluster all servers information. ```shell curl http://{TiDBIP}:10080/info/all ``` + ```shell + $curl http://127.0.0.1:10080/info/all + { + "all_servers_info": { + "275a19ae-d248-4dc0-b78c-6613a7509423": { + "ddl_id": "275a19ae-d248-4dc0-b78c-6613a7509423", + "git_hash": "f572e33854e1c0f942f031e9656d0004f99995c6", + "ip": "192.168.197.206", + "lease": "45s", + "listening_port": 4001, + "status_port": 10081, + "version": "5.7.10-TiDB-v2.1.0-rc.3-355-gf572e3385-dirty" + }, + "f7e73ed5-63b4-4cb4-ba7c-42b32dc74e77": { + "ddl_id": "f7e73ed5-63b4-4cb4-ba7c-42b32dc74e77", + "git_hash": "f572e33854e1c0f942f031e9656d0004f99995c6", + "ip": "192.168.197.206", + "lease": "45s", + "listening_port": 4000, + "status_port": 10080, + "version": "5.7.10-TiDB-v2.1.0-rc.3-355-gf572e3385-dirty" + } + }, + "is_all_server_version_consistent": true, + "owner_id": "f7e73ed5-63b4-4cb4-ba7c-42b32dc74e77", + "servers_num": 2 + } + ``` 1. Enable/Disable TiDB server general log diff --git a/executor/admin_test.go b/executor/admin_test.go index 81d3a58e85c8c..4df2fec231878 100644 --- a/executor/admin_test.go +++ b/executor/admin_test.go @@ -21,14 +21,13 @@ import ( . "github.com/pingcap/check" "github.com/pingcap/parser/model" "github.com/pingcap/tidb/executor" - "github.com/pingcap/tidb/meta/autoid" "github.com/pingcap/tidb/table/tables" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/mock" "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestAdminCheckIndexRange(c *C) { +func (s *testSuite1) TestAdminCheckIndexRange(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec(`drop table if exists check_index_test;`) @@ -54,7 +53,7 @@ func findIndexByName(idxName string, indices []*model.IndexInfo) *model.IndexInf return nil } -func (s *testSuite) TestAdminRecoverIndex(c *C) { +func (s *testSuite2) TestAdminRecoverIndex(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists admin_test") @@ -168,7 +167,7 @@ func (s *testSuite) TestAdminRecoverIndex(c *C) { tk.MustExec("admin check table admin_test") } -func (s *testSuite) TestAdminRecoverIndex1(c *C) { +func (s *testSuite2) TestAdminRecoverIndex1(c *C) { tk := testkit.NewTestKit(c, s.store) s.ctx = mock.NewContext() s.ctx.Store = s.store @@ -219,7 +218,7 @@ func (s *testSuite) TestAdminRecoverIndex1(c *C) { tk.MustExec("admin check index admin_test `primary`") } -func (s *testSuite) TestAdminCleanupIndex(c *C) { +func (s *testSuite2) TestAdminCleanupIndex(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists admin_test") @@ -298,7 +297,7 @@ func (s *testSuite) TestAdminCleanupIndex(c *C) { tk.MustExec("admin check table admin_test") } -func (s *testSuite) TestAdminCleanupIndexPKNotHandle(c *C) { +func (s *testSuite2) TestAdminCleanupIndexPKNotHandle(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists admin_test") @@ -346,7 +345,7 @@ func (s *testSuite) TestAdminCleanupIndexPKNotHandle(c *C) { tk.MustExec("admin check table admin_test") } -func (s *testSuite) TestAdminCleanupIndexMore(c *C) { +func (s *testSuite2) TestAdminCleanupIndexMore(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists admin_test") @@ -409,7 +408,7 @@ func (s *testSuite) TestAdminCleanupIndexMore(c *C) { tk.MustExec("admin check table admin_test") } -func (s *testSuite) TestAdminCheckTable(c *C) { +func (s *testSuite1) TestAdminCheckTable(c *C) { // test NULL value. tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -509,7 +508,7 @@ func (s *testSuite) TestAdminCheckTable(c *C) { tk.MustExec(`ADMIN CHECK TABLE td1;`) } -func (s *testSuite) TestAdminCheckPrimaryIndex(c *C) { +func (s *testSuite1) TestAdminCheckPrimaryIndex(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table t(a bigint unsigned primary key, b int, c int, index idx(a, b));") @@ -517,49 +516,7 @@ func (s *testSuite) TestAdminCheckPrimaryIndex(c *C) { tk.MustExec("admin check index t idx;") } -func (s *testSuite) TestAdminShowNextID(c *C) { - step := int64(10) - autoIDStep := autoid.GetStep() - autoid.SetStep(step) - defer autoid.SetStep(autoIDStep) - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("create table t(id int, c int)") - // Start handle is 1. - r := tk.MustQuery("admin show t next_row_id") - r.Check(testkit.Rows("test t _tidb_rowid 1")) - // Row ID is step + 1. - tk.MustExec("insert into t values(1, 1)") - r = tk.MustQuery("admin show t next_row_id") - r.Check(testkit.Rows("test t _tidb_rowid 11")) - // Row ID is original + step. - for i := 0; i < int(step); i++ { - tk.MustExec("insert into t values(10000, 1)") - } - r = tk.MustQuery("admin show t next_row_id") - r.Check(testkit.Rows("test t _tidb_rowid 21")) - - // test for a table with the primary key - tk.MustExec("create table tt(id int primary key auto_increment, c int)") - // Start handle is 1. - r = tk.MustQuery("admin show tt next_row_id") - r.Check(testkit.Rows("test tt id 1")) - // After rebasing auto ID, row ID is 20 + step + 1. - tk.MustExec("insert into tt values(20, 1)") - r = tk.MustQuery("admin show tt next_row_id") - r.Check(testkit.Rows("test tt id 31")) - // test for renaming the table - tk.MustExec("create database test1") - tk.MustExec("rename table test.tt to test1.tt") - tk.MustExec("use test1") - r = tk.MustQuery("admin show tt next_row_id") - r.Check(testkit.Rows("test1 tt id 31")) - tk.MustExec("insert test1.tt values ()") - r = tk.MustQuery("admin show tt next_row_id") - r.Check(testkit.Rows("test1 tt id 41")) -} - -func (s *testSuite) TestAdminCheckWithSnapshot(c *C) { +func (s *testSuite2) TestAdminCheckWithSnapshot(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists admin_t_s") diff --git a/executor/aggfuncs/aggfunc_test.go b/executor/aggfuncs/aggfunc_test.go index 2f40e218431b4..2852865185f04 100644 --- a/executor/aggfuncs/aggfunc_test.go +++ b/executor/aggfuncs/aggfunc_test.go @@ -28,6 +28,7 @@ var _ = Suite(&testSuite{}) func TestT(t *testing.T) { CustomVerboseFlag = true + *CustomParallelSuiteFlag = true TestingT(t) } diff --git a/executor/aggregate_test.go b/executor/aggregate_test.go index 677c262f79022..8db9d8cdfcef2 100644 --- a/executor/aggregate_test.go +++ b/executor/aggregate_test.go @@ -20,7 +20,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestAggregation(c *C) { +func (s *testSuite1) TestAggregation(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("set @@tidb_hash_join_concurrency=1") tk.MustExec("use test") @@ -67,7 +67,7 @@ func (s *testSuite) TestAggregation(c *C) { result.Check(testkit.Rows("2 4 2 4", "4 6 4 6", "5 7 5 7")) result = tk.MustQuery("select count(distinct c,d) from t") result.Check(testkit.Rows("5")) - _, err := tk.Exec("select count(c,d) from t") + err := tk.ExecToErr("select count(c,d) from t") c.Assert(err, NotNil) result = tk.MustQuery("select d*2 as ee, sum(c) from t group by ee order by ee") result.Check(testkit.Rows("2 2", "4 4", "6 5")) @@ -164,9 +164,9 @@ func (s *testSuite) TestAggregation(c *C) { result.Check(testkit.Rows("-1 1", "0 1", "1 1")) result = tk.MustQuery("select c as d, c as d from t group by d order by d") result.Check(testkit.Rows("1 1", "1 1", "1 1")) - _, err = tk.Exec("select d as d, c as d from t group by d") + err = tk.ExecToErr("select d as d, c as d from t group by d") c.Assert(err, NotNil) - _, err = tk.Exec("select t.d, c as d from t group by d") + err = tk.ExecToErr("select t.d, c as d from t group by d") c.Assert(err, NotNil) result = tk.MustQuery("select *, c+1 as d from t group by 3 order by d") result.Check(testkit.Rows("1 -1 2")) @@ -238,11 +238,6 @@ func (s *testSuite) TestAggregation(c *C) { result = tk.MustQuery("SELECT COALESCE ( + 1, cor0.col0 ) + - CAST( NULL AS DECIMAL ) FROM t2, t1 AS cor0, t2 AS cor1 GROUP BY cor0.col1") result.Check(testkit.Rows("", "")) - result = tk.MustQuery("select count(*) from information_schema.columns") - // When adding new memory columns in information_schema, please update this variable. - columnCountOfAllInformationSchemaTables := "762" - result.Check(testkit.Rows(columnCountOfAllInformationSchemaTables)) - tk.MustExec("drop table if exists t1") tk.MustExec("drop table if exists t2") tk.MustExec("create table t1 (c1 int)") @@ -341,7 +336,7 @@ func (s *testSuite) TestAggregation(c *C) { tk.MustQuery("select sum(a) from (select a from t union all select a from t) tmp").Check(testkit.Rows("-3.9484")) } -func (s *testSuite) TestStreamAggPushDown(c *C) { +func (s *testSuite1) TestStreamAggPushDown(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -352,7 +347,7 @@ func (s *testSuite) TestStreamAggPushDown(c *C) { tk.MustQuery("select count(a) from t;").Check(testkit.Rows("0")) // test for one row tk.MustExec("insert t values(0,0,0)") - tk.MustQuery("select distinct b from t group by a").Check(testkit.Rows("0")) + tk.MustQuery("select distinct b from t").Check(testkit.Rows("0")) tk.MustQuery("select count(b) from t group by a;").Check(testkit.Rows("1")) // test for rows tk.MustExec("insert t values(1,1,1),(3,3,6),(3,2,5),(2,1,4),(1,1,3),(1,1,2);") @@ -361,7 +356,7 @@ func (s *testSuite) TestStreamAggPushDown(c *C) { tk.MustQuery("select count(a) from t where b>0 group by a, b order by a limit 1;").Check(testkit.Rows("3")) } -func (s *testSuite) TestAggPrune(c *C) { +func (s *testSuite1) TestAggPrune(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -385,7 +380,7 @@ func (s *testSuite) TestAggPrune(c *C) { tk.MustQuery("SELECT a, MIN(b), MAX(b) FROM t GROUP BY a").Check(testkit.Rows("1 11 11", "3 ")) } -func (s *testSuite) TestGroupConcatAggr(c *C) { +func (s *testSuite1) TestGroupConcatAggr(c *C) { // issue #5411 tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -427,7 +422,7 @@ func (s *testSuite) TestSelectDistinct(c *C) { } -func (s *testSuite) TestAggPushDown(c *C) { +func (s *testSuite1) TestAggPushDown(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t, tt") @@ -439,7 +434,7 @@ func (s *testSuite) TestAggPushDown(c *C) { tk.MustQuery("select a, count(b) from (select * from t union all select * from tt) k group by a order by a").Check(testkit.Rows("1 2", "2 1")) } -func (s *testSuite) TestOnlyFullGroupBy(c *C) { +func (s *testSuite1) TestOnlyFullGroupBy(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("set sql_mode = 'ONLY_FULL_GROUP_BY'") @@ -451,39 +446,39 @@ func (s *testSuite) TestOnlyFullGroupBy(c *C) { tk.MustQuery("select max(a) from t group by d") // test incompatible with sql_mode = ONLY_FULL_GROUP_BY var err error - _, err = tk.Exec("select * from t group by d") + err = tk.ExecToErr("select * from t group by d") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select b-c from t group by b+c") + err = tk.ExecToErr("select b-c from t group by b+c") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select (b-c)*(b+c), min(a) from t group by b+c, b-c") + err = tk.ExecToErr("select (b-c)*(b+c), min(a) from t group by b+c, b-c") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select b between c and d from t group by b,c") + err = tk.ExecToErr("select b between c and d from t group by b,c") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select case b when 1 then c when 2 then d else d end from t group by b,c") + err = tk.ExecToErr("select case b when 1 then c when 2 then d else d end from t group by b,c") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select c > (select b from t) from t group by b") + err = tk.ExecToErr("select c > (select b from t) from t group by b") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select c is null from t group by b") + err = tk.ExecToErr("select c is null from t group by b") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select c is true from t group by b") + err = tk.ExecToErr("select c is true from t group by b") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select (c+b)*d from t group by c,d") + err = tk.ExecToErr("select (c+b)*d from t group by c,d") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select b in (c,d) from t group by b,c") + err = tk.ExecToErr("select b in (c,d) from t group by b,c") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select b like '%a' from t group by c") + err = tk.ExecToErr("select b like '%a' from t group by c") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select c REGEXP '1.*' from t group by b") + err = tk.ExecToErr("select c REGEXP '1.*' from t group by b") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select -b from t group by c") + err = tk.ExecToErr("select -b from t group by c") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select a, max(b) from t") + err = tk.ExecToErr("select a, max(b) from t") c.Assert(terror.ErrorEqual(err, plannercore.ErrMixOfGroupFuncAndFields), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select sum(a)+b from t") + err = tk.ExecToErr("select sum(a)+b from t") c.Assert(terror.ErrorEqual(err, plannercore.ErrMixOfGroupFuncAndFields), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select count(b), c from t") + err = tk.ExecToErr("select count(b), c from t") c.Assert(terror.ErrorEqual(err, plannercore.ErrMixOfGroupFuncAndFields), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select distinct a, b, count(a) from t") + err = tk.ExecToErr("select distinct a, b, count(a) from t") c.Assert(terror.ErrorEqual(err, plannercore.ErrMixOfGroupFuncAndFields), IsTrue, Commentf("err %v", err)) // test compatible with sql_mode = ONLY_FULL_GROUP_BY tk.MustQuery("select a from t group by a,b,c") @@ -512,7 +507,7 @@ func (s *testSuite) TestOnlyFullGroupBy(c *C) { // test functional depend on unique not null columns tk.MustQuery("select * from t group by b,d") // test functional depend on a unique null column - _, err = tk.Exec("select * from t group by b,c") + err = tk.ExecToErr("select * from t group by b,c") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) // test functional dependency derived from keys in where condition tk.MustQuery("select * from t where c = d group by b, c") @@ -520,7 +515,7 @@ func (s *testSuite) TestOnlyFullGroupBy(c *C) { tk.MustQuery("select t.*, x.* from t, x where t.b = x.b and t.d = x.d group by t.b, t.d") tk.MustQuery("select t.*, x.* from t, x where t.b = x.a group by t.b, t.d") tk.MustQuery("select t.b, x.* from t, x where t.b = x.a group by t.b") - _, err = tk.Exec("select t.*, x.* from t, x where t.c = x.a group by t.b, t.c") + err = tk.ExecToErr("select t.*, x.* from t, x where t.c = x.a group by t.b, t.c") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) // test functional dependency derived from keys in join tk.MustQuery("select t.*, x.* from t inner join x on t.a = x.a group by t.a") @@ -530,27 +525,27 @@ func (s *testSuite) TestOnlyFullGroupBy(c *C) { tk.MustQuery("select t.b, x.* from t left join x on x.b = t.b group by t.b, x.d") tk.MustQuery("select x.b, t.* from t right join x on x.b = t.b group by x.b, t.d") tk.MustQuery("select x.b, t.* from t right join x on t.b = x.b group by x.b, t.d") - _, err = tk.Exec("select t.b, x.* from t right join x on t.b = x.b group by t.b, x.d") + err = tk.ExecToErr("select t.b, x.* from t right join x on t.b = x.b group by t.b, x.d") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) - _, err = tk.Exec("select t.b, x.* from t right join x on t.b = x.b group by t.b, x.d") + err = tk.ExecToErr("select t.b, x.* from t right join x on t.b = x.b group by t.b, x.d") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) // FixMe: test functional dependency of derived table //tk.MustQuery("select * from (select * from t) as e group by a") //tk.MustQuery("select * from (select * from t) as e group by b,d") - //_, err = tk.Exec("select * from (select * from t) as e group by b,c") + //err = tk.ExecToErr("select * from (select * from t) as e group by b,c") //c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue) // test order by tk.MustQuery("select c from t group by c,d order by d") - _, err = tk.Exec("select c from t group by c order by d") + err = tk.ExecToErr("select c from t group by c order by d") c.Assert(terror.ErrorEqual(err, plannercore.ErrFieldNotInGroupBy), IsTrue, Commentf("err %v", err)) // test ambiguous column - _, err = tk.Exec("select c from t,x group by t.c") + err = tk.ExecToErr("select c from t,x group by t.c") c.Assert(terror.ErrorEqual(err, plannercore.ErrAmbiguous), IsTrue, Commentf("err %v", err)) } -func (s *testSuite) TestHaving(c *C) { +func (s *testSuite1) TestHaving(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) tk.MustExec("set sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'") @@ -575,7 +570,7 @@ func (s *testSuite) TestHaving(c *C) { tk.MustQuery("select 1 from t group by c1 having sum(abs(c2 + c3)) = c1").Check(testkit.Rows("1")) } -func (s *testSuite) TestAggEliminator(c *C) { +func (s *testSuite1) TestAggEliminator(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) tk.MustExec("create table t(a int primary key, b int)") @@ -587,7 +582,7 @@ func (s *testSuite) TestAggEliminator(c *C) { tk.MustQuery("select min(b*b) from t").Check(testkit.Rows("1")) } -func (s *testSuite) TestMaxMinFloatScalaFunc(c *C) { +func (s *testSuite1) TestMaxMinFloatScalaFunc(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) tk.MustExec(`DROP TABLE IF EXISTS T;`) @@ -597,7 +592,7 @@ func (s *testSuite) TestMaxMinFloatScalaFunc(c *C) { tk.MustQuery(`SELECT MIN(CASE B WHEN 'val_b' THEN C ELSE 0 END) val_b FROM T WHERE cast(A as signed) = 0 GROUP BY a;`).Check(testkit.Rows("12.190999984741211")) } -func (s *testSuite) TestBuildProjBelowAgg(c *C) { +func (s *testSuite1) TestBuildProjBelowAgg(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) tk.MustExec("drop table if exists t;") tk.MustExec("create table t (i int);") @@ -609,7 +604,7 @@ func (s *testSuite) TestBuildProjBelowAgg(c *C) { "4 3 18 7,7,7 8")) } -func (s *testSuite) TestFirstRowEnum(c *C) { +func (s *testSuite1) TestFirstRowEnum(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) tk.MustExec(`use test;`) tk.MustExec(`drop table if exists t;`) diff --git a/executor/analyze_test.go b/executor/analyze_test.go index 6e362fbdfc12e..5c0199b8bf9b2 100644 --- a/executor/analyze_test.go +++ b/executor/analyze_test.go @@ -26,7 +26,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestAnalyzePartition(c *C) { +func (s *testSuite1) TestAnalyzePartition(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -88,7 +88,7 @@ PARTITION BY RANGE ( a ) ( } } -func (s *testSuite) TestAnalyzeParameters(c *C) { +func (s *testSuite1) TestAnalyzeParameters(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -102,15 +102,15 @@ func (s *testSuite) TestAnalyzeParameters(c *C) { table, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) c.Assert(err, IsNil) tableInfo := table.Meta() - tbl := s.domain.StatsHandle().GetTableStats(tableInfo) + tbl := s.dom.StatsHandle().GetTableStats(tableInfo) c.Assert(tbl.Columns[1].Len(), Equals, 20) tk.MustExec("analyze table t with 4 buckets") - tbl = s.domain.StatsHandle().GetTableStats(tableInfo) + tbl = s.dom.StatsHandle().GetTableStats(tableInfo) c.Assert(tbl.Columns[1].Len(), Equals, 4) } -func (s *testSuite) TestAnalyzeTooLongColumns(c *C) { +func (s *testSuite1) TestAnalyzeTooLongColumns(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -123,7 +123,7 @@ func (s *testSuite) TestAnalyzeTooLongColumns(c *C) { table, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t")) c.Assert(err, IsNil) tableInfo := table.Meta() - tbl := s.domain.StatsHandle().GetTableStats(tableInfo) + tbl := s.dom.StatsHandle().GetTableStats(tableInfo) c.Assert(tbl.Columns[1].Len(), Equals, 0) c.Assert(tbl.Columns[1].TotColSize, Equals, int64(65559)) } diff --git a/executor/builder.go b/executor/builder.go index b89439671d0e9..d2f221b30d4aa 100644 --- a/executor/builder.go +++ b/executor/builder.go @@ -1029,8 +1029,8 @@ func (b *executorBuilder) buildProjBelowAgg(aggFuncs []*aggregation.AggFuncDesc, } return &ProjectionExec{ - baseExecutor: newBaseExecutor(b.ctx, expression.NewSchema(projSchemaCols...), projFromID, src), - numWorkers: b.ctx.GetSessionVars().ProjectionConcurrency, + baseExecutor: newBaseExecutor(b.ctx, expression.NewSchema(projSchemaCols...), projFromID, src), + //numWorkers: b.ctx.GetSessionVars().ProjectionConcurrency, evaluatorSuit: expression.NewEvaluatorSuite(projExprs, false), } } diff --git a/executor/ddl_test.go b/executor/ddl_test.go index 010bafa402019..def0f570e27da 100644 --- a/executor/ddl_test.go +++ b/executor/ddl_test.go @@ -34,7 +34,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestTruncateTable(c *C) { +func (s *testSuite3) TestTruncateTable(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec(`drop table if exists truncate_test;`) @@ -51,7 +51,7 @@ func (s *testSuite) TestTruncateTable(c *C) { // 1. Execute the SQL of "begin"; // 2. A SQL that will fail to execute; // 3. Execute DDL. -func (s *testSuite) TestInTxnExecDDLFail(c *C) { +func (s *testSuite3) TestInTxnExecDDLFail(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table t (i int key);") @@ -64,7 +64,7 @@ func (s *testSuite) TestInTxnExecDDLFail(c *C) { result.Check(testkit.Rows("1")) } -func (s *testSuite) TestCreateTable(c *C) { +func (s *testSuite3) TestCreateTable(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") // Test create an exist database @@ -135,7 +135,7 @@ func (s *testSuite) TestCreateTable(c *C) { r.Check(testkit.Rows("1000 aa")) } -func (s *testSuite) TestCreateView(c *C) { +func (s *testSuite3) TestCreateView(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") //create an source table @@ -183,7 +183,7 @@ func (s *testSuite) TestCreateView(c *C) { c.Assert(err.Error(), Equals, ddl.ErrViewWrongList.Error()) } -func (s *testSuite) TestCreateDropDatabase(c *C) { +func (s *testSuite3) TestCreateDropDatabase(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("create database if not exists drop_test;") tk.MustExec("drop database if exists drop_test;") @@ -192,14 +192,14 @@ func (s *testSuite) TestCreateDropDatabase(c *C) { tk.MustExec("drop database drop_test;") _, err := tk.Exec("drop table t;") c.Assert(err.Error(), Equals, plannercore.ErrNoDB.Error()) - _, err = tk.Exec("select * from t;") + err = tk.ExecToErr("select * from t;") c.Assert(err.Error(), Equals, plannercore.ErrNoDB.Error()) _, err = tk.Exec("drop database mysql") c.Assert(err, NotNil) } -func (s *testSuite) TestCreateDropTable(c *C) { +func (s *testSuite3) TestCreateDropTable(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table if not exists drop_test (a int)") @@ -211,7 +211,7 @@ func (s *testSuite) TestCreateDropTable(c *C) { c.Assert(err, NotNil) } -func (s *testSuite) TestCreateDropIndex(c *C) { +func (s *testSuite3) TestCreateDropIndex(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table if not exists drop_test (a int)") @@ -220,14 +220,14 @@ func (s *testSuite) TestCreateDropIndex(c *C) { tk.MustExec("drop table drop_test") } -func (s *testSuite) TestAlterTableAddColumn(c *C) { +func (s *testSuite3) TestAlterTableAddColumn(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table if not exists alter_test (c1 int)") tk.MustExec("insert into alter_test values(1)") tk.MustExec("alter table alter_test add column c2 timestamp default current_timestamp") - time.Sleep(1 * time.Second) - now := time.Now().Add(-time.Duration(1 * time.Second)).Format(types.TimeFormat) + time.Sleep(1 * time.Millisecond) + now := time.Now().Add(-time.Duration(1 * time.Millisecond)).Format(types.TimeFormat) r, err := tk.Exec("select c2 from alter_test") c.Assert(err, IsNil) chk := r.NewChunk() @@ -236,11 +236,12 @@ func (s *testSuite) TestAlterTableAddColumn(c *C) { row := chk.GetRow(0) c.Assert(row.Len(), Equals, 1) c.Assert(now, GreaterEqual, row.GetTime(0).String()) + r.Close() tk.MustExec("alter table alter_test add column c3 varchar(50) default 'CURRENT_TIMESTAMP'") tk.MustQuery("select c3 from alter_test").Check(testkit.Rows("CURRENT_TIMESTAMP")) } -func (s *testSuite) TestAddNotNullColumnNoDefault(c *C) { +func (s *testSuite3) TestAddNotNullColumnNoDefault(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table nn (c1 int)") @@ -261,7 +262,7 @@ func (s *testSuite) TestAddNotNullColumnNoDefault(c *C) { tk.MustQuery("select * from nn").Check(testkit.Rows("1 0", "2 0", "3 0")) } -func (s *testSuite) TestAlterTableModifyColumn(c *C) { +func (s *testSuite3) TestAlterTableModifyColumn(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists mc") @@ -284,7 +285,7 @@ func (s *testSuite) TestAlterTableModifyColumn(c *C) { c.Assert(createSQL, Equals, expected) } -func (s *testSuite) TestDefaultDBAfterDropCurDB(c *C) { +func (s *testSuite3) TestDefaultDBAfterDropCurDB(c *C) { tk := testkit.NewTestKit(c, s.store) testSQL := `create database if not exists test_db CHARACTER SET latin1 COLLATE latin1_swedish_ci;` @@ -303,7 +304,7 @@ func (s *testSuite) TestDefaultDBAfterDropCurDB(c *C) { tk.MustQuery(`select @@collation_database;`).Check(testkit.Rows("utf8_unicode_ci")) } -func (s *testSuite) TestRenameTable(c *C) { +func (s *testSuite3) TestRenameTable(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("create database rename1") @@ -359,7 +360,7 @@ func (s *testSuite) TestRenameTable(c *C) { tk.MustExec("drop database rename2") } -func (s *testSuite) TestUnsupportedCharset(c *C) { +func (s *testSuite3) TestUnsupportedCharset(c *C) { tk := testkit.NewTestKit(c, s.store) dbName := "unsupported_charset" tk.MustExec("create database " + dbName) @@ -387,7 +388,7 @@ func (s *testSuite) TestUnsupportedCharset(c *C) { tk.MustExec("drop database " + dbName) } -func (s *testSuite) TestTooLargeIdentifierLength(c *C) { +func (s *testSuite3) TestTooLargeIdentifierLength(c *C) { tk := testkit.NewTestKit(c, s.store) // for database. @@ -422,7 +423,7 @@ func (s *testSuite) TestTooLargeIdentifierLength(c *C) { c.Assert(err.Error(), Equals, fmt.Sprintf("[ddl:1059]Identifier name '%s' is too long", indexName2)) } -func (s *testSuite) TestShardRowIDBits(c *C) { +func (s *testSuite3) TestShardRowIDBits(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -457,7 +458,7 @@ func (s *testSuite) TestShardRowIDBits(c *C) { tk.MustExec("alter table auto shard_row_id_bits = 0") } -func (s *testSuite) TestMaxHandleAddIndex(c *C) { +func (s *testSuite3) TestMaxHandleAddIndex(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -474,7 +475,7 @@ func (s *testSuite) TestMaxHandleAddIndex(c *C) { tk.MustExec("admin check table t1") } -func (s *testSuite) TestSetDDLReorgWorkerCnt(c *C) { +func (s *testSuite3) TestSetDDLReorgWorkerCnt(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") c.Assert(variable.GetDDLReorgWorkerCounter(), Equals, int32(variable.DefTiDBDDLReorgWorkerCount)) @@ -500,7 +501,7 @@ func (s *testSuite) TestSetDDLReorgWorkerCnt(c *C) { res.Check(testkit.Rows("100")) } -func (s *testSuite) TestSetDDLReorgBatchSize(c *C) { +func (s *testSuite3) TestSetDDLReorgBatchSize(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") c.Assert(variable.GetDDLReorgBatchSize(), Equals, int32(variable.DefTiDBDDLReorgBatchSize)) diff --git a/executor/distsql_test.go b/executor/distsql_test.go index db732a6be415f..54a50b22f214b 100644 --- a/executor/distsql_test.go +++ b/executor/distsql_test.go @@ -19,8 +19,6 @@ import ( "fmt" "runtime/pprof" "strings" - "sync/atomic" - "time" . "github.com/pingcap/check" "github.com/pingcap/parser/model" @@ -31,40 +29,6 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -// TestIndexDoubleReadClose checks that when a index double read returns before reading all the rows, the goroutine doesn't -// leak. For testing distsql with multiple regions, we need to manually split a mock TiKV. -func (s *testSuite) TestIndexDoubleReadClose(c *C) { - if _, ok := s.store.GetClient().(*tikv.CopClient); !ok { - // Make sure the store is tikv store. - return - } - originSize := atomic.LoadInt32(&executor.LookupTableTaskChannelSize) - atomic.StoreInt32(&executor.LookupTableTaskChannelSize, 1) - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("set @@tidb_index_lookup_size = '10'") - tk.MustExec("use test") - tk.MustExec("create table dist (id int primary key, c_idx int, c_col int, index (c_idx))") - - // Insert 100 rows. - var values []string - for i := 0; i < 100; i++ { - values = append(values, fmt.Sprintf("(%d, %d, %d)", i, i, i)) - } - tk.MustExec("insert dist values " + strings.Join(values, ",")) - - rs, err := tk.Exec("select * from dist where c_idx between 0 and 100") - c.Assert(err, IsNil) - chk := rs.NewChunk() - err = rs.Next(context.Background(), chk) - c.Assert(err, IsNil) - c.Assert(err, IsNil) - keyword := "pickAndExecTask" - rs.Close() - time.Sleep(time.Millisecond * 50) - c.Check(checkGoroutineExists(keyword), IsFalse) - atomic.StoreInt32(&executor.LookupTableTaskChannelSize, originSize) -} - func checkGoroutineExists(keyword string) bool { buf := new(bytes.Buffer) profile := pprof.Lookup("goroutine") @@ -73,7 +37,7 @@ func checkGoroutineExists(keyword string) bool { return strings.Contains(str, keyword) } -func (s *testSuite) TestCopClientSend(c *C) { +func (s *testSuite3) TestCopClientSend(c *C) { c.Skip("not stable") if _, ok := s.store.GetClient().(*tikv.CopClient); !ok { // Make sure the store is tikv store. @@ -104,11 +68,11 @@ func (s *testSuite) TestCopClientSend(c *C) { // Send coprocessor request when the table split. rs, err := tk.Exec("select sum(id) from copclient") c.Assert(err, IsNil) - defer rs.Close() chk := rs.NewChunk() err = rs.Next(ctx, chk) c.Assert(err, IsNil) c.Assert(chk.GetRow(0).GetMyDecimal(0).String(), Equals, "499500") + rs.Close() // Split one region. key := tablecodec.EncodeRowKeyWithHandle(tblID, 500) @@ -136,7 +100,7 @@ func (s *testSuite) TestCopClientSend(c *C) { c.Check(checkGoroutineExists(keyword), IsFalse) } -func (s *testSuite) TestGetLackHandles(c *C) { +func (s *testSuite3) TestGetLackHandles(c *C) { expectedHandles := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} handlesMap := make(map[int64]struct{}) for _, h := range expectedHandles { @@ -160,7 +124,7 @@ func (s *testSuite) TestGetLackHandles(c *C) { c.Assert(retHandles, DeepEquals, diffHandles) } -func (s *testSuite) TestBigIntPK(c *C) { +func (s *testSuite3) TestBigIntPK(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table t(a bigint unsigned primary key, b int, c int, index idx(a, b))") @@ -168,7 +132,7 @@ func (s *testSuite) TestBigIntPK(c *C) { tk.MustQuery("select * from t use index(idx) order by a").Check(testkit.Rows("1 1 1", "9223372036854775807 2 2")) } -func (s *testSuite) TestCorColToRanges(c *C) { +func (s *testSuite3) TestCorColToRanges(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("set sql_mode='STRICT_TRANS_TABLES'") // disable only-full-group-by @@ -184,7 +148,7 @@ func (s *testSuite) TestCorColToRanges(c *C) { tk.MustQuery("select t.c in (select count(*) from t s use index(idx), t t1 where s.b = t.a and s.c = t1.a) from t").Check(testkit.Rows("1", "0", "0", "0", "0", "0", "0", "0", "0")) } -func (s *testSuite) TestUniqueKeyNullValueSelect(c *C) { +func (s *testSuite3) TestUniqueKeyNullValueSelect(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") diff --git a/executor/executor.go b/executor/executor.go index 8a33e48bda78e..7e6009ac72166 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -1083,6 +1083,9 @@ func (e *MaxOneRowExec) Next(ctx context.Context, chk *chunk.Chunk) error { childChunk := e.children[0].newFirstChunk() err = e.children[0].Next(ctx, childChunk) + if err != nil { + return errors.Trace(err) + } if childChunk.NumRows() != 0 { return errors.New("subquery returns more than 1 row") } diff --git a/executor/executor_test.go b/executor/executor_test.go index c5b1a2bebd257..0aeff4bb3598a 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -29,7 +29,6 @@ import ( "github.com/golang/protobuf/proto" . "github.com/pingcap/check" "github.com/pingcap/errors" - gofail "github.com/pingcap/gofail/runtime" pb "github.com/pingcap/kvproto/pkg/kvrpcpb" "github.com/pingcap/parser" "github.com/pingcap/parser/model" @@ -66,17 +65,25 @@ import ( "github.com/pingcap/tipb/go-tipb" ) +// TestLeakCheckCnt is the check count in the pacakge of executor. +// In this package CustomParallelSuiteFlag is true, so we need to increase check count. +const TestLeakCheckCnt = 1000 + func TestT(t *testing.T) { CustomVerboseFlag = true + *CustomParallelSuiteFlag = true logLevel := os.Getenv("log_level") logutil.InitLogger(&logutil.LogConfig{ Level: logLevel, }) + autoid.SetStep(5000) TestingT(t) } var _ = Suite(&testSuite{}) -var _ = Suite(&testContextOptionSuite{}) +var _ = Suite(&testSuite1{}) +var _ = Suite(&testSuite2{}) +var _ = Suite(&testSuite3{}) var _ = Suite(&testBypassSuite{}) type testSuite struct { @@ -86,16 +93,12 @@ type testSuite struct { domain *domain.Domain *parser.Parser ctx *mock.Context - - autoIDStep int64 } var mockTikv = flag.Bool("mockTikv", true, "use mock tikv store in executor test") func (s *testSuite) SetUpSuite(c *C) { testleak.BeforeTest() - s.autoIDStep = autoid.GetStep() - autoid.SetStep(5000) s.Parser = parser.New() flag.Lookup("mockTikv") useMockTikv := *mockTikv @@ -121,8 +124,7 @@ func (s *testSuite) SetUpSuite(c *C) { func (s *testSuite) TearDownSuite(c *C) { s.domain.Close() s.store.Close() - autoid.SetStep(s.autoIDStep) - testleak.AfterTest(c)() + testleak.AfterTest(c, TestLeakCheckCnt)() } func (s *testSuite) TearDownTest(c *C) { @@ -682,7 +684,7 @@ func (s *testSuite) TestSelectLimit(c *C) { r = tk.MustQuery("select * from select_limit limit 18446744073709551615 offset 3;") r.Check(testkit.Rows("4 hello")) - _, err := tk.Exec("select * from select_limit limit 18446744073709551616 offset 3;") + err := tk.ExecToErr("select * from select_limit limit 18446744073709551616 offset 3;") c.Assert(err, NotNil) } @@ -810,28 +812,28 @@ func (s *testSuite) TestSelectErrorRow(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") - _, err := tk.Exec("select row(1, 1) from test") + err := tk.ExecToErr("select row(1, 1) from test") c.Assert(err, NotNil) - _, err = tk.Exec("select * from test group by row(1, 1);") + err = tk.ExecToErr("select * from test group by row(1, 1);") c.Assert(err, NotNil) - _, err = tk.Exec("select * from test order by row(1, 1);") + err = tk.ExecToErr("select * from test order by row(1, 1);") c.Assert(err, NotNil) - _, err = tk.Exec("select * from test having row(1, 1);") + err = tk.ExecToErr("select * from test having row(1, 1);") c.Assert(err, NotNil) - _, err = tk.Exec("select (select 1, 1) from test;") + err = tk.ExecToErr("select (select 1, 1) from test;") c.Assert(err, NotNil) - _, err = tk.Exec("select * from test group by (select 1, 1);") + err = tk.ExecToErr("select * from test group by (select 1, 1);") c.Assert(err, NotNil) - _, err = tk.Exec("select * from test order by (select 1, 1);") + err = tk.ExecToErr("select * from test order by (select 1, 1);") c.Assert(err, NotNil) - _, err = tk.Exec("select * from test having (select 1, 1);") + err = tk.ExecToErr("select * from test having (select 1, 1);") c.Assert(err, NotNil) } @@ -850,6 +852,7 @@ func (s *testSuite) TestIssue2612(c *C) { err = rs.Next(context.Background(), chk) c.Assert(err, IsNil) c.Assert(chk.GetRow(0).GetDuration(0, 0).String(), Equals, "-46:09:02") + rs.Close() } // TestIssue345 is related with https://github.com/pingcap/tidb/issues/345 @@ -1038,12 +1041,12 @@ func (s *testSuite) TestUnion(c *C) { tk.MustQuery("select -10 as a from dual union select a from t order by a limit 1 ").Check(testkit.Rows("-10")) tk.MustQuery("select count(1) from (select a from t union all select a from t) tmp").Check(testkit.Rows("4")) - _, err := tk.Exec("select 1 from (select a from t limit 1 union all select a from t limit 1) tmp") + err := tk.ExecToErr("select 1 from (select a from t limit 1 union all select a from t limit 1) tmp") c.Assert(err, NotNil) terr := errors.Cause(err).(*terror.Error) c.Assert(terr.Code(), Equals, terror.ErrCode(mysql.ErrWrongUsage)) - _, err = tk.Exec("select 1 from (select a from t order by a union all select a from t limit 1) tmp") + err = tk.ExecToErr("select 1 from (select a from t order by a union all select a from t limit 1) tmp") c.Assert(err, NotNil) terr = errors.Cause(err).(*terror.Error) c.Assert(terr.Code(), Equals, terror.ErrCode(mysql.ErrWrongUsage)) @@ -1922,12 +1925,14 @@ func (s *testSuite) TestColumnName(c *C) { c.Check(fields[0].ColumnAsName.L, Equals, "1 + c") c.Check(fields[1].Column.Name.L, Equals, "count(*)") c.Check(fields[1].ColumnAsName.L, Equals, "count(*)") + rs.Close() rs, err = tk.Exec("select (c) > all (select c from t) from t") c.Check(err, IsNil) fields = rs.Fields() c.Check(len(fields), Equals, 1) c.Check(fields[0].Column.Name.L, Equals, "(c) > all (select c from t)") c.Check(fields[0].ColumnAsName.L, Equals, "(c) > all (select c from t)") + rs.Close() tk.MustExec("begin") tk.MustExec("insert t values(1,1)") rs, err = tk.Exec("select c d, d c from t") @@ -1938,6 +1943,7 @@ func (s *testSuite) TestColumnName(c *C) { c.Check(fields[0].ColumnAsName.L, Equals, "d") c.Check(fields[1].Column.Name.L, Equals, "d") c.Check(fields[1].ColumnAsName.L, Equals, "c") + rs.Close() // Test case for query a column of a table. // In this case, all attributes have values. rs, err = tk.Exec("select c as a from t as t2") @@ -1948,6 +1954,7 @@ func (s *testSuite) TestColumnName(c *C) { c.Check(fields[0].Table.Name.L, Equals, "t") c.Check(fields[0].TableAsName.L, Equals, "t2") c.Check(fields[0].DBName.L, Equals, "test") + rs.Close() // Test case for query a expression which only using constant inputs. // In this case, the table, org_table and database attributes will all be empty. rs, err = tk.Exec("select hour(1) as a from t as t2") @@ -1958,6 +1965,7 @@ func (s *testSuite) TestColumnName(c *C) { c.Check(fields[0].Table.Name.L, Equals, "") c.Check(fields[0].TableAsName.L, Equals, "") c.Check(fields[0].DBName.L, Equals, "") + rs.Close() // Test case for query a column wrapped with parentheses and unary plus. // In this case, the column name should be its original name. rs, err = tk.Exec("select (c), (+c), +(c), +(+(c)), ++c from t") @@ -1967,6 +1975,7 @@ func (s *testSuite) TestColumnName(c *C) { c.Check(fields[0].Column.Name.L, Equals, "c") c.Check(fields[0].ColumnAsName.L, Equals, "c") } + rs.Close() } func (s *testSuite) TestSelectVar(c *C) { @@ -2350,13 +2359,13 @@ func (c *checkRequestClient) SendRequest(ctx context.Context, addr string, req * return resp, err } -type testContextOptionSuite struct { +type testSuite1 struct { store kv.Storage dom *domain.Domain cli *checkRequestClient } -func (s *testContextOptionSuite) SetUpSuite(c *C) { +func (s *testSuite1) SetUpSuite(c *C) { cli := &checkRequestClient{} hijackClient := func(c tikv.Client) tikv.Client { cli.Client = c @@ -2373,12 +2382,22 @@ func (s *testContextOptionSuite) SetUpSuite(c *C) { c.Assert(err, IsNil) } -func (s *testContextOptionSuite) TearDownSuite(c *C) { +func (s *testSuite1) TearDownSuite(c *C) { s.dom.Close() s.store.Close() } -func (s *testContextOptionSuite) TestAddIndexPriority(c *C) { +func (s *testSuite1) TearDownTest(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + r := tk.MustQuery("show tables") + for _, tb := range r.Rows() { + tableName := tb[0] + tk.MustExec(fmt.Sprintf("drop table %v", tableName)) + } +} + +func (s *testSuite1) TestAddIndexPriority(c *C) { cli := &checkRequestClient{} hijackClient := func(c tikv.Client) tikv.Client { cli.Client = c @@ -2447,7 +2466,7 @@ func (s *testContextOptionSuite) TestAddIndexPriority(c *C) { cli.mu.Unlock() } -func (s *testContextOptionSuite) TestAlterTableComment(c *C) { +func (s *testSuite1) TestAlterTableComment(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t_1") @@ -2460,7 +2479,7 @@ func (s *testContextOptionSuite) TestAlterTableComment(c *C) { result.Check(testkit.Rows("table t comment")) } -func (s *testContextOptionSuite) TestCoprocessorPriority(c *C) { +func (s *testSuite1) TestCoprocessorPriority(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table t (id int primary key)") @@ -2581,7 +2600,7 @@ func (s *testSuite) TestNotFillCacheFlag(c *C) { c.Assert(count, Equals, len(tests)) // Make sure the hook function is called. } -func (s *testContextOptionSuite) TestSyncLog(c *C) { +func (s *testSuite1) TestSyncLog(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -2640,6 +2659,7 @@ func (s *testSuite) TestBit(c *C) { err = r.Next(context.Background(), chk) c.Assert(err, IsNil) c.Assert(types.BinaryLiteral(chk.GetRow(0).GetBytes(0)), DeepEquals, types.NewBinaryLiteralFromUint(2, -1)) + r.Close() tk.MustExec("drop table if exists t") tk.MustExec("create table t (c1 bit(31))") @@ -2774,51 +2794,6 @@ func (s *testSuite) TestUnsignedPk(c *C) { tk.MustQuery("select * from t where id not in (2)").Check(testkit.Rows(num1Str, num2Str, "1")) } -func (s *testSuite) TestEarlyClose(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("create table earlyclose (id int primary key)") - - // Insert 1000 rows. - var values []string - for i := 0; i < 1000; i++ { - values = append(values, fmt.Sprintf("(%d)", i)) - } - tk.MustExec("insert earlyclose values " + strings.Join(values, ",")) - - // Get table ID for split. - dom := domain.GetDomain(tk.Se) - is := dom.InfoSchema() - tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("earlyclose")) - c.Assert(err, IsNil) - tblID := tbl.Meta().ID - - // Split the table. - s.cluster.SplitTable(s.mvccStore, tblID, 500) - - ctx := context.Background() - for i := 0; i < 500; i++ { - rss, err1 := tk.Se.Execute(ctx, "select * from earlyclose order by id") - c.Assert(err1, IsNil) - rs := rss[0] - chk := rs.NewChunk() - err = rs.Next(ctx, chk) - c.Assert(err, IsNil) - rs.Close() - } - - // Goroutine should not leak when error happen. - gofail.Enable("github.com/pingcap/tidb/store/tikv/handleTaskOnceError", `return(true)`) - defer gofail.Disable("github.com/pingcap/tidb/store/tikv/handleTaskOnceError") - rss, err := tk.Se.Execute(ctx, "select * from earlyclose") - c.Assert(err, IsNil) - rs := rss[0] - chk := rs.NewChunk() - err = rs.Next(ctx, chk) - c.Assert(err, NotNil) - rs.Close() -} - func (s *testSuite) TestIssue5666(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("set @@profiling=1") @@ -3081,7 +3056,7 @@ func (s *testSuite) TestCoprocessorStreamingWarning(c *C) { tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1105|Division by 0")) } -func (s *testSuite) TestYearTypeDeleteIndex(c *C) { +func (s *testSuite3) TestYearTypeDeleteIndex(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -3091,7 +3066,7 @@ func (s *testSuite) TestYearTypeDeleteIndex(c *C) { tk.MustExec("admin check table t") } -func (s *testSuite) TestForSelectScopeInUnion(c *C) { +func (s *testSuite3) TestForSelectScopeInUnion(c *C) { // A union B for update, the "for update" option belongs to union statement, so // it should works on both A and B. tk1 := testkit.NewTestKit(c, s.store) @@ -3123,7 +3098,7 @@ func (s *testSuite) TestForSelectScopeInUnion(c *C) { c.Assert(err, IsNil) } -func (s *testSuite) TestUnsignedDecimalOverflow(c *C) { +func (s *testSuite3) TestUnsignedDecimalOverflow(c *C) { tests := []struct { input interface{} hasErr bool @@ -3173,7 +3148,7 @@ func (s *testSuite) TestUnsignedDecimalOverflow(c *C) { r.Check(testkit.Rows("0.00")) } -func (s *testSuite) TestIndexJoinTableDualPanic(c *C) { +func (s *testSuite3) TestIndexJoinTableDualPanic(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists a") @@ -3183,7 +3158,7 @@ func (s *testSuite) TestIndexJoinTableDualPanic(c *C) { Check(testkit.Rows("1 a")) } -func (s *testSuite) TestUnionAutoSignedCast(c *C) { +func (s *testSuite3) TestUnionAutoSignedCast(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1,t2") @@ -3223,7 +3198,7 @@ func (s *testSuite) TestUnionAutoSignedCast(c *C) { Check(testkit.Rows("1 1", "2 -1", "3 -1")) } -func (s *testSuite) TestUpdateJoin(c *C) { +func (s *testSuite3) TestUpdateJoin(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2, t3, t4, t5, t6, t7") @@ -3296,7 +3271,7 @@ func (s *testSuite) TestUpdateJoin(c *C) { tk.MustQuery("select v from t6").Check(testkit.Rows("a")) } -func (s *testSuite) TestMaxOneRow(c *C) { +func (s *testSuite3) TestMaxOneRow(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`use test`) tk.MustExec(`drop table if exists t1`) @@ -3316,7 +3291,7 @@ func (s *testSuite) TestMaxOneRow(c *C) { c.Assert(err, IsNil) } -func (s *testSuite) TestCurrentTimestampValueSelection(c *C) { +func (s *testSuite3) TestCurrentTimestampValueSelection(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t,t1") @@ -3350,7 +3325,7 @@ func (s *testSuite) TestCurrentTimestampValueSelection(c *C) { c.Assert(len(strings.Split(d, ".")[1]), Equals, 3) } -func (s *testSuite) TestRowID(c *C) { +func (s *testSuite3) TestRowID(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`use test`) tk.MustExec(`drop table if exists t`) @@ -3372,7 +3347,7 @@ func (s *testSuite) TestRowID(c *C) { tk.MustQuery("select *, _tidb_rowid from t use index(`primary`) where _tidb_rowid=1").Check(testkit.Rows("a 1")) } -func (s *testSuite) TestDoSubquery(c *C) { +func (s *testSuite3) TestDoSubquery(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`use test`) tk.MustExec(`drop table if exists t`) @@ -3385,7 +3360,7 @@ func (s *testSuite) TestDoSubquery(c *C) { c.Assert(r, IsNil, Commentf("result of Do not empty")) } -func (s *testSuite) TestTSOFail(c *C) { +func (s *testSuite3) TestTSOFail(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`use test`) tk.MustExec(`drop table if exists t`) @@ -3397,7 +3372,7 @@ func (s *testSuite) TestTSOFail(c *C) { c.Assert(err, NotNil) } -func (s *testSuite) TestSelectHashPartitionTable(c *C) { +func (s *testSuite3) TestSelectHashPartitionTable(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`use test`) tk.MustExec(`drop table if exists th`) @@ -3463,3 +3438,101 @@ func (s *testSuite) TestSelectView(c *C) { tk.MustExec("drop table view_t;") tk.MustExec("drop view view1,view2,view3;") } + +type testSuite2 struct { + cluster *mocktikv.Cluster + mvccStore mocktikv.MVCCStore + store kv.Storage + domain *domain.Domain + *parser.Parser + ctx *mock.Context +} + +func (s *testSuite2) SetUpSuite(c *C) { + testleak.BeforeTest() + s.Parser = parser.New() + flag.Lookup("mockTikv") + useMockTikv := *mockTikv + if useMockTikv { + s.cluster = mocktikv.NewCluster() + mocktikv.BootstrapWithSingleStore(s.cluster) + s.mvccStore = mocktikv.MustNewMVCCStore() + store, err := mockstore.NewMockTikvStore( + mockstore.WithCluster(s.cluster), + mockstore.WithMVCCStore(s.mvccStore), + ) + c.Assert(err, IsNil) + s.store = store + session.SetSchemaLease(0) + session.SetStatsLease(0) + } + d, err := session.BootstrapSession(s.store) + c.Assert(err, IsNil) + d.SetStatsUpdating(true) + s.domain = d +} + +func (s *testSuite2) TearDownSuite(c *C) { + s.domain.Close() + s.store.Close() + testleak.AfterTest(c, TestLeakCheckCnt)() +} + +func (s *testSuite2) TearDownTest(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + r := tk.MustQuery("show tables") + for _, tb := range r.Rows() { + tableName := tb[0] + tk.MustExec(fmt.Sprintf("drop table %v", tableName)) + } +} + +type testSuite3 struct { + cluster *mocktikv.Cluster + mvccStore mocktikv.MVCCStore + store kv.Storage + domain *domain.Domain + *parser.Parser + ctx *mock.Context +} + +func (s *testSuite3) SetUpSuite(c *C) { + testleak.BeforeTest() + s.Parser = parser.New() + flag.Lookup("mockTikv") + useMockTikv := *mockTikv + if useMockTikv { + s.cluster = mocktikv.NewCluster() + mocktikv.BootstrapWithSingleStore(s.cluster) + s.mvccStore = mocktikv.MustNewMVCCStore() + store, err := mockstore.NewMockTikvStore( + mockstore.WithCluster(s.cluster), + mockstore.WithMVCCStore(s.mvccStore), + ) + c.Assert(err, IsNil) + s.store = store + session.SetSchemaLease(0) + session.SetStatsLease(0) + } + d, err := session.BootstrapSession(s.store) + c.Assert(err, IsNil) + d.SetStatsUpdating(true) + s.domain = d +} + +func (s *testSuite3) TearDownSuite(c *C) { + s.domain.Close() + s.store.Close() + testleak.AfterTest(c, TestLeakCheckCnt)() +} + +func (s *testSuite3) TearDownTest(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + r := tk.MustQuery("show tables") + for _, tb := range r.Rows() { + tableName := tb[0] + tk.MustExec(fmt.Sprintf("drop table %v", tableName)) + } +} diff --git a/executor/grant_test.go b/executor/grant_test.go index 3e9817a0d96ac..01085eb073f86 100644 --- a/executor/grant_test.go +++ b/executor/grant_test.go @@ -24,7 +24,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestGrantGlobal(c *C) { +func (s *testSuite3) TestGrantGlobal(c *C) { tk := testkit.NewTestKit(c, s.store) // Create a new user. createUserSQL := `CREATE USER 'testGlobal'@'localhost' IDENTIFIED BY '123';` @@ -55,7 +55,7 @@ func (s *testSuite) TestGrantGlobal(c *C) { } } -func (s *testSuite) TestGrantDBScope(c *C) { +func (s *testSuite3) TestGrantDBScope(c *C) { tk := testkit.NewTestKit(c, s.store) // Create a new user. createUserSQL := `CREATE USER 'testDB'@'localhost' IDENTIFIED BY '123';` @@ -84,7 +84,7 @@ func (s *testSuite) TestGrantDBScope(c *C) { } } -func (s *testSuite) TestWithGrantOption(c *C) { +func (s *testSuite3) TestWithGrantOption(c *C) { tk := testkit.NewTestKit(c, s.store) // Create a new user. createUserSQL := `CREATE USER 'testWithGrant'@'localhost' IDENTIFIED BY '123';` @@ -98,7 +98,7 @@ func (s *testSuite) TestWithGrantOption(c *C) { tk.MustQuery("SELECT grant_priv FROM mysql.DB WHERE User=\"testWithGrant\" and host=\"localhost\" and db=\"test\"").Check(testkit.Rows("Y")) } -func (s *testSuite) TestTableScope(c *C) { +func (s *testSuite3) TestTableScope(c *C) { tk := testkit.NewTestKit(c, s.store) // Create a new user. createUserSQL := `CREATE USER 'testTbl'@'localhost' IDENTIFIED BY '123';` @@ -136,7 +136,7 @@ func (s *testSuite) TestTableScope(c *C) { } } -func (s *testSuite) TestColumnScope(c *C) { +func (s *testSuite3) TestColumnScope(c *C) { tk := testkit.NewTestKit(c, s.store) // Create a new user. createUserSQL := `CREATE USER 'testCol'@'localhost' IDENTIFIED BY '123';` @@ -176,14 +176,14 @@ func (s *testSuite) TestColumnScope(c *C) { } } -func (s *testSuite) TestIssue2456(c *C) { +func (s *testSuite3) TestIssue2456(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("CREATE USER 'dduser'@'%' IDENTIFIED by '123456';") tk.MustExec("GRANT ALL PRIVILEGES ON `dddb_%`.* TO 'dduser'@'%';") tk.MustExec("GRANT ALL PRIVILEGES ON `dddb_%`.`te%` to 'dduser'@'%';") } -func (s *testSuite) TestNoAutoCreateUser(c *C) { +func (s *testSuite3) TestNoAutoCreateUser(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`DROP USER IF EXISTS 'test'@'%'`) tk.MustExec(`SET sql_mode='NO_AUTO_CREATE_USER'`) @@ -192,7 +192,7 @@ func (s *testSuite) TestNoAutoCreateUser(c *C) { c.Assert(terror.ErrorEqual(err, executor.ErrPasswordNoMatch), IsTrue) } -func (s *testSuite) TestCreateUserWhenGrant(c *C) { +func (s *testSuite3) TestCreateUserWhenGrant(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`DROP USER IF EXISTS 'test'@'%'`) // This only applies to sql_mode:NO_AUTO_CREATE_USER off @@ -205,7 +205,7 @@ func (s *testSuite) TestCreateUserWhenGrant(c *C) { tk.MustExec(`DROP USER IF EXISTS 'test'@'%'`) } -func (s *testSuite) TestIssue2654(c *C) { +func (s *testSuite3) TestIssue2654(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`DROP USER IF EXISTS 'test'@'%'`) tk.MustExec(`CREATE USER 'test'@'%' IDENTIFIED BY 'test'`) @@ -214,7 +214,7 @@ func (s *testSuite) TestIssue2654(c *C) { rows.Check(testkit.Rows(`test %`)) } -func (s *testSuite) TestGrantUnderANSIQuotes(c *C) { +func (s *testSuite3) TestGrantUnderANSIQuotes(c *C) { tk := testkit.NewTestKit(c, s.store) // Fix a bug that the GrantExec fails in ANSI_QUOTES sql mode // The bug is caused by the improper usage of double quotes like: diff --git a/executor/index_lookup_join_test.go b/executor/index_lookup_join_test.go index 3da1ede553a4f..adeb966a1f764 100644 --- a/executor/index_lookup_join_test.go +++ b/executor/index_lookup_join_test.go @@ -20,7 +20,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestIndexLookupJoinHang(c *C) { +func (s *testSuite1) TestIndexLookupJoinHang(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) tk.MustExec("create table idxJoinOuter (a int unsigned)") tk.MustExec("create table idxJoinInner (a int unsigned unique)") @@ -38,7 +38,7 @@ func (s *testSuite) TestIndexLookupJoinHang(c *C) { rs.Close() } -func (s *testSuite) TestIndexJoinUnionScan(c *C) { +func (s *testSuite1) TestIndexJoinUnionScan(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) tk.MustExec("create table t1(id int primary key, a int)") tk.MustExec("create table t2(id int primary key, a int, b int, key idx_a(a))") @@ -92,7 +92,7 @@ func (s *testSuite) TestIndexJoinUnionScan(c *C) { tk.MustExec("rollback") } -func (s *testSuite) TestBatchIndexJoinUnionScan(c *C) { +func (s *testSuite1) TestBatchIndexJoinUnionScan(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) tk.MustExec("create table t1(id int primary key, a int)") tk.MustExec("create table t2(id int primary key, a int, key idx_a(a))") diff --git a/executor/insert_test.go b/executor/insert_test.go index 71407c64f5ad9..2542da7461aca 100644 --- a/executor/insert_test.go +++ b/executor/insert_test.go @@ -20,7 +20,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestInsertOnDuplicateKey(c *C) { +func (s *testSuite3) TestInsertOnDuplicateKey(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -184,7 +184,7 @@ func (s *testSuite) TestInsertOnDuplicateKey(c *C) { tk.CheckLastMessage("Records: 5 Duplicates: 2 Warnings: 0") } -func (s *testSuite) TestUpdateDuplicateKey(c *C) { +func (s *testSuite3) TestUpdateDuplicateKey(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -196,7 +196,7 @@ func (s *testSuite) TestUpdateDuplicateKey(c *C) { c.Assert(err.Error(), Equals, "[kv:1062]Duplicate entry '1-2-4' for key 'PRIMARY'") } -func (s *testSuite) TestInsertWrongValueForField(c *C) { +func (s *testSuite3) TestInsertWrongValueForField(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec(`drop table if exists t1;`) @@ -205,7 +205,7 @@ func (s *testSuite) TestInsertWrongValueForField(c *C) { c.Assert(terror.ErrorEqual(err, table.ErrTruncatedWrongValueForField), IsTrue) } -func (s *testSuite) TestInsertDateTimeWithTimeZone(c *C) { +func (s *testSuite3) TestInsertDateTimeWithTimeZone(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`use test;`) @@ -220,7 +220,7 @@ func (s *testSuite) TestInsertDateTimeWithTimeZone(c *C) { )) } -func (s *testSuite) TestInsertZeroYear(c *C) { +func (s *testSuite3) TestInsertZeroYear(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec(`drop table if exists t1;`) diff --git a/executor/join_test.go b/executor/join_test.go index 364a8027069db..cdb028882d0ab 100644 --- a/executor/join_test.go +++ b/executor/join_test.go @@ -23,18 +23,18 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestJoinPanic(c *C) { +func (s *testSuite2) TestJoinPanic(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("set sql_mode = 'ONLY_FULL_GROUP_BY'") tk.MustExec("drop table if exists events") tk.MustExec("create table events (clock int, source int)") tk.MustQuery("SELECT * FROM events e JOIN (SELECT MAX(clock) AS clock FROM events e2 GROUP BY e2.source) e3 ON e3.clock=e.clock") - _, err := tk.Exec("SELECT * FROM events e JOIN (SELECT clock FROM events e2 GROUP BY e2.source) e3 ON e3.clock=e.clock") + err := tk.ExecToErr("SELECT * FROM events e JOIN (SELECT clock FROM events e2 GROUP BY e2.source) e3 ON e3.clock=e.clock") c.Check(err, NotNil) } -func (s *testSuite) TestJoin(c *C) { +func (s *testSuite2) TestJoin(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("set @@tidb_index_lookup_join_concurrency = 200") @@ -119,11 +119,11 @@ func (s *testSuite) TestJoin(c *C) { result.Check(testkit.Rows("1", "2", "3")) plannercore.AllowCartesianProduct = false - _, err := tk.Exec("select * from t, t1") + err := tk.ExecToErr("select * from t, t1") c.Check(plannercore.ErrCartesianProductUnsupported.Equal(err), IsTrue) - _, err = tk.Exec("select * from t left join t1 on 1") + err = tk.ExecToErr("select * from t left join t1 on 1") c.Check(plannercore.ErrCartesianProductUnsupported.Equal(err), IsTrue) - _, err = tk.Exec("select * from t right join t1 on 1") + err = tk.ExecToErr("select * from t right join t1 on 1") c.Check(plannercore.ErrCartesianProductUnsupported.Equal(err), IsTrue) plannercore.AllowCartesianProduct = true tk.MustExec("drop table if exists t,t2,t1") @@ -152,11 +152,11 @@ func (s *testSuite) TestJoin(c *C) { tk.MustQuery("select /*+ TIDB_INLJ(t) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000")) // Test that two conflict hints will return error. - _, err = tk.Exec("select /*+ TIDB_INLJ(t) TIDB_SMJ(t) */ * from t join t1 on t.a=t1.a") + err = tk.ExecToErr("select /*+ TIDB_INLJ(t) TIDB_SMJ(t) */ * from t join t1 on t.a=t1.a") c.Assert(err, NotNil) - _, err = tk.Exec("select /*+ TIDB_INLJ(t) TIDB_HJ(t) */ from t join t1 on t.a=t1.a") + err = tk.ExecToErr("select /*+ TIDB_INLJ(t) TIDB_HJ(t) */ from t join t1 on t.a=t1.a") c.Assert(err, NotNil) - _, err = tk.Exec("select /*+ TIDB_SMJ(t) TIDB_HJ(t) */ from t join t1 on t.a=t1.a") + err = tk.ExecToErr("select /*+ TIDB_SMJ(t) TIDB_HJ(t) */ from t join t1 on t.a=t1.a") c.Assert(err, NotNil) tk.MustExec("drop table if exists t") @@ -279,7 +279,7 @@ func (s *testSuite) TestJoin(c *C) { tk.MustQuery("select min(t2.b) from t1 right join t2 on t2.a=t1.a right join t3 on t2.a=t3.a left join t4 on t3.a=t4.a").Check(testkit.Rows("1")) } -func (s *testSuite) TestJoinCast(c *C) { +func (s *testSuite2) TestJoinCast(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -349,7 +349,7 @@ func (s *testSuite) TestJoinCast(c *C) { tk.MustExec("set @@tidb_max_chunk_size=1024") } -func (s *testSuite) TestUsing(c *C) { +func (s *testSuite2) TestUsing(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -397,7 +397,7 @@ func (s *testSuite) TestUsing(c *C) { tk.MustExec("select * from t join tt using(a)") } -func (s *testSuite) TestNaturalJoin(c *C) { +func (s *testSuite2) TestNaturalJoin(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -412,7 +412,7 @@ func (s *testSuite) TestNaturalJoin(c *C) { tk.MustQuery("select * from t1 natural right join t2 order by a").Check(testkit.Rows("1 3 2", "100 200 ")) } -func (s *testSuite) TestMultiJoin(c *C) { +func (s *testSuite2) TestMultiJoin(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table t35(a35 int primary key, b35 int, x35 int)") @@ -504,7 +504,7 @@ AND b44=a42`) result.Check(testkit.Rows("7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7")) } -func (s *testSuite) TestSubquerySameTable(c *C) { +func (s *testSuite2) TestSubquerySameTable(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -516,7 +516,7 @@ func (s *testSuite) TestSubquerySameTable(c *C) { result.Check(testkit.Rows("1")) } -func (s *testSuite) TestSubquery(c *C) { +func (s *testSuite2) TestSubquery(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("set @@tidb_hash_join_concurrency=1") tk.MustExec("set @@tidb_hashagg_partial_concurrency=1") @@ -528,6 +528,9 @@ func (s *testSuite) TestSubquery(c *C) { tk.MustExec("insert t values (2, 2)") tk.MustExec("insert t values (3, 4)") tk.MustExec("commit") + + tk.MustExec("set sql_mode = 'STRICT_TRANS_TABLES'") + result := tk.MustQuery("select * from t where exists(select * from t k where t.c = k.c having sum(c) = 1)") result.Check(testkit.Rows("1 1")) result = tk.MustQuery("select * from t where exists(select k.c, k.d from t k, t p where t.c = k.d)") @@ -685,7 +688,7 @@ func (s *testSuite) TestSubquery(c *C) { tk.MustExec("set @@tidb_hash_join_concurrency=5") } -func (s *testSuite) TestInSubquery(c *C) { +func (s *testSuite2) TestInSubquery(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -752,7 +755,7 @@ func (s *testSuite) TestInSubquery(c *C) { result.Check(testkit.Rows("2", "2", "1")) } -func (s *testSuite) TestJoinLeak(c *C) { +func (s *testSuite2) TestJoinLeak(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("set @@tidb_hash_join_concurrency=1") tk.MustExec("use test") @@ -768,13 +771,13 @@ func (s *testSuite) TestJoinLeak(c *C) { chk := result.NewChunk() err = result.Next(context.Background(), chk) c.Assert(err, IsNil) - time.Sleep(100 * time.Millisecond) + time.Sleep(time.Millisecond) result.Close() tk.MustExec("set @@tidb_hash_join_concurrency=5") } -func (s *testSuite) TestHashJoinExecEncodeDecodeRow(c *C) { +func (s *testSuite2) TestHashJoinExecEncodeDecodeRow(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1") @@ -787,7 +790,7 @@ func (s *testSuite) TestHashJoinExecEncodeDecodeRow(c *C) { result.Check(testkit.Rows("2003-06-09 10:51:26")) } -func (s *testSuite) TestSubqueryInJoinOn(c *C) { +func (s *testSuite2) TestSubqueryInJoinOn(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1") @@ -797,11 +800,11 @@ func (s *testSuite) TestSubqueryInJoinOn(c *C) { tk.MustExec("insert into t1 values (1)") tk.MustExec("insert into t2 values (1)") - _, err := tk.Exec("SELECT * FROM t1 JOIN t2 on (t2.id < all (SELECT 1))") + err := tk.ExecToErr("SELECT * FROM t1 JOIN t2 on (t2.id < all (SELECT 1))") c.Check(err, NotNil) } -func (s *testSuite) TestIssue5255(c *C) { +func (s *testSuite2) TestIssue5255(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2") @@ -812,7 +815,7 @@ func (s *testSuite) TestIssue5255(c *C) { tk.MustQuery("select /*+ TIDB_INLJ(t1) */ * from t1 join t2 on t1.a=t2.a").Check(testkit.Rows("1 2017-11-29 2.2 1")) } -func (s *testSuite) TestIssue5278(c *C) { +func (s *testSuite2) TestIssue5278(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t, tt") @@ -822,7 +825,7 @@ func (s *testSuite) TestIssue5278(c *C) { tk.MustQuery("select * from t left join tt on t.a=tt.a left join t ttt on t.a=ttt.a").Check(testkit.Rows("1 1 1 1")) } -func (s *testSuite) TestIndexLookupJoin(c *C) { +func (s *testSuite2) TestIndexLookupJoin(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("set @@tidb_max_chunk_size=2") @@ -883,7 +886,7 @@ func (s *testSuite) TestIndexLookupJoin(c *C) { )) } -func (s *testSuite) TestMergejoinOrder(c *C) { +func (s *testSuite2) TestMergejoinOrder(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2;") @@ -928,7 +931,7 @@ func (s *testSuite) TestMergejoinOrder(c *C) { )) } -func (s *testSuite) TestEmbeddedOuterJoin(c *C) { +func (s *testSuite2) TestEmbeddedOuterJoin(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2") @@ -939,7 +942,7 @@ func (s *testSuite) TestEmbeddedOuterJoin(c *C) { Check(testkit.Rows("1 1 ")) } -func (s *testSuite) TestHashJoin(c *C) { +func (s *testSuite2) TestHashJoin(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2") diff --git a/executor/merge_join_test.go b/executor/merge_join_test.go index 899164094630c..a1bf5613110ce 100644 --- a/executor/merge_join_test.go +++ b/executor/merge_join_test.go @@ -235,7 +235,7 @@ func checkPlanAndRun(tk *testkit.TestKit, c *C, plan string, sql string) *testki return tk.MustQuery(sql) } -func (s *testSuite) TestMergeJoin(c *C) { +func (s *testSuite1) TestMergeJoin(c *C) { // FIXME: the TIDB_SMJ hint does not really work when there is no index on join onCondition. tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -303,11 +303,11 @@ func (s *testSuite) TestMergeJoin(c *C) { tk.MustExec("rollback;") plannercore.AllowCartesianProduct = false - _, err := tk.Exec("select /*+ TIDB_SMJ(t,t1) */ * from t, t1") + err := tk.ExecToErr("select /*+ TIDB_SMJ(t,t1) */ * from t, t1") c.Check(plannercore.ErrCartesianProductUnsupported.Equal(err), IsTrue) - _, err = tk.Exec("select /*+ TIDB_SMJ(t,t1) */ * from t left join t1 on 1") + err = tk.ExecToErr("select /*+ TIDB_SMJ(t,t1) */ * from t left join t1 on 1") c.Check(plannercore.ErrCartesianProductUnsupported.Equal(err), IsTrue) - _, err = tk.Exec("select /*+ TIDB_SMJ(t,t1) */ * from t right join t1 on 1") + err = tk.ExecToErr("select /*+ TIDB_SMJ(t,t1) */ * from t right join t1 on 1") c.Check(plannercore.ErrCartesianProductUnsupported.Equal(err), IsTrue) plannercore.AllowCartesianProduct = true tk.MustExec("drop table if exists t") @@ -333,7 +333,7 @@ func (s *testSuite) TestMergeJoin(c *C) { tk.MustQuery("select /*+ TIDB_SMJ(t, s) */ count(*) from t join s on t.a = s.a").Check(testkit.Rows("4")) } -func (s *testSuite) Test3WaysMergeJoin(c *C) { +func (s *testSuite1) Test3WaysMergeJoin(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") diff --git a/executor/metrics_test.go b/executor/metrics_test.go index 8bc0207c21088..9bac799f2c81b 100644 --- a/executor/metrics_test.go +++ b/executor/metrics_test.go @@ -25,7 +25,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestStmtLabel(c *C) { +func (s *testSuite2) TestStmtLabel(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table label (c1 int primary key, c2 int, c3 int, index (c2))") diff --git a/executor/point_get_test.go b/executor/point_get_test.go index 65f8786ea7f71..e3ba00ccf9f7f 100644 --- a/executor/point_get_test.go +++ b/executor/point_get_test.go @@ -18,7 +18,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestPointGet(c *C) { +func (s *testSuite1) TestPointGet(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table point (id int primary key, c int, d varchar(10), unique c_d (c, d))") @@ -30,6 +30,7 @@ func (s *testSuite) TestPointGet(c *C) { c.Assert(err, IsNil) fields := result.Fields() c.Assert(fields[0].ColumnAsName.O, Equals, "ident") + result.Close() tk.MustExec("CREATE TABLE tab3(pk INTEGER PRIMARY KEY, col0 INTEGER, col1 FLOAT, col2 TEXT, col3 INTEGER, col4 FLOAT, col5 TEXT);") tk.MustExec("CREATE UNIQUE INDEX idx_tab3_0 ON tab3 (col4);") diff --git a/executor/prepared_test.go b/executor/prepared_test.go index d732b275a8f5e..1eb64770f412f 100644 --- a/executor/prepared_test.go +++ b/executor/prepared_test.go @@ -14,317 +14,11 @@ package executor_test import ( - "context" - "math" - "strings" - . "github.com/pingcap/check" - "github.com/pingcap/errors" - "github.com/pingcap/parser/terror" - "github.com/pingcap/tidb/executor" - "github.com/pingcap/tidb/metrics" - plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/util/testkit" - dto "github.com/prometheus/client_model/go" ) -func (s *testSuite) TestPrepared(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - flags := []bool{false, true} - ctx := context.Background() - for _, flag := range flags { - var err error - plannercore.SetPreparedPlanCache(flag) - plannercore.PreparedPlanCacheCapacity = 100 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists prepare_test") - tk.MustExec("create table prepare_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1)") - tk.MustExec("insert prepare_test (c1) values (1),(2),(NULL)") - - tk.MustExec(`prepare stmt_test_1 from 'select id from prepare_test where id > ?'; set @a = 1; execute stmt_test_1 using @a;`) - tk.MustExec(`prepare stmt_test_2 from 'select 1'`) - // Prepare multiple statement is not allowed. - _, err = tk.Exec(`prepare stmt_test_3 from 'select id from prepare_test where id > ?;select id from prepare_test where id > ?;'`) - c.Assert(executor.ErrPrepareMulti.Equal(err), IsTrue) - // The variable count does not match. - _, err = tk.Exec(`prepare stmt_test_4 from 'select id from prepare_test where id > ? and id < ?'; set @a = 1; execute stmt_test_4 using @a;`) - c.Assert(plannercore.ErrWrongParamCount.Equal(err), IsTrue) - // Prepare and deallocate prepared statement immediately. - tk.MustExec(`prepare stmt_test_5 from 'select id from prepare_test where id > ?'; deallocate prepare stmt_test_5;`) - - // Statement not found. - _, err = tk.Exec("deallocate prepare stmt_test_5") - c.Assert(plannercore.ErrStmtNotFound.Equal(err), IsTrue) - - // incorrect SQLs in prepare. issue #3738, SQL in prepare stmt is parsed in DoPrepare. - _, err = tk.Exec(`prepare p from "delete from t where a = 7 or 1=1/*' and b = 'p'";`) - c.Assert(terror.ErrorEqual(err, errors.New(`[parser:1064]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*' and b = 'p'' at line 1`)), IsTrue, Commentf("err %v", err)) - - // The `stmt_test5` should not be found. - _, err = tk.Exec(`set @a = 1; execute stmt_test_5 using @a;`) - c.Assert(plannercore.ErrStmtNotFound.Equal(err), IsTrue) - - // Use parameter marker with argument will run prepared statement. - result := tk.MustQuery("select distinct c1, c2 from prepare_test where c1 = ?", 1) - result.Check(testkit.Rows("1 ")) - - // Call Session PrepareStmt directly to get stmtID. - query := "select c1, c2 from prepare_test where c1 = ?" - stmtID, _, _, err := tk.Se.PrepareStmt(query) - c.Assert(err, IsNil) - rs, err := tk.Se.ExecutePreparedStmt(ctx, stmtID, 1) - c.Assert(err, IsNil) - tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1 ")) - - 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) - c.Assert(err, IsNil) - tk1 := testkit.NewTestKitWithInit(c, s.store) - 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 = (select c1 from prepare_test where c1 = ?)" - stmtID, _, _, err = tk.Se.PrepareStmt(query) - c.Assert(err, IsNil) - _, 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) - c.Assert(err, IsNil) - _, 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 = ?" - stmtID, _, _, err = tk.Se.PrepareStmt(query) - c.Assert(err, IsNil) - tk.MustExec("rollback") - rs, err = tk.Se.ExecutePreparedStmt(ctx, stmtID, 4) - c.Assert(err, IsNil) - tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows()) - - // Check that ast.Statement created by executor.CompileExecutePreparedStmt has query text. - stmt, err := executor.CompileExecutePreparedStmt(tk.Se, stmtID, 1) - c.Assert(err, IsNil) - c.Assert(stmt.OriginText(), Equals, query) - - // Check that rebuild plan works. - tk.Se.PrepareTxnCtx(ctx) - _, err = stmt.RebuildPlan() - c.Assert(err, IsNil) - rs, err = stmt.Exec(ctx) - c.Assert(err, IsNil) - chk := rs.NewChunk() - err = rs.Next(ctx, chk) - c.Assert(err, IsNil) - c.Assert(rs.Close(), IsNil) - - // Make schema change. - tk.MustExec("drop table if exists prepare2") - tk.Exec("create table prepare2 (a int)") - - // Should success as the changed schema do not affect the prepared statement. - _, err = tk.Se.ExecutePreparedStmt(ctx, stmtID, 1) - c.Assert(err, IsNil) - - // Drop a column so the prepared statement become invalid. - query = "select c1, c2 from prepare_test where c1 = ?" - stmtID, _, _, err = tk.Se.PrepareStmt(query) - c.Assert(err, IsNil) - tk.MustExec("alter table prepare_test drop column c2") - - _, err = tk.Se.ExecutePreparedStmt(ctx, stmtID, 1) - c.Assert(plannercore.ErrUnknownColumn.Equal(err), IsTrue) - - tk.MustExec("drop table prepare_test") - _, err = tk.Se.ExecutePreparedStmt(ctx, stmtID, 1) - c.Assert(plannercore.ErrSchemaChanged.Equal(err), IsTrue) - - // issue 3381 - tk.MustExec("drop table if exists prepare3") - tk.MustExec("create table prepare3 (a decimal(1))") - tk.MustExec("prepare stmt from 'insert into prepare3 value(123)'") - _, err = tk.Exec("execute stmt") - c.Assert(err, NotNil) - - _, _, fields, err := tk.Se.PrepareStmt("select a from prepare3") - c.Assert(err, IsNil) - c.Assert(fields[0].DBName.L, Equals, "test") - c.Assert(fields[0].TableAsName.L, Equals, "prepare3") - c.Assert(fields[0].ColumnAsName.L, Equals, "a") - - _, _, fields, err = tk.Se.PrepareStmt("select a from prepare3 where ?") - c.Assert(err, IsNil) - c.Assert(fields[0].DBName.L, Equals, "test") - c.Assert(fields[0].TableAsName.L, Equals, "prepare3") - c.Assert(fields[0].ColumnAsName.L, Equals, "a") - - _, _, fields, err = tk.Se.PrepareStmt("select (1,1) in (select 1,1)") - c.Assert(err, IsNil) - c.Assert(fields[0].DBName.L, Equals, "") - c.Assert(fields[0].TableAsName.L, Equals, "") - c.Assert(fields[0].ColumnAsName.L, Equals, "(1,1) in (select 1,1)") - - _, _, fields, err = tk.Se.PrepareStmt("select a from prepare3 where a = (" + - "select a from prepare2 where a = ?)") - c.Assert(err, IsNil) - c.Assert(fields[0].DBName.L, Equals, "test") - c.Assert(fields[0].TableAsName.L, Equals, "prepare3") - c.Assert(fields[0].ColumnAsName.L, Equals, "a") - - _, _, fields, err = tk.Se.PrepareStmt("select * from prepare3 as t1 join prepare3 as t2") - c.Assert(err, IsNil) - c.Assert(fields[0].DBName.L, Equals, "test") - c.Assert(fields[0].TableAsName.L, Equals, "t1") - c.Assert(fields[0].ColumnAsName.L, Equals, "a") - c.Assert(fields[1].DBName.L, Equals, "test") - c.Assert(fields[1].TableAsName.L, Equals, "t2") - c.Assert(fields[1].ColumnAsName.L, Equals, "a") - - _, _, fields, err = tk.Se.PrepareStmt("update prepare3 set a = ?") - c.Assert(err, IsNil) - c.Assert(len(fields), Equals, 0) - - // issue 8074 - tk.MustExec("drop table if exists prepare1;") - tk.MustExec("create table prepare1 (a decimal(1))") - tk.MustExec("insert into prepare1 values(1);") - _, err = tk.Exec("prepare stmt FROM @sql1") - c.Assert(err.Error(), Equals, "line 1 column 4 near \"\" (total length 4)") - tk.MustExec("SET @sql = 'update prepare1 set a=5 where a=?';") - _, err = tk.Exec("prepare stmt FROM @sql") - c.Assert(err, IsNil) - tk.MustExec("set @var=1;") - _, err = tk.Exec("execute stmt using @var") - c.Assert(err, IsNil) - tk.MustQuery("select a from prepare1;").Check(testkit.Rows("5")) - - // Coverage. - exec := &executor.ExecuteExec{} - exec.Next(ctx, nil) - exec.Close() - } -} - -func (s *testSuite) TestPreparedLimitOffset(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - flags := []bool{false, true} - ctx := context.Background() - for _, flag := range flags { - var err error - plannercore.SetPreparedPlanCache(flag) - plannercore.PreparedPlanCacheCapacity = 100 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists prepare_test") - tk.MustExec("create table prepare_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1)") - tk.MustExec("insert prepare_test (c1) values (1),(2),(NULL)") - tk.MustExec(`prepare stmt_test_1 from 'select id from prepare_test limit ? offset ?'; set @a = 1, @b=1;`) - r := tk.MustQuery(`execute stmt_test_1 using @a, @b;`) - r.Check(testkit.Rows("2")) - - tk.MustExec(`set @a=1.1`) - r = tk.MustQuery(`execute stmt_test_1 using @a, @b;`) - r.Check(testkit.Rows("2")) - - tk.MustExec(`set @c="-1"`) - _, err = tk.Exec("execute stmt_test_1 using @c, @c") - c.Assert(plannercore.ErrWrongArguments.Equal(err), IsTrue) - - stmtID, _, _, err := tk.Se.PrepareStmt("select id from prepare_test limit ?") - c.Assert(err, IsNil) - _, err = tk.Se.ExecutePreparedStmt(ctx, stmtID, 1) - c.Assert(err, IsNil) - } -} - -func (s *testSuite) TestPreparedNullParam(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - flags := []bool{false, true} - for _, flag := range flags { - plannercore.SetPreparedPlanCache(flag) - plannercore.PreparedPlanCacheCapacity = 100 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t (id int, KEY id (id))") - tk.MustExec("insert into t values (1), (2), (3)") - tk.MustExec(`prepare stmt from 'select * from t use index(id) where id = ?'`) - - r := tk.MustQuery(`execute stmt using @id;`) - r.Check(nil) - - r = tk.MustQuery(`execute stmt using @id;`) - r.Check(nil) - - tk.MustExec(`set @id="1"`) - r = tk.MustQuery(`execute stmt using @id;`) - r.Check(testkit.Rows("1")) - - r = tk.MustQuery(`execute stmt using @id2;`) - r.Check(nil) - - r = tk.MustQuery(`execute stmt using @id;`) - r.Check(testkit.Rows("1")) - } -} - -func (s *testSuite) TestPreparedNameResolver(c *C) { +func (s *testSuite1) TestPreparedNameResolver(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -336,452 +30,3 @@ func (s *testSuite) TestPreparedNameResolver(c *C) { _, err = tk.Exec("prepare stmt from '(select * FROM t) union all (select * FROM t) order by a limit ?'") c.Assert(err.Error(), Equals, "[planner:1054]Unknown column 'a' in 'order clause'") } - -func (s *testSuite) TestPrepareMaxParamCountCheck(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t (v int)") - normalSQL, normalParams := generateBatchSQL(math.MaxUint16) - _, err := tk.Exec(normalSQL, normalParams...) - c.Assert(err, IsNil) - - bigSQL, bigParams := generateBatchSQL(math.MaxUint16 + 2) - _, err = tk.Exec(bigSQL, bigParams...) - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[executor:1390]Prepared statement contains too many placeholders") -} - -func (s *testSuite) TestPrepareWithAggregation(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - flags := []bool{false, true} - for _, flag := range flags { - plannercore.SetPreparedPlanCache(flag) - plannercore.PreparedPlanCacheCapacity = 100 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t (id int primary key)") - tk.MustExec("insert into t values (1), (2), (3)") - tk.MustExec(`prepare stmt from 'select sum(id) from t where id = ?'`) - - tk.MustExec(`set @id="1"`) - r := tk.MustQuery(`execute stmt using @id;`) - r.Check(testkit.Rows("1")) - - r = tk.MustQuery(`execute stmt using @id;`) - r.Check(testkit.Rows("1")) - } -} - -func generateBatchSQL(paramCount int) (sql string, paramSlice []interface{}) { - params := make([]interface{}, 0, paramCount) - placeholders := make([]string, 0, paramCount) - for i := 0; i < paramCount; i++ { - params = append(params, i) - placeholders = append(placeholders, "(?)") - } - return "insert into t values " + strings.Join(placeholders, ","), params -} - -func (s *testSuite) TestPreparedIssue7579(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - flags := []bool{false, true} - for _, flag := range flags { - plannercore.SetPreparedPlanCache(flag) - plannercore.PreparedPlanCacheCapacity = 100 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t (a int, b int, index a_idx(a))") - tk.MustExec("insert into t values (1,1), (2,2), (null,3)") - - r := tk.MustQuery("select a, b from t order by b asc;") - r.Check(testkit.Rows("1 1", "2 2", " 3")) - - tk.MustExec(`prepare stmt from 'select a, b from t where ? order by b asc'`) - - r = tk.MustQuery(`execute stmt using @param;`) - r.Check(nil) - - tk.MustExec(`set @param = true`) - r = tk.MustQuery(`execute stmt using @param;`) - r.Check(testkit.Rows("1 1", "2 2", " 3")) - - tk.MustExec(`set @param = false`) - r = tk.MustQuery(`execute stmt using @param;`) - r.Check(nil) - - tk.MustExec(`set @param = 1`) - r = tk.MustQuery(`execute stmt using @param;`) - r.Check(testkit.Rows("1 1", "2 2", " 3")) - - tk.MustExec(`set @param = 0`) - r = tk.MustQuery(`execute stmt using @param;`) - r.Check(nil) - } -} - -func (s *testSuite) TestPreparedInsert(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - metrics.PlanCacheCounter.Reset() - counter := metrics.PlanCacheCounter.WithLabelValues("prepare") - pb := &dto.Metric{} - flags := []bool{false, true} - for _, flag := range flags { - plannercore.SetPreparedPlanCache(flag) - plannercore.PreparedPlanCacheCapacity = 100 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists prepare_test") - tk.MustExec("create table prepare_test (id int PRIMARY KEY, c1 int)") - tk.MustExec(`prepare stmt_insert from 'insert into prepare_test values (?, ?)'`) - tk.MustExec(`set @a=1,@b=1; execute stmt_insert using @a, @b;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(0)) - } - tk.MustExec(`set @a=2,@b=2; execute stmt_insert using @a, @b;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(1)) - } - tk.MustExec(`set @a=3,@b=3; execute stmt_insert using @a, @b;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(2)) - } - - result := tk.MustQuery("select id, c1 from prepare_test where id = ?", 1) - result.Check(testkit.Rows("1 1")) - result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 2) - result.Check(testkit.Rows("2 2")) - result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 3) - result.Check(testkit.Rows("3 3")) - - tk.MustExec(`prepare stmt_insert_select from 'insert into prepare_test (id, c1) select id + 100, c1 + 100 from prepare_test where id = ?'`) - tk.MustExec(`set @a=1; execute stmt_insert_select using @a;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(2)) - } - tk.MustExec(`set @a=2; execute stmt_insert_select using @a;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(3)) - } - tk.MustExec(`set @a=3; execute stmt_insert_select using @a;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(4)) - } - - result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 101) - result.Check(testkit.Rows("101 101")) - result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 102) - result.Check(testkit.Rows("102 102")) - result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 103) - result.Check(testkit.Rows("103 103")) - } -} - -func (s *testSuite) TestPreparedUpdate(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - metrics.PlanCacheCounter.Reset() - counter := metrics.PlanCacheCounter.WithLabelValues("prepare") - pb := &dto.Metric{} - flags := []bool{false, true} - for _, flag := range flags { - plannercore.SetPreparedPlanCache(flag) - plannercore.PreparedPlanCacheCapacity = 100 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists prepare_test") - tk.MustExec("create table prepare_test (id int PRIMARY KEY, c1 int)") - tk.MustExec(`insert into prepare_test values (1, 1)`) - tk.MustExec(`insert into prepare_test values (2, 2)`) - tk.MustExec(`insert into prepare_test values (3, 3)`) - - tk.MustExec(`prepare stmt_update from 'update prepare_test set c1 = c1 + ? where id = ?'`) - tk.MustExec(`set @a=1,@b=100; execute stmt_update using @b,@a;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(0)) - } - tk.MustExec(`set @a=2,@b=200; execute stmt_update using @b,@a;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(1)) - } - tk.MustExec(`set @a=3,@b=300; execute stmt_update using @b,@a;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(2)) - } - - result := tk.MustQuery("select id, c1 from prepare_test where id = ?", 1) - result.Check(testkit.Rows("1 101")) - result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 2) - result.Check(testkit.Rows("2 202")) - result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 3) - result.Check(testkit.Rows("3 303")) - } -} - -func (s *testSuite) TestPreparedDelete(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - metrics.PlanCacheCounter.Reset() - counter := metrics.PlanCacheCounter.WithLabelValues("prepare") - pb := &dto.Metric{} - flags := []bool{false, true} - for _, flag := range flags { - plannercore.SetPreparedPlanCache(flag) - plannercore.PreparedPlanCacheCapacity = 100 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists prepare_test") - tk.MustExec("create table prepare_test (id int PRIMARY KEY, c1 int)") - tk.MustExec(`insert into prepare_test values (1, 1)`) - tk.MustExec(`insert into prepare_test values (2, 2)`) - tk.MustExec(`insert into prepare_test values (3, 3)`) - - tk.MustExec(`prepare stmt_delete from 'delete from prepare_test where id = ?'`) - tk.MustExec(`set @a=1; execute stmt_delete using @a;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(0)) - } - tk.MustExec(`set @a=2; execute stmt_delete using @a;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(1)) - } - tk.MustExec(`set @a=3; execute stmt_delete using @a;`) - if flag { - counter.Write(pb) - hit := pb.GetCounter().GetValue() - c.Check(hit, Equals, float64(2)) - } - - result := tk.MustQuery("select id, c1 from prepare_test where id = ?", 1) - result.Check(nil) - result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 2) - result.Check(nil) - result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 3) - result.Check(nil) - } -} - -func (s *testSuite) TestPrepareDealloc(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - plannercore.SetPreparedPlanCache(true) - plannercore.PreparedPlanCacheCapacity = 3 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists prepare_test") - tk.MustExec("create table prepare_test (id int PRIMARY KEY, c1 int)") - - c.Assert(tk.Se.PreparedPlanCache().Size(), Equals, 0) - tk.MustExec(`prepare stmt1 from 'select * from prepare_test'`) - tk.MustExec("execute stmt1") - tk.MustExec(`prepare stmt2 from 'select * from prepare_test'`) - tk.MustExec("execute stmt2") - tk.MustExec(`prepare stmt3 from 'select * from prepare_test'`) - tk.MustExec("execute stmt3") - tk.MustExec(`prepare stmt4 from 'select * from prepare_test'`) - tk.MustExec("execute stmt4") - c.Assert(tk.Se.PreparedPlanCache().Size(), Equals, 3) - - tk.MustExec("deallocate prepare stmt1") - c.Assert(tk.Se.PreparedPlanCache().Size(), Equals, 3) - tk.MustExec("deallocate prepare stmt2") - tk.MustExec("deallocate prepare stmt3") - tk.MustExec("deallocate prepare stmt4") - c.Assert(tk.Se.PreparedPlanCache().Size(), Equals, 0) -} - -func (s *testSuite) TestPreparedIssue8153(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - flags := []bool{false, true} - for _, flag := range flags { - var err error - plannercore.SetPreparedPlanCache(flag) - plannercore.PreparedPlanCacheCapacity = 100 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t (a int, b int)") - tk.MustExec("insert into t (a, b) values (1,3), (2,2), (3,1)") - - tk.MustExec(`prepare stmt from 'select * from t order by ? asc'`) - r := tk.MustQuery(`execute stmt using @param;`) - r.Check(testkit.Rows("1 3", "2 2", "3 1")) - - tk.MustExec(`set @param = 1`) - r = tk.MustQuery(`execute stmt using @param;`) - r.Check(testkit.Rows("1 3", "2 2", "3 1")) - - tk.MustExec(`set @param = 2`) - r = tk.MustQuery(`execute stmt using @param;`) - r.Check(testkit.Rows("3 1", "2 2", "1 3")) - - tk.MustExec(`set @param = 3`) - _, err = tk.Exec(`execute stmt using @param;`) - c.Assert(err.Error(), Equals, "[planner:1054]Unknown column '?' in 'order clause'") - - tk.MustExec(`set @param = '##'`) - r = tk.MustQuery(`execute stmt using @param;`) - r.Check(testkit.Rows("1 3", "2 2", "3 1")) - - tk.MustExec("insert into t (a, b) values (1,1), (1,2), (2,1), (2,3), (3,2), (3,3)") - tk.MustExec(`prepare stmt from 'select ?, sum(a) from t group by ?'`) - - tk.MustExec(`set @a=1,@b=1`) - r = tk.MustQuery(`execute stmt using @a,@b;`) - r.Check(testkit.Rows("1 18")) - - tk.MustExec(`set @a=1,@b=2`) - _, err = tk.Exec(`execute stmt using @a,@b;`) - c.Assert(err.Error(), Equals, "[planner:1056]Can't group on 'sum(a)'") - } -} - -func (s *testSuite) TestPreparedIssue8644(c *C) { - orgEnable := plannercore.PreparedPlanCacheEnabled() - orgCapacity := plannercore.PreparedPlanCacheCapacity - orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio - orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory - defer func() { - plannercore.SetPreparedPlanCache(orgEnable) - plannercore.PreparedPlanCacheCapacity = orgCapacity - plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio - plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory - }() - flags := []bool{false, true} - for _, flag := range flags { - plannercore.SetPreparedPlanCache(flag) - plannercore.PreparedPlanCacheCapacity = 100 - plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 - // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache - // behavior would not be effected by the uncertain memory utilization. - plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t(data mediumblob)") - - tk.MustExec(`prepare stmt1 from 'insert t (data) values (?)'`) - - tk.MustExec(`set @a = 'a'`) - tk.MustExec(`execute stmt1 using @a;`) - - tk.MustExec(`set @b = 'aaaaaaaaaaaaaaaaaa'`) - tk.MustExec(`execute stmt1 using @b;`) - - r := tk.MustQuery(`select * from t`) - r.Check(testkit.Rows("a", "aaaaaaaaaaaaaaaaaa")) - } -} diff --git a/executor/revoke_test.go b/executor/revoke_test.go index de194356b0a95..f3a00c0a3e947 100644 --- a/executor/revoke_test.go +++ b/executor/revoke_test.go @@ -22,7 +22,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestRevokeGlobal(c *C) { +func (s *testSuite1) TestRevokeGlobal(c *C) { tk := testkit.NewTestKit(c, s.store) _, err := tk.Exec(`REVOKE ALL PRIVILEGES ON *.* FROM 'nonexistuser'@'host'`) @@ -50,7 +50,7 @@ func (s *testSuite) TestRevokeGlobal(c *C) { } } -func (s *testSuite) TestRevokeDBScope(c *C) { +func (s *testSuite1) TestRevokeDBScope(c *C) { tk := testkit.NewTestKit(c, s.store) // Create a new user. tk.MustExec(`CREATE USER 'testDBRevoke'@'localhost' IDENTIFIED BY '123';`) @@ -70,7 +70,7 @@ func (s *testSuite) TestRevokeDBScope(c *C) { } } -func (s *testSuite) TestRevokeTableScope(c *C) { +func (s *testSuite1) TestRevokeTableScope(c *C) { tk := testkit.NewTestKit(c, s.store) // Create a new user. tk.MustExec(`CREATE USER 'testTblRevoke'@'localhost' IDENTIFIED BY '123';`) @@ -101,7 +101,7 @@ func (s *testSuite) TestRevokeTableScope(c *C) { tk.MustQuery(`SELECT Table_priv FROM mysql.Tables_priv WHERE User="testTblRevoke" and host="localhost" and db="test" and Table_name="test1"`).Check(testkit.Rows("")) } -func (s *testSuite) TestRevokeColumnScope(c *C) { +func (s *testSuite1) TestRevokeColumnScope(c *C) { tk := testkit.NewTestKit(c, s.store) // Create a new user. tk.MustExec(`CREATE USER 'testColRevoke'@'localhost' IDENTIFIED BY '123';`) diff --git a/executor/rowid_test.go b/executor/rowid_test.go index 0e7d8a3d101d8..db97a5acd93d0 100644 --- a/executor/rowid_test.go +++ b/executor/rowid_test.go @@ -18,7 +18,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestExportRowID(c *C) { +func (s *testSuite1) TestExportRowID(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) tk.Se.GetSessionVars().AllowWriteRowID = true defer func() { @@ -47,7 +47,7 @@ func (s *testSuite) TestExportRowID(c *C) { 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") + err = tk.ExecToErr("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) @@ -61,7 +61,7 @@ func (s *testSuite) TestExportRowID(c *C) { c.Assert(err.Error(), Equals, "insert, update and replace statements for _tidb_rowid are not supported.") } -func (s *testSuite) TestNotAllowWriteRowID(c *C) { +func (s *testSuite1) 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));") diff --git a/executor/seqtest/prepared_test.go b/executor/seqtest/prepared_test.go new file mode 100644 index 0000000000000..068260619093e --- /dev/null +++ b/executor/seqtest/prepared_test.go @@ -0,0 +1,748 @@ +// Copyright 2016 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package executor_test + +import ( + "context" + "math" + + . "github.com/pingcap/check" + "github.com/pingcap/errors" + "github.com/pingcap/parser/terror" + "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/metrics" + plannercore "github.com/pingcap/tidb/planner/core" + "github.com/pingcap/tidb/util/testkit" + dto "github.com/prometheus/client_model/go" +) + +func (s *seqTestSuite) TestPrepared(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + flags := []bool{false, true} + ctx := context.Background() + for _, flag := range flags { + var err error + plannercore.SetPreparedPlanCache(flag) + plannercore.PreparedPlanCacheCapacity = 100 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists prepare_test") + tk.MustExec("create table prepare_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1)") + tk.MustExec("insert prepare_test (c1) values (1),(2),(NULL)") + + tk.MustExec(`prepare stmt_test_1 from 'select id from prepare_test where id > ?'; set @a = 1; execute stmt_test_1 using @a;`) + tk.MustExec(`prepare stmt_test_2 from 'select 1'`) + // Prepare multiple statement is not allowed. + _, err = tk.Exec(`prepare stmt_test_3 from 'select id from prepare_test where id > ?;select id from prepare_test where id > ?;'`) + c.Assert(executor.ErrPrepareMulti.Equal(err), IsTrue) + // The variable count does not match. + _, err = tk.Exec(`prepare stmt_test_4 from 'select id from prepare_test where id > ? and id < ?'; set @a = 1; execute stmt_test_4 using @a;`) + c.Assert(plannercore.ErrWrongParamCount.Equal(err), IsTrue) + // Prepare and deallocate prepared statement immediately. + tk.MustExec(`prepare stmt_test_5 from 'select id from prepare_test where id > ?'; deallocate prepare stmt_test_5;`) + + // Statement not found. + _, err = tk.Exec("deallocate prepare stmt_test_5") + c.Assert(plannercore.ErrStmtNotFound.Equal(err), IsTrue) + + // incorrect SQLs in prepare. issue #3738, SQL in prepare stmt is parsed in DoPrepare. + _, err = tk.Exec(`prepare p from "delete from t where a = 7 or 1=1/*' and b = 'p'";`) + c.Assert(terror.ErrorEqual(err, errors.New(`[parser:1064]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*' and b = 'p'' at line 1`)), IsTrue, Commentf("err %v", err)) + + // The `stmt_test5` should not be found. + _, err = tk.Exec(`set @a = 1; execute stmt_test_5 using @a;`) + c.Assert(plannercore.ErrStmtNotFound.Equal(err), IsTrue) + + // Use parameter marker with argument will run prepared statement. + result := tk.MustQuery("select distinct c1, c2 from prepare_test where c1 = ?", 1) + result.Check(testkit.Rows("1 ")) + + // Call Session PrepareStmt directly to get stmtID. + query := "select c1, c2 from prepare_test where c1 = ?" + stmtID, _, _, err := tk.Se.PrepareStmt(query) + c.Assert(err, IsNil) + rs, err := tk.Se.ExecutePreparedStmt(ctx, stmtID, 1) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows("1 ")) + + 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) + c.Assert(err, IsNil) + tk1 := testkit.NewTestKitWithInit(c, s.store) + 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 = (select c1 from prepare_test where c1 = ?)" + stmtID, _, _, err = tk.Se.PrepareStmt(query) + c.Assert(err, IsNil) + _, 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) + c.Assert(err, IsNil) + _, 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 = ?" + stmtID, _, _, err = tk.Se.PrepareStmt(query) + c.Assert(err, IsNil) + tk.MustExec("rollback") + rs, err = tk.Se.ExecutePreparedStmt(ctx, stmtID, 4) + c.Assert(err, IsNil) + tk.ResultSetToResult(rs, Commentf("%v", rs)).Check(testkit.Rows()) + + // Check that ast.Statement created by executor.CompileExecutePreparedStmt has query text. + stmt, err := executor.CompileExecutePreparedStmt(tk.Se, stmtID, 1) + c.Assert(err, IsNil) + c.Assert(stmt.OriginText(), Equals, query) + + // Check that rebuild plan works. + tk.Se.PrepareTxnCtx(ctx) + _, err = stmt.RebuildPlan() + c.Assert(err, IsNil) + rs, err = stmt.Exec(ctx) + c.Assert(err, IsNil) + chk := rs.NewChunk() + err = rs.Next(ctx, chk) + c.Assert(err, IsNil) + c.Assert(rs.Close(), IsNil) + + // Make schema change. + tk.MustExec("drop table if exists prepare2") + tk.Exec("create table prepare2 (a int)") + + // Should success as the changed schema do not affect the prepared statement. + _, err = tk.Se.ExecutePreparedStmt(ctx, stmtID, 1) + c.Assert(err, IsNil) + + // Drop a column so the prepared statement become invalid. + query = "select c1, c2 from prepare_test where c1 = ?" + stmtID, _, _, err = tk.Se.PrepareStmt(query) + c.Assert(err, IsNil) + tk.MustExec("alter table prepare_test drop column c2") + + _, err = tk.Se.ExecutePreparedStmt(ctx, stmtID, 1) + c.Assert(plannercore.ErrUnknownColumn.Equal(err), IsTrue) + + tk.MustExec("drop table prepare_test") + _, err = tk.Se.ExecutePreparedStmt(ctx, stmtID, 1) + c.Assert(plannercore.ErrSchemaChanged.Equal(err), IsTrue) + + // issue 3381 + tk.MustExec("drop table if exists prepare3") + tk.MustExec("create table prepare3 (a decimal(1))") + tk.MustExec("prepare stmt from 'insert into prepare3 value(123)'") + _, err = tk.Exec("execute stmt") + c.Assert(err, NotNil) + + _, _, fields, err := tk.Se.PrepareStmt("select a from prepare3") + c.Assert(err, IsNil) + c.Assert(fields[0].DBName.L, Equals, "test") + c.Assert(fields[0].TableAsName.L, Equals, "prepare3") + c.Assert(fields[0].ColumnAsName.L, Equals, "a") + + _, _, fields, err = tk.Se.PrepareStmt("select a from prepare3 where ?") + c.Assert(err, IsNil) + c.Assert(fields[0].DBName.L, Equals, "test") + c.Assert(fields[0].TableAsName.L, Equals, "prepare3") + c.Assert(fields[0].ColumnAsName.L, Equals, "a") + + _, _, fields, err = tk.Se.PrepareStmt("select (1,1) in (select 1,1)") + c.Assert(err, IsNil) + c.Assert(fields[0].DBName.L, Equals, "") + c.Assert(fields[0].TableAsName.L, Equals, "") + c.Assert(fields[0].ColumnAsName.L, Equals, "(1,1) in (select 1,1)") + + _, _, fields, err = tk.Se.PrepareStmt("select a from prepare3 where a = (" + + "select a from prepare2 where a = ?)") + c.Assert(err, IsNil) + c.Assert(fields[0].DBName.L, Equals, "test") + c.Assert(fields[0].TableAsName.L, Equals, "prepare3") + c.Assert(fields[0].ColumnAsName.L, Equals, "a") + + _, _, fields, err = tk.Se.PrepareStmt("select * from prepare3 as t1 join prepare3 as t2") + c.Assert(err, IsNil) + c.Assert(fields[0].DBName.L, Equals, "test") + c.Assert(fields[0].TableAsName.L, Equals, "t1") + c.Assert(fields[0].ColumnAsName.L, Equals, "a") + c.Assert(fields[1].DBName.L, Equals, "test") + c.Assert(fields[1].TableAsName.L, Equals, "t2") + c.Assert(fields[1].ColumnAsName.L, Equals, "a") + + _, _, fields, err = tk.Se.PrepareStmt("update prepare3 set a = ?") + c.Assert(err, IsNil) + c.Assert(len(fields), Equals, 0) + + // issue 8074 + tk.MustExec("drop table if exists prepare1;") + tk.MustExec("create table prepare1 (a decimal(1))") + tk.MustExec("insert into prepare1 values(1);") + _, err = tk.Exec("prepare stmt FROM @sql1") + c.Assert(err.Error(), Equals, "line 1 column 4 near \"\" (total length 4)") + tk.MustExec("SET @sql = 'update prepare1 set a=5 where a=?';") + _, err = tk.Exec("prepare stmt FROM @sql") + c.Assert(err, IsNil) + tk.MustExec("set @var=1;") + _, err = tk.Exec("execute stmt using @var") + c.Assert(err, IsNil) + tk.MustQuery("select a from prepare1;").Check(testkit.Rows("5")) + + // Coverage. + exec := &executor.ExecuteExec{} + exec.Next(ctx, nil) + exec.Close() + } +} + +func (s *seqTestSuite) TestPreparedLimitOffset(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + flags := []bool{false, true} + ctx := context.Background() + for _, flag := range flags { + var err error + plannercore.SetPreparedPlanCache(flag) + plannercore.PreparedPlanCacheCapacity = 100 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists prepare_test") + tk.MustExec("create table prepare_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1)") + tk.MustExec("insert prepare_test (c1) values (1),(2),(NULL)") + tk.MustExec(`prepare stmt_test_1 from 'select id from prepare_test limit ? offset ?'; set @a = 1, @b=1;`) + r := tk.MustQuery(`execute stmt_test_1 using @a, @b;`) + r.Check(testkit.Rows("2")) + + tk.MustExec(`set @a=1.1`) + r = tk.MustQuery(`execute stmt_test_1 using @a, @b;`) + r.Check(testkit.Rows("2")) + + tk.MustExec(`set @c="-1"`) + _, err = tk.Exec("execute stmt_test_1 using @c, @c") + c.Assert(plannercore.ErrWrongArguments.Equal(err), IsTrue) + + stmtID, _, _, err := tk.Se.PrepareStmt("select id from prepare_test limit ?") + c.Assert(err, IsNil) + _, err = tk.Se.ExecutePreparedStmt(ctx, stmtID, 1) + c.Assert(err, IsNil) + } +} + +func (s *seqTestSuite) TestPreparedNullParam(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + flags := []bool{false, true} + for _, flag := range flags { + plannercore.SetPreparedPlanCache(flag) + plannercore.PreparedPlanCacheCapacity = 100 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (id int, KEY id (id))") + tk.MustExec("insert into t values (1), (2), (3)") + tk.MustExec(`prepare stmt from 'select * from t use index(id) where id = ?'`) + + r := tk.MustQuery(`execute stmt using @id;`) + r.Check(nil) + + r = tk.MustQuery(`execute stmt using @id;`) + r.Check(nil) + + tk.MustExec(`set @id="1"`) + r = tk.MustQuery(`execute stmt using @id;`) + r.Check(testkit.Rows("1")) + + r = tk.MustQuery(`execute stmt using @id2;`) + r.Check(nil) + + r = tk.MustQuery(`execute stmt using @id;`) + r.Check(testkit.Rows("1")) + } +} + +func (s *seqTestSuite) TestPrepareWithAggregation(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + flags := []bool{false, true} + for _, flag := range flags { + plannercore.SetPreparedPlanCache(flag) + plannercore.PreparedPlanCacheCapacity = 100 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (id int primary key)") + tk.MustExec("insert into t values (1), (2), (3)") + tk.MustExec(`prepare stmt from 'select sum(id) from t where id = ?'`) + + tk.MustExec(`set @id="1"`) + r := tk.MustQuery(`execute stmt using @id;`) + r.Check(testkit.Rows("1")) + + r = tk.MustQuery(`execute stmt using @id;`) + r.Check(testkit.Rows("1")) + } +} + +func (s *seqTestSuite) TestPreparedIssue7579(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + flags := []bool{false, true} + for _, flag := range flags { + plannercore.SetPreparedPlanCache(flag) + plannercore.PreparedPlanCacheCapacity = 100 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (a int, b int, index a_idx(a))") + tk.MustExec("insert into t values (1,1), (2,2), (null,3)") + + r := tk.MustQuery("select a, b from t order by b asc;") + r.Check(testkit.Rows("1 1", "2 2", " 3")) + + tk.MustExec(`prepare stmt from 'select a, b from t where ? order by b asc'`) + + r = tk.MustQuery(`execute stmt using @param;`) + r.Check(nil) + + tk.MustExec(`set @param = true`) + r = tk.MustQuery(`execute stmt using @param;`) + r.Check(testkit.Rows("1 1", "2 2", " 3")) + + tk.MustExec(`set @param = false`) + r = tk.MustQuery(`execute stmt using @param;`) + r.Check(nil) + + tk.MustExec(`set @param = 1`) + r = tk.MustQuery(`execute stmt using @param;`) + r.Check(testkit.Rows("1 1", "2 2", " 3")) + + tk.MustExec(`set @param = 0`) + r = tk.MustQuery(`execute stmt using @param;`) + r.Check(nil) + } +} + +func (s *seqTestSuite) TestPreparedInsert(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + metrics.PlanCacheCounter.Reset() + counter := metrics.PlanCacheCounter.WithLabelValues("prepare") + pb := &dto.Metric{} + flags := []bool{false, true} + for _, flag := range flags { + plannercore.SetPreparedPlanCache(flag) + plannercore.PreparedPlanCacheCapacity = 100 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists prepare_test") + tk.MustExec("create table prepare_test (id int PRIMARY KEY, c1 int)") + tk.MustExec(`prepare stmt_insert from 'insert into prepare_test values (?, ?)'`) + tk.MustExec(`set @a=1,@b=1; execute stmt_insert using @a, @b;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(0)) + } + tk.MustExec(`set @a=2,@b=2; execute stmt_insert using @a, @b;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(1)) + } + tk.MustExec(`set @a=3,@b=3; execute stmt_insert using @a, @b;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(2)) + } + + result := tk.MustQuery("select id, c1 from prepare_test where id = ?", 1) + result.Check(testkit.Rows("1 1")) + result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 2) + result.Check(testkit.Rows("2 2")) + result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 3) + result.Check(testkit.Rows("3 3")) + + tk.MustExec(`prepare stmt_insert_select from 'insert into prepare_test (id, c1) select id + 100, c1 + 100 from prepare_test where id = ?'`) + tk.MustExec(`set @a=1; execute stmt_insert_select using @a;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(2)) + } + tk.MustExec(`set @a=2; execute stmt_insert_select using @a;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(3)) + } + tk.MustExec(`set @a=3; execute stmt_insert_select using @a;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(4)) + } + + result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 101) + result.Check(testkit.Rows("101 101")) + result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 102) + result.Check(testkit.Rows("102 102")) + result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 103) + result.Check(testkit.Rows("103 103")) + } +} + +func (s *seqTestSuite) TestPreparedUpdate(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + metrics.PlanCacheCounter.Reset() + counter := metrics.PlanCacheCounter.WithLabelValues("prepare") + pb := &dto.Metric{} + flags := []bool{false, true} + for _, flag := range flags { + plannercore.SetPreparedPlanCache(flag) + plannercore.PreparedPlanCacheCapacity = 100 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists prepare_test") + tk.MustExec("create table prepare_test (id int PRIMARY KEY, c1 int)") + tk.MustExec(`insert into prepare_test values (1, 1)`) + tk.MustExec(`insert into prepare_test values (2, 2)`) + tk.MustExec(`insert into prepare_test values (3, 3)`) + + tk.MustExec(`prepare stmt_update from 'update prepare_test set c1 = c1 + ? where id = ?'`) + tk.MustExec(`set @a=1,@b=100; execute stmt_update using @b,@a;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(0)) + } + tk.MustExec(`set @a=2,@b=200; execute stmt_update using @b,@a;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(1)) + } + tk.MustExec(`set @a=3,@b=300; execute stmt_update using @b,@a;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(2)) + } + + result := tk.MustQuery("select id, c1 from prepare_test where id = ?", 1) + result.Check(testkit.Rows("1 101")) + result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 2) + result.Check(testkit.Rows("2 202")) + result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 3) + result.Check(testkit.Rows("3 303")) + } +} + +func (s *seqTestSuite) TestPreparedDelete(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + metrics.PlanCacheCounter.Reset() + counter := metrics.PlanCacheCounter.WithLabelValues("prepare") + pb := &dto.Metric{} + flags := []bool{false, true} + for _, flag := range flags { + plannercore.SetPreparedPlanCache(flag) + plannercore.PreparedPlanCacheCapacity = 100 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists prepare_test") + tk.MustExec("create table prepare_test (id int PRIMARY KEY, c1 int)") + tk.MustExec(`insert into prepare_test values (1, 1)`) + tk.MustExec(`insert into prepare_test values (2, 2)`) + tk.MustExec(`insert into prepare_test values (3, 3)`) + + tk.MustExec(`prepare stmt_delete from 'delete from prepare_test where id = ?'`) + tk.MustExec(`set @a=1; execute stmt_delete using @a;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(0)) + } + tk.MustExec(`set @a=2; execute stmt_delete using @a;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(1)) + } + tk.MustExec(`set @a=3; execute stmt_delete using @a;`) + if flag { + counter.Write(pb) + hit := pb.GetCounter().GetValue() + c.Check(hit, Equals, float64(2)) + } + + result := tk.MustQuery("select id, c1 from prepare_test where id = ?", 1) + result.Check(nil) + result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 2) + result.Check(nil) + result = tk.MustQuery("select id, c1 from prepare_test where id = ?", 3) + result.Check(nil) + } +} + +func (s *seqTestSuite) TestPrepareDealloc(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + plannercore.SetPreparedPlanCache(true) + plannercore.PreparedPlanCacheCapacity = 3 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists prepare_test") + tk.MustExec("create table prepare_test (id int PRIMARY KEY, c1 int)") + + c.Assert(tk.Se.PreparedPlanCache().Size(), Equals, 0) + tk.MustExec(`prepare stmt1 from 'select * from prepare_test'`) + tk.MustExec("execute stmt1") + tk.MustExec(`prepare stmt2 from 'select * from prepare_test'`) + tk.MustExec("execute stmt2") + tk.MustExec(`prepare stmt3 from 'select * from prepare_test'`) + tk.MustExec("execute stmt3") + tk.MustExec(`prepare stmt4 from 'select * from prepare_test'`) + tk.MustExec("execute stmt4") + c.Assert(tk.Se.PreparedPlanCache().Size(), Equals, 3) + + tk.MustExec("deallocate prepare stmt1") + c.Assert(tk.Se.PreparedPlanCache().Size(), Equals, 3) + tk.MustExec("deallocate prepare stmt2") + tk.MustExec("deallocate prepare stmt3") + tk.MustExec("deallocate prepare stmt4") + c.Assert(tk.Se.PreparedPlanCache().Size(), Equals, 0) +} + +func (s *seqTestSuite) TestPreparedIssue8153(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + flags := []bool{false, true} + for _, flag := range flags { + var err error + plannercore.SetPreparedPlanCache(flag) + plannercore.PreparedPlanCacheCapacity = 100 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (a int, b int)") + tk.MustExec("insert into t (a, b) values (1,3), (2,2), (3,1)") + + tk.MustExec(`prepare stmt from 'select * from t order by ? asc'`) + r := tk.MustQuery(`execute stmt using @param;`) + r.Check(testkit.Rows("1 3", "2 2", "3 1")) + + tk.MustExec(`set @param = 1`) + r = tk.MustQuery(`execute stmt using @param;`) + r.Check(testkit.Rows("1 3", "2 2", "3 1")) + + tk.MustExec(`set @param = 2`) + r = tk.MustQuery(`execute stmt using @param;`) + r.Check(testkit.Rows("3 1", "2 2", "1 3")) + + tk.MustExec(`set @param = 3`) + _, err = tk.Exec(`execute stmt using @param;`) + c.Assert(err.Error(), Equals, "[planner:1054]Unknown column '?' in 'order clause'") + + tk.MustExec(`set @param = '##'`) + r = tk.MustQuery(`execute stmt using @param;`) + r.Check(testkit.Rows("1 3", "2 2", "3 1")) + + tk.MustExec("insert into t (a, b) values (1,1), (1,2), (2,1), (2,3), (3,2), (3,3)") + tk.MustExec(`prepare stmt from 'select ?, sum(a) from t group by ?'`) + + tk.MustExec(`set @a=1,@b=1`) + r = tk.MustQuery(`execute stmt using @a,@b;`) + r.Check(testkit.Rows("1 18")) + + tk.MustExec(`set @a=1,@b=2`) + _, err = tk.Exec(`execute stmt using @a,@b;`) + c.Assert(err.Error(), Equals, "[planner:1056]Can't group on 'sum(a)'") + } +} + +func (s *seqTestSuite) TestPreparedIssue8644(c *C) { + orgEnable := plannercore.PreparedPlanCacheEnabled() + orgCapacity := plannercore.PreparedPlanCacheCapacity + orgMemGuardRatio := plannercore.PreparedPlanCacheMemoryGuardRatio + orgMaxMemory := plannercore.PreparedPlanCacheMaxMemory + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + plannercore.PreparedPlanCacheCapacity = orgCapacity + plannercore.PreparedPlanCacheMemoryGuardRatio = orgMemGuardRatio + plannercore.PreparedPlanCacheMaxMemory = orgMaxMemory + }() + flags := []bool{false, true} + for _, flag := range flags { + plannercore.SetPreparedPlanCache(flag) + plannercore.PreparedPlanCacheCapacity = 100 + plannercore.PreparedPlanCacheMemoryGuardRatio = 0.1 + // PreparedPlanCacheMaxMemory is set to MAX_UINT64 to make sure the cache + // behavior would not be effected by the uncertain memory utilization. + plannercore.PreparedPlanCacheMaxMemory = math.MaxUint64 + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(data mediumblob)") + + tk.MustExec(`prepare stmt1 from 'insert t (data) values (?)'`) + + tk.MustExec(`set @a = 'a'`) + tk.MustExec(`execute stmt1 using @a;`) + + tk.MustExec(`set @b = 'aaaaaaaaaaaaaaaaaa'`) + tk.MustExec(`execute stmt1 using @b;`) + + r := tk.MustQuery(`select * from t`) + r.Check(testkit.Rows("a", "aaaaaaaaaaaaaaaaaa")) + } +} diff --git a/executor/seqtest/seq_executor_test.go b/executor/seqtest/seq_executor_test.go new file mode 100644 index 0000000000000..caf7302ff9580 --- /dev/null +++ b/executor/seqtest/seq_executor_test.go @@ -0,0 +1,718 @@ +// Copyright 2015 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package executor_test + +import ( + "bytes" + "context" + "flag" + "fmt" + "math" + "os" + "runtime/pprof" + "strconv" + "strings" + "sync/atomic" + "testing" + "time" + + . "github.com/pingcap/check" + gofail "github.com/pingcap/gofail/runtime" + "github.com/pingcap/parser" + "github.com/pingcap/parser/model" + "github.com/pingcap/tidb/domain" + "github.com/pingcap/tidb/executor" + "github.com/pingcap/tidb/kv" + "github.com/pingcap/tidb/meta/autoid" + "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/sessionctx/variable" + "github.com/pingcap/tidb/statistics" + "github.com/pingcap/tidb/store/mockstore" + "github.com/pingcap/tidb/store/mockstore/mocktikv" + "github.com/pingcap/tidb/store/tikv" + "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/mock" + "github.com/pingcap/tidb/util/testkit" + "github.com/pingcap/tidb/util/testleak" + "github.com/pingcap/tidb/util/testutil" +) + +func TestT(t *testing.T) { + CustomVerboseFlag = true + logLevel := os.Getenv("log_level") + logutil.InitLogger(&logutil.LogConfig{ + Level: logLevel, + }) + TestingT(t) +} + +var _ = Suite(&seqTestSuite{}) + +type seqTestSuite struct { + cluster *mocktikv.Cluster + mvccStore mocktikv.MVCCStore + store kv.Storage + domain *domain.Domain + *parser.Parser + ctx *mock.Context +} + +var mockTikv = flag.Bool("mockTikv", true, "use mock tikv store in executor test") + +func (s *seqTestSuite) SetUpSuite(c *C) { + testleak.BeforeTest() + s.Parser = parser.New() + flag.Lookup("mockTikv") + useMockTikv := *mockTikv + if useMockTikv { + s.cluster = mocktikv.NewCluster() + mocktikv.BootstrapWithSingleStore(s.cluster) + s.mvccStore = mocktikv.MustNewMVCCStore() + store, err := mockstore.NewMockTikvStore( + mockstore.WithCluster(s.cluster), + mockstore.WithMVCCStore(s.mvccStore), + ) + c.Assert(err, IsNil) + s.store = store + session.SetSchemaLease(0) + session.SetStatsLease(0) + } + d, err := session.BootstrapSession(s.store) + c.Assert(err, IsNil) + d.SetStatsUpdating(true) + s.domain = d +} + +func (s *seqTestSuite) TearDownSuite(c *C) { + s.domain.Close() + s.store.Close() + testleak.AfterTest(c)() +} + +func (s *seqTestSuite) TestEarlyClose(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("create table earlyclose (id int primary key)") + + // Insert 1000 rows. + var values []string + for i := 0; i < 1000; i++ { + values = append(values, fmt.Sprintf("(%d)", i)) + } + tk.MustExec("insert earlyclose values " + strings.Join(values, ",")) + + // Get table ID for split. + dom := domain.GetDomain(tk.Se) + is := dom.InfoSchema() + tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("earlyclose")) + c.Assert(err, IsNil) + tblID := tbl.Meta().ID + + // Split the table. + s.cluster.SplitTable(s.mvccStore, tblID, 500) + + ctx := context.Background() + for i := 0; i < 500; i++ { + rss, err1 := tk.Se.Execute(ctx, "select * from earlyclose order by id") + c.Assert(err1, IsNil) + rs := rss[0] + chk := rs.NewChunk() + err = rs.Next(ctx, chk) + c.Assert(err, IsNil) + rs.Close() + } + + // Goroutine should not leak when error happen. + gofail.Enable("github.com/pingcap/tidb/store/tikv/handleTaskOnceError", `return(true)`) + defer gofail.Disable("github.com/pingcap/tidb/store/tikv/handleTaskOnceError") + rss, err := tk.Se.Execute(ctx, "select * from earlyclose") + c.Assert(err, IsNil) + rs := rss[0] + chk := rs.NewChunk() + err = rs.Next(ctx, chk) + c.Assert(err, NotNil) + rs.Close() +} + +type stats struct { +} + +func (s stats) GetScope(status string) variable.ScopeFlag { return variable.DefaultStatusVarScopeFlag } + +func (s stats) Stats(vars *variable.SessionVars) (map[string]interface{}, error) { + m := make(map[string]interface{}) + var a, b interface{} + b = "123" + m["test_interface_nil"] = a + m["test_interface"] = b + m["test_interface_slice"] = []interface{}{"a", "b", "c"} + return m, nil +} + +func (s *seqTestSuite) TestShow(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + + testSQL := `drop table if exists show_test` + tk.MustExec(testSQL) + testSQL = `create table SHOW_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int comment "c1_comment", c2 int, c3 int default 1, c4 text, c5 boolean, key idx_wide_c4(c3, c4(10))) ENGINE=InnoDB AUTO_INCREMENT=28934 DEFAULT CHARSET=utf8 COMMENT "table_comment";` + tk.MustExec(testSQL) + + testSQL = "show columns from show_test;" + result := tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 6) + + testSQL = "show create table show_test;" + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 1) + row := result.Rows()[0] + // For issue https://github.com/pingcap/tidb/issues/1061 + expectedRow := []interface{}{ + "SHOW_test", "CREATE TABLE `SHOW_test` (\n `id` int(11) NOT NULL AUTO_INCREMENT,\n `c1` int(11) DEFAULT NULL COMMENT 'c1_comment',\n `c2` int(11) DEFAULT NULL,\n `c3` int(11) DEFAULT '1',\n `c4` text DEFAULT NULL,\n `c5` tinyint(1) DEFAULT NULL,\n PRIMARY KEY (`id`),\n KEY `idx_wide_c4` (`c3`,`c4`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=28934 COMMENT='table_comment'"} + for i, r := range row { + c.Check(r, Equals, expectedRow[i]) + } + + // For issue https://github.com/pingcap/tidb/issues/1918 + testSQL = `create table ptest( + a int primary key, + b double NOT NULL DEFAULT 2.0, + c varchar(10) NOT NULL, + d time unique, + e timestamp NULL, + f timestamp + );` + tk.MustExec(testSQL) + testSQL = "show create table ptest;" + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 1) + row = result.Rows()[0] + expectedRow = []interface{}{ + "ptest", "CREATE TABLE `ptest` (\n `a` int(11) NOT NULL,\n `b` double NOT NULL DEFAULT '2.0',\n `c` varchar(10) NOT NULL,\n `d` time DEFAULT NULL,\n `e` timestamp NULL DEFAULT NULL,\n `f` timestamp NULL DEFAULT NULL,\n PRIMARY KEY (`a`),\n UNIQUE KEY `d` (`d`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} + for i, r := range row { + c.Check(r, Equals, expectedRow[i]) + } + + // Issue #4684. + tk.MustExec("drop table if exists `t1`") + testSQL = "create table `t1` (" + + "`c1` tinyint unsigned default null," + + "`c2` smallint unsigned default null," + + "`c3` mediumint unsigned default null," + + "`c4` int unsigned default null," + + "`c5` bigint unsigned default null);`" + + tk.MustExec(testSQL) + testSQL = "show create table t1" + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 1) + row = result.Rows()[0] + expectedRow = []interface{}{ + "t1", "CREATE TABLE `t1` (\n" + + " `c1` tinyint(3) UNSIGNED DEFAULT NULL,\n" + + " `c2` smallint(5) UNSIGNED DEFAULT NULL,\n" + + " `c3` mediumint(8) UNSIGNED DEFAULT NULL,\n" + + " `c4` int(10) UNSIGNED DEFAULT NULL,\n" + + " `c5` bigint(20) UNSIGNED DEFAULT NULL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} + for i, r := range row { + c.Check(r, Equals, expectedRow[i]) + } + + // Issue #7665 + tk.MustExec("drop table if exists `decimalschema`") + testSQL = "create table `decimalschema` (`c1` decimal);" + tk.MustExec(testSQL) + testSQL = "show create table decimalschema" + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 1) + row = result.Rows()[0] + expectedRow = []interface{}{ + "decimalschema", "CREATE TABLE `decimalschema` (\n" + + " `c1` decimal(11,0) DEFAULT NULL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} + for i, r := range row { + c.Check(r, Equals, expectedRow[i]) + } + + tk.MustExec("drop table if exists `decimalschema`") + testSQL = "create table `decimalschema` (`c1` decimal(15));" + tk.MustExec(testSQL) + testSQL = "show create table decimalschema" + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 1) + row = result.Rows()[0] + expectedRow = []interface{}{ + "decimalschema", "CREATE TABLE `decimalschema` (\n" + + " `c1` decimal(15,0) DEFAULT NULL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} + for i, r := range row { + c.Check(r, Equals, expectedRow[i]) + } + + testSQL = "SHOW VARIABLES LIKE 'character_set_results';" + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 1) + + // Test case for index type and comment + tk.MustExec(`create table show_index (id int, c int, primary key (id), index cIdx using hash (c) comment "index_comment_for_cIdx");`) + tk.MustExec(`create index idx1 on show_index (id) using hash;`) + tk.MustExec(`create index idx2 on show_index (id) comment 'idx';`) + tk.MustExec(`create index idx3 on show_index (id) using hash comment 'idx';`) + tk.MustExec(`alter table show_index add index idx4 (id) using btree comment 'idx';`) + tk.MustExec(`create index idx5 using hash on show_index (id) using btree comment 'idx';`) + tk.MustExec(`create index idx6 using hash on show_index (id);`) + tk.MustExec(`create index idx7 on show_index (id);`) + testSQL = "SHOW index from show_index;" + tk.MustQuery(testSQL).Check(testutil.RowsWithSep("|", + "show_index|0|PRIMARY|1|id|A|0||||BTREE||", + "show_index|1|cIdx|1|c|A|0|||YES|HASH||index_comment_for_cIdx", + "show_index|1|idx1|1|id|A|0|||YES|HASH||", + "show_index|1|idx2|1|id|A|0|||YES|BTREE||idx", + "show_index|1|idx3|1|id|A|0|||YES|HASH||idx", + "show_index|1|idx4|1|id|A|0|||YES|BTREE||idx", + "show_index|1|idx5|1|id|A|0|||YES|BTREE||idx", + "show_index|1|idx6|1|id|A|0|||YES|HASH||", + "show_index|1|idx7|1|id|A|0|||YES|BTREE||", + )) + + // For show like with escape + testSQL = `show tables like 'SHOW\_test'` + result = tk.MustQuery(testSQL) + rows := result.Rows() + c.Check(rows, HasLen, 1) + c.Check(rows[0], DeepEquals, []interface{}{"SHOW_test"}) + + var ss stats + variable.RegisterStatistics(ss) + testSQL = "show status like 'character_set_results';" + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), NotNil) + + tk.MustQuery("SHOW PROCEDURE STATUS WHERE Db='test'").Check(testkit.Rows()) + tk.MustQuery("SHOW TRIGGERS WHERE `Trigger` ='test'").Check(testkit.Rows()) + tk.MustQuery("SHOW PROCESSLIST;").Check(testkit.Rows()) + tk.MustQuery("SHOW FULL PROCESSLIST;").Check(testkit.Rows()) + tk.MustQuery("SHOW EVENTS WHERE Db = 'test'").Check(testkit.Rows()) + tk.MustQuery("SHOW PLUGINS").Check(testkit.Rows()) + tk.MustQuery("SHOW PROFILES").Check(testkit.Rows()) + + // +-------------+--------------------+--------------+------------------+-------------------+ + // | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | + // +-------------+--------------------+--------------+------------------+-------------------+ + // | tidb-binlog | 400668057259474944 | | | | + // +-------------+--------------------+--------------+------------------+-------------------+ + result = tk.MustQuery("SHOW MASTER STATUS") + c.Check(result.Rows(), HasLen, 1) + row = result.Rows()[0] + c.Check(row, HasLen, 5) + c.Assert(row[1].(string) != "0", IsTrue) + + tk.MustQuery("SHOW PRIVILEGES") + + // Test show create database + testSQL = `create database show_test_DB` + tk.MustExec(testSQL) + testSQL = "show create database show_test_DB;" + tk.MustQuery(testSQL).Check(testutil.RowsWithSep("|", + "show_test_DB|CREATE DATABASE `show_test_DB` /* !40100 DEFAULT CHARACTER SET utf8mb4 */", + )) + + tk.MustExec("use show_test_DB") + result = tk.MustQuery("SHOW index from show_index from test where Column_name = 'c'") + c.Check(result.Rows(), HasLen, 1) + + // Test show full columns + // for issue https://github.com/pingcap/tidb/issues/4224 + tk.MustExec(`drop table if exists show_test_comment`) + tk.MustExec(`create table show_test_comment (id int not null default 0 comment "show_test_comment_id")`) + tk.MustQuery(`show full columns from show_test_comment`).Check(testutil.RowsWithSep("|", + "id|int(11)|binary|NO||0||select,insert,update,references|show_test_comment_id", + )) + + // Test show create table with AUTO_INCREMENT option + // for issue https://github.com/pingcap/tidb/issues/3747 + tk.MustExec(`drop table if exists show_auto_increment`) + tk.MustExec(`create table show_auto_increment (id int key auto_increment) auto_increment=4`) + tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|", + ""+ + "show_auto_increment CREATE TABLE `show_auto_increment` (\n"+ + " `id` int(11) NOT NULL AUTO_INCREMENT,\n"+ + " PRIMARY KEY (`id`)\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=4", + )) + // for issue https://github.com/pingcap/tidb/issues/4678 + autoIDStep := autoid.GetStep() + tk.MustExec("insert into show_auto_increment values(20)") + autoID := autoIDStep + 21 + tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|", + ""+ + "show_auto_increment CREATE TABLE `show_auto_increment` (\n"+ + " `id` int(11) NOT NULL AUTO_INCREMENT,\n"+ + " PRIMARY KEY (`id`)\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT="+strconv.Itoa(int(autoID)), + )) + tk.MustExec(`drop table show_auto_increment`) + tk.MustExec(`create table show_auto_increment (id int primary key auto_increment)`) + tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|", + ""+ + "show_auto_increment CREATE TABLE `show_auto_increment` (\n"+ + " `id` int(11) NOT NULL AUTO_INCREMENT,\n"+ + " PRIMARY KEY (`id`)\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + )) + tk.MustExec("insert into show_auto_increment values(10)") + autoID = autoIDStep + 11 + tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|", + ""+ + "show_auto_increment CREATE TABLE `show_auto_increment` (\n"+ + " `id` int(11) NOT NULL AUTO_INCREMENT,\n"+ + " PRIMARY KEY (`id`)\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT="+strconv.Itoa(int(autoID)), + )) + + // Test show table with column's comment contain escape character + // for issue https://github.com/pingcap/tidb/issues/4411 + tk.MustExec(`drop table if exists show_escape_character`) + tk.MustExec(`create table show_escape_character(id int comment 'a\rb\nc\td\0ef')`) + tk.MustQuery(`show create table show_escape_character`).Check(testutil.RowsWithSep("|", + ""+ + "show_escape_character CREATE TABLE `show_escape_character` (\n"+ + " `id` int(11) DEFAULT NULL COMMENT 'a\\rb\\nc d\\0ef'\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + )) + + // for issue https://github.com/pingcap/tidb/issues/4424 + tk.MustExec("drop table if exists show_test") + testSQL = `create table show_test( + a varchar(10) COMMENT 'a\nb\rc\td\0e' + ) COMMENT='a\nb\rc\td\0e';` + tk.MustExec(testSQL) + testSQL = "show create table show_test;" + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 1) + row = result.Rows()[0] + expectedRow = []interface{}{ + "show_test", "CREATE TABLE `show_test` (\n `a` varchar(10) DEFAULT NULL COMMENT 'a\\nb\\rc d\\0e'\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='a\\nb\\rc d\\0e'"} + for i, r := range row { + c.Check(r, Equals, expectedRow[i]) + } + + // for issue https://github.com/pingcap/tidb/issues/4425 + tk.MustExec("drop table if exists show_test") + testSQL = `create table show_test( + a varchar(10) DEFAULT 'a\nb\rc\td\0e' + );` + tk.MustExec(testSQL) + testSQL = "show create table show_test;" + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 1) + row = result.Rows()[0] + expectedRow = []interface{}{ + "show_test", "CREATE TABLE `show_test` (\n `a` varchar(10) DEFAULT 'a\\nb\\rc d\\0e'\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} + for i, r := range row { + c.Check(r, Equals, expectedRow[i]) + } + + // for issue https://github.com/pingcap/tidb/issues/4426 + tk.MustExec("drop table if exists show_test") + testSQL = `create table show_test( + a bit(1), + b bit(32) DEFAULT 0b0, + c bit(1) DEFAULT 0b1, + d bit(10) DEFAULT 0b1010 + );` + tk.MustExec(testSQL) + testSQL = "show create table show_test;" + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 1) + row = result.Rows()[0] + expectedRow = []interface{}{ + "show_test", "CREATE TABLE `show_test` (\n `a` bit(1) DEFAULT NULL,\n `b` bit(32) DEFAULT b'0',\n `c` bit(1) DEFAULT b'1',\n `d` bit(10) DEFAULT b'1010'\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} + for i, r := range row { + c.Check(r, Equals, expectedRow[i]) + } + + // for issue #4255 + result = tk.MustQuery(`show function status like '%'`) + result.Check(result.Rows()) + result = tk.MustQuery(`show plugins like '%'`) + result.Check(result.Rows()) + + // for issue #4740 + testSQL = `drop table if exists t` + tk.MustExec(testSQL) + testSQL = `create table t (a int1, b int2, c int3, d int4, e int8)` + tk.MustExec(testSQL) + testSQL = `show create table t;` + result = tk.MustQuery(testSQL) + c.Check(result.Rows(), HasLen, 1) + row = result.Rows()[0] + expectedRow = []interface{}{ + "t", + "CREATE TABLE `t` (\n" + + " `a` tinyint(4) DEFAULT NULL,\n" + + " `b` smallint(6) DEFAULT NULL,\n" + + " `c` mediumint(9) DEFAULT NULL,\n" + + " `d` int(11) DEFAULT NULL,\n" + + " `e` bigint(20) DEFAULT NULL\n" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + } + for i, r := range row { + c.Check(r, Equals, expectedRow[i]) + } + + // Test get default collate for a specified charset. + tk.MustExec(`drop table if exists t`) + tk.MustExec(`create table t (a int) default charset=utf8mb4`) + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + )) + + // Test range partition + tk.MustExec(`drop table if exists t`) + tk.MustExec(`CREATE TABLE t (a int) PARTITION BY RANGE(a) ( + PARTITION p0 VALUES LESS THAN (10), + PARTITION p1 VALUES LESS THAN (20), + PARTITION p2 VALUES LESS THAN (MAXVALUE))`) + tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|", + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"+"\nPARTITION BY RANGE ( `a` ) (\n PARTITION p0 VALUES LESS THAN (10),\n PARTITION p1 VALUES LESS THAN (20),\n PARTITION p2 VALUES LESS THAN (MAXVALUE)\n)", + )) + + tk.MustExec(`drop table if exists t`) + _, err := tk.Exec(`CREATE TABLE t (x int, y char) PARTITION BY RANGE(y) ( + PARTITION p0 VALUES LESS THAN (10), + PARTITION p1 VALUES LESS THAN (20), + PARTITION p2 VALUES LESS THAN (MAXVALUE))`) + c.Assert(err, NotNil) + + // Test range columns partition + tk.MustExec(`drop table if exists t`) + tk.MustExec(`CREATE TABLE t (a int, b int, c char, d int) PARTITION BY RANGE COLUMNS(a,d,c) ( + PARTITION p0 VALUES LESS THAN (5,10,'ggg'), + PARTITION p1 VALUES LESS THAN (10,20,'mmm'), + PARTITION p2 VALUES LESS THAN (15,30,'sss'), + PARTITION p3 VALUES LESS THAN (50,MAXVALUE,MAXVALUE))`) + tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|", + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` int(11) DEFAULT NULL,\n"+ + " `c` char(1) DEFAULT NULL,\n"+ + " `d` int(11) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"+"\nPARTITION BY RANGE COLUMNS(a,d,c) (\n PARTITION p0 VALUES LESS THAN (5,10,\"ggg\"),\n PARTITION p1 VALUES LESS THAN (10,20,\"mmm\"),\n PARTITION p2 VALUES LESS THAN (15,30,\"sss\"),\n PARTITION p3 VALUES LESS THAN (50,MAXVALUE,MAXVALUE)\n)", + )) + + // Test hash partition + tk.MustExec(`drop table if exists t`) + tk.MustExec(`CREATE TABLE t (a int) PARTITION BY HASH(a) PARTITIONS 4`) + tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|", + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"+"\nPARTITION BY HASH( `a` )\nPARTITIONS 4", + )) + + // Test show create table compression type. + tk.MustExec(`drop table if exists t1`) + tk.MustExec(`CREATE TABLE t1 (c1 INT) COMPRESSION="zlib";`) + tk.MustQuery("show create table t1").Check(testutil.RowsWithSep("|", + "t1 CREATE TABLE `t1` (\n"+ + " `c1` int(11) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMPRESSION='zlib'", + )) + + // Test show create table year type + tk.MustExec(`drop table if exists t`) + tk.MustExec(`create table t(y year unsigned signed zerofill zerofill, x int, primary key(y));`) + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", + "t CREATE TABLE `t` (\n"+ + " `y` year NOT NULL,\n"+ + " `x` int(11) DEFAULT NULL,\n"+ + " PRIMARY KEY (`y`)\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + + // Test show create table with zerofill flag + tk.MustExec(`drop table if exists t`) + tk.MustExec(`create table t(id int primary key, val tinyint(10) zerofill);`) + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", + "t CREATE TABLE `t` (\n"+ + " `id` int(11) NOT NULL,\n"+ + " `val` tinyint(10) UNSIGNED ZEROFILL DEFAULT NULL,\n"+ + " PRIMARY KEY (`id`)\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + + // Test show columns with different types of default value + tk.MustExec(`drop table if exists t`) + tk.MustExec(`create table t( + c0 int default 1, + c1 int default b'010', + c2 bigint default x'A7', + c3 bit(8) default b'00110001', + c4 varchar(6) default b'00110001', + c5 varchar(6) default '\'C6\'', + c6 enum('s', 'm', 'l', 'xl') default 'xl', + c7 set('a', 'b', 'c', 'd') default 'a,c,c', + c8 datetime default current_timestamp on update current_timestamp, + c9 year default '2014' + );`) + tk.MustQuery(`show columns from t`).Check(testutil.RowsWithSep("|", + "c0|int(11)|YES||1|", + "c1|int(11)|YES||2|", + "c2|bigint(20)|YES||167|", + "c3|bit(8)|YES||b'110001'|", + "c4|varchar(6)|YES||1|", + "c5|varchar(6)|YES||'C6'|", + "c6|enum('s','m','l','xl')|YES||xl|", + "c7|set('a','b','c','d')|YES||a,c,c|", + "c8|datetime|YES||CURRENT_TIMESTAMP|on update CURRENT_TIMESTAMP", + "c9|year|YES||2014|", + )) +} + +func (s *seqTestSuite) TestShowStatsHealthy(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (a int)") + tk.MustExec("create index idx on t(a)") + tk.MustExec("analyze table t") + tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 100")) + tk.MustExec("insert into t values (1), (2)") + do, _ := session.GetDomain(s.store) + do.StatsHandle().DumpStatsDeltaToKV(statistics.DumpAll) + tk.MustExec("analyze table t") + tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 100")) + tk.MustExec("insert into t values (3), (4), (5), (6), (7), (8), (9), (10)") + do.StatsHandle().DumpStatsDeltaToKV(statistics.DumpAll) + do.StatsHandle().Update(do.InfoSchema()) + tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 19")) + tk.MustExec("analyze table t") + tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 100")) + tk.MustExec("delete from t") + do.StatsHandle().DumpStatsDeltaToKV(statistics.DumpAll) + do.StatsHandle().Update(do.InfoSchema()) + tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 0")) +} + +// TestIndexDoubleReadClose checks that when a index double read returns before reading all the rows, the goroutine doesn't +// leak. For testing distsql with multiple regions, we need to manually split a mock TiKV. +func (s *seqTestSuite) TestIndexDoubleReadClose(c *C) { + if _, ok := s.store.GetClient().(*tikv.CopClient); !ok { + // Make sure the store is tikv store. + return + } + originSize := atomic.LoadInt32(&executor.LookupTableTaskChannelSize) + atomic.StoreInt32(&executor.LookupTableTaskChannelSize, 1) + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("set @@tidb_index_lookup_size = '10'") + tk.MustExec("use test") + tk.MustExec("create table dist (id int primary key, c_idx int, c_col int, index (c_idx))") + + // Insert 100 rows. + var values []string + for i := 0; i < 100; i++ { + values = append(values, fmt.Sprintf("(%d, %d, %d)", i, i, i)) + } + tk.MustExec("insert dist values " + strings.Join(values, ",")) + + rs, err := tk.Exec("select * from dist where c_idx between 0 and 100") + c.Assert(err, IsNil) + chk := rs.NewChunk() + err = rs.Next(context.Background(), chk) + c.Assert(err, IsNil) + c.Assert(err, IsNil) + keyword := "pickAndExecTask" + rs.Close() + time.Sleep(time.Millisecond * 10) + c.Check(checkGoroutineExists(keyword), IsFalse) + atomic.StoreInt32(&executor.LookupTableTaskChannelSize, originSize) +} + +func checkGoroutineExists(keyword string) bool { + buf := new(bytes.Buffer) + profile := pprof.Lookup("goroutine") + profile.WriteTo(buf, 1) + str := buf.String() + return strings.Contains(str, keyword) +} + +func (s *seqTestSuite) TestAdminShowNextID(c *C) { + step := int64(10) + autoIDStep := autoid.GetStep() + autoid.SetStep(step) + defer autoid.SetStep(autoIDStep) + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("create table t(id int, c int)") + // Start handle is 1. + r := tk.MustQuery("admin show t next_row_id") + r.Check(testkit.Rows("test t _tidb_rowid 1")) + // Row ID is step + 1. + tk.MustExec("insert into t values(1, 1)") + r = tk.MustQuery("admin show t next_row_id") + r.Check(testkit.Rows("test t _tidb_rowid 11")) + // Row ID is original + step. + for i := 0; i < int(step); i++ { + tk.MustExec("insert into t values(10000, 1)") + } + r = tk.MustQuery("admin show t next_row_id") + r.Check(testkit.Rows("test t _tidb_rowid 21")) + + // test for a table with the primary key + tk.MustExec("create table tt(id int primary key auto_increment, c int)") + // Start handle is 1. + r = tk.MustQuery("admin show tt next_row_id") + r.Check(testkit.Rows("test tt id 1")) + // After rebasing auto ID, row ID is 20 + step + 1. + tk.MustExec("insert into tt values(20, 1)") + r = tk.MustQuery("admin show tt next_row_id") + r.Check(testkit.Rows("test tt id 31")) + // test for renaming the table + tk.MustExec("create database test1") + tk.MustExec("rename table test.tt to test1.tt") + tk.MustExec("use test1") + r = tk.MustQuery("admin show tt next_row_id") + r.Check(testkit.Rows("test1 tt id 31")) + tk.MustExec("insert test1.tt values ()") + r = tk.MustQuery("admin show tt next_row_id") + r.Check(testkit.Rows("test1 tt id 41")) +} + +func (s *seqTestSuite) TestPrepareMaxParamCountCheck(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (v int)") + normalSQL, normalParams := generateBatchSQL(math.MaxUint16) + _, err := tk.Exec(normalSQL, normalParams...) + c.Assert(err, IsNil) + + bigSQL, bigParams := generateBatchSQL(math.MaxUint16 + 2) + _, err = tk.Exec(bigSQL, bigParams...) + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "[executor:1390]Prepared statement contains too many placeholders") +} + +func generateBatchSQL(paramCount int) (sql string, paramSlice []interface{}) { + params := make([]interface{}, 0, paramCount) + placeholders := make([]string, 0, paramCount) + for i := 0; i < paramCount; i++ { + params = append(params, i) + placeholders = append(placeholders, "(?)") + } + return "insert into t values " + strings.Join(placeholders, ","), params +} diff --git a/executor/set_test.go b/executor/set_test.go index f02c594bbe105..51a35985d8125 100644 --- a/executor/set_test.go +++ b/executor/set_test.go @@ -24,7 +24,7 @@ import ( "github.com/pingcap/tidb/util/testutil" ) -func (s *testSuite) TestSetVar(c *C) { +func (s *testSuite2) TestSetVar(c *C) { tk := testkit.NewTestKit(c, s.store) testSQL := "SET @a = 1;" tk.MustExec(testSQL) @@ -276,7 +276,7 @@ func (s *testSuite) TestSetVar(c *C) { c.Assert(err, NotNil) } -func (s *testSuite) TestSetCharset(c *C) { +func (s *testSuite2) TestSetCharset(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`SET NAMES latin1`) @@ -301,7 +301,7 @@ func (s *testSuite) TestSetCharset(c *C) { tk.MustExec(`SET NAMES binary`) } -func (s *testSuite) TestValidateSetVar(c *C) { +func (s *testSuite2) TestValidateSetVar(c *C) { tk := testkit.NewTestKit(c, s.store) _, err := tk.Exec("set global tidb_distsql_scan_concurrency='fff';") diff --git a/executor/show_stats_test.go b/executor/show_stats_test.go index c0cc6e70f7cd1..05987b5935203 100644 --- a/executor/show_stats_test.go +++ b/executor/show_stats_test.go @@ -15,12 +15,10 @@ package executor_test import ( . "github.com/pingcap/check" - "github.com/pingcap/tidb/session" - "github.com/pingcap/tidb/statistics" "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestShowStatsMeta(c *C) { +func (s *testSuite1) TestShowStatsMeta(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t, t1") @@ -36,7 +34,7 @@ func (s *testSuite) TestShowStatsMeta(c *C) { c.Assert(result.Rows()[0][1], Equals, "t") } -func (s *testSuite) TestShowStatsHistograms(c *C) { +func (s *testSuite1) TestShowStatsHistograms(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -51,7 +49,7 @@ func (s *testSuite) TestShowStatsHistograms(c *C) { c.Assert(result.Rows()[0][3], Equals, "a") } -func (s *testSuite) TestShowStatsBuckets(c *C) { +func (s *testSuite1) TestShowStatsBuckets(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -65,32 +63,7 @@ func (s *testSuite) TestShowStatsBuckets(c *C) { result.Check(testkit.Rows("test t idx 1 0 1 1 (1, 1) (1, 1)")) } -func (s *testSuite) TestShowStatsHealthy(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t") - tk.MustExec("create table t (a int)") - tk.MustExec("create index idx on t(a)") - tk.MustExec("analyze table t") - tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 100")) - tk.MustExec("insert into t values (1), (2)") - do, _ := session.GetDomain(s.store) - do.StatsHandle().DumpStatsDeltaToKV(statistics.DumpAll) - tk.MustExec("analyze table t") - tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 100")) - tk.MustExec("insert into t values (3), (4), (5), (6), (7), (8), (9), (10)") - do.StatsHandle().DumpStatsDeltaToKV(statistics.DumpAll) - do.StatsHandle().Update(do.InfoSchema()) - tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 19")) - tk.MustExec("analyze table t") - tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 100")) - tk.MustExec("delete from t") - do.StatsHandle().DumpStatsDeltaToKV(statistics.DumpAll) - do.StatsHandle().Update(do.InfoSchema()) - tk.MustQuery("show stats_healthy").Check(testkit.Rows("test t 0")) -} - -func (s *testSuite) TestShowStatsHasNullValue(c *C) { +func (s *testSuite1) TestShowStatsHasNullValue(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table t (a int, index idx(a))") @@ -99,7 +72,7 @@ func (s *testSuite) TestShowStatsHasNullValue(c *C) { tk.MustQuery("show stats_buckets").Check(testkit.Rows("test t idx 1 0 1 1 NULL NULL")) } -func (s *testSuite) TestShowPartitionStats(c *C) { +func (s *testSuite1) TestShowPartitionStats(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("set @@session.tidb_enable_table_partition=1") tk.MustExec("use test") diff --git a/executor/show_test.go b/executor/show_test.go index 67d7f16d664b9..c16c521caa628 100644 --- a/executor/show_test.go +++ b/executor/show_test.go @@ -16,7 +16,6 @@ package executor_test import ( "context" "fmt" - "strconv" . "github.com/pingcap/check" "github.com/pingcap/errors" @@ -24,439 +23,14 @@ import ( "github.com/pingcap/parser/model" "github.com/pingcap/parser/mysql" "github.com/pingcap/tidb/domain" - "github.com/pingcap/tidb/meta/autoid" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/util/testkit" "github.com/pingcap/tidb/util/testutil" ) -func (s *testSuite) TestShow(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - - testSQL := `drop table if exists show_test` - tk.MustExec(testSQL) - testSQL = `create table SHOW_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int comment "c1_comment", c2 int, c3 int default 1, c4 text, c5 boolean, key idx_wide_c4(c3, c4(10))) ENGINE=InnoDB AUTO_INCREMENT=28934 DEFAULT CHARSET=utf8 COMMENT "table_comment";` - tk.MustExec(testSQL) - - testSQL = "show columns from show_test;" - result := tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 6) - - testSQL = "show create table show_test;" - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 1) - row := result.Rows()[0] - // For issue https://github.com/pingcap/tidb/issues/1061 - expectedRow := []interface{}{ - "SHOW_test", "CREATE TABLE `SHOW_test` (\n `id` int(11) NOT NULL AUTO_INCREMENT,\n `c1` int(11) DEFAULT NULL COMMENT 'c1_comment',\n `c2` int(11) DEFAULT NULL,\n `c3` int(11) DEFAULT '1',\n `c4` text DEFAULT NULL,\n `c5` tinyint(1) DEFAULT NULL,\n PRIMARY KEY (`id`),\n KEY `idx_wide_c4` (`c3`,`c4`(10))\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=28934 COMMENT='table_comment'"} - for i, r := range row { - c.Check(r, Equals, expectedRow[i]) - } - - // For issue https://github.com/pingcap/tidb/issues/1918 - testSQL = `create table ptest( - a int primary key, - b double NOT NULL DEFAULT 2.0, - c varchar(10) NOT NULL, - d time unique, - e timestamp NULL, - f timestamp - );` - tk.MustExec(testSQL) - testSQL = "show create table ptest;" - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 1) - row = result.Rows()[0] - expectedRow = []interface{}{ - "ptest", "CREATE TABLE `ptest` (\n `a` int(11) NOT NULL,\n `b` double NOT NULL DEFAULT '2.0',\n `c` varchar(10) NOT NULL,\n `d` time DEFAULT NULL,\n `e` timestamp NULL DEFAULT NULL,\n `f` timestamp NULL DEFAULT NULL,\n PRIMARY KEY (`a`),\n UNIQUE KEY `d` (`d`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} - for i, r := range row { - c.Check(r, Equals, expectedRow[i]) - } - - // Issue #4684. - tk.MustExec("drop table if exists `t1`") - testSQL = "create table `t1` (" + - "`c1` tinyint unsigned default null," + - "`c2` smallint unsigned default null," + - "`c3` mediumint unsigned default null," + - "`c4` int unsigned default null," + - "`c5` bigint unsigned default null);`" - - tk.MustExec(testSQL) - testSQL = "show create table t1" - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 1) - row = result.Rows()[0] - expectedRow = []interface{}{ - "t1", "CREATE TABLE `t1` (\n" + - " `c1` tinyint(3) UNSIGNED DEFAULT NULL,\n" + - " `c2` smallint(5) UNSIGNED DEFAULT NULL,\n" + - " `c3` mediumint(8) UNSIGNED DEFAULT NULL,\n" + - " `c4` int(10) UNSIGNED DEFAULT NULL,\n" + - " `c5` bigint(20) UNSIGNED DEFAULT NULL\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} - for i, r := range row { - c.Check(r, Equals, expectedRow[i]) - } - - // Issue #7665 - tk.MustExec("drop table if exists `decimalschema`") - testSQL = "create table `decimalschema` (`c1` decimal);" - tk.MustExec(testSQL) - testSQL = "show create table decimalschema" - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 1) - row = result.Rows()[0] - expectedRow = []interface{}{ - "decimalschema", "CREATE TABLE `decimalschema` (\n" + - " `c1` decimal(11,0) DEFAULT NULL\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} - for i, r := range row { - c.Check(r, Equals, expectedRow[i]) - } - - tk.MustExec("drop table if exists `decimalschema`") - testSQL = "create table `decimalschema` (`c1` decimal(15));" - tk.MustExec(testSQL) - testSQL = "show create table decimalschema" - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 1) - row = result.Rows()[0] - expectedRow = []interface{}{ - "decimalschema", "CREATE TABLE `decimalschema` (\n" + - " `c1` decimal(15,0) DEFAULT NULL\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} - for i, r := range row { - c.Check(r, Equals, expectedRow[i]) - } - - testSQL = "SHOW VARIABLES LIKE 'character_set_results';" - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 1) - - // Test case for index type and comment - tk.MustExec(`create table show_index (id int, c int, primary key (id), index cIdx using hash (c) comment "index_comment_for_cIdx");`) - tk.MustExec(`create index idx1 on show_index (id) using hash;`) - tk.MustExec(`create index idx2 on show_index (id) comment 'idx';`) - tk.MustExec(`create index idx3 on show_index (id) using hash comment 'idx';`) - tk.MustExec(`alter table show_index add index idx4 (id) using btree comment 'idx';`) - tk.MustExec(`create index idx5 using hash on show_index (id) using btree comment 'idx';`) - tk.MustExec(`create index idx6 using hash on show_index (id);`) - tk.MustExec(`create index idx7 on show_index (id);`) - testSQL = "SHOW index from show_index;" - tk.MustQuery(testSQL).Check(testutil.RowsWithSep("|", - "show_index|0|PRIMARY|1|id|A|0||||BTREE||", - "show_index|1|cIdx|1|c|A|0|||YES|HASH||index_comment_for_cIdx", - "show_index|1|idx1|1|id|A|0|||YES|HASH||", - "show_index|1|idx2|1|id|A|0|||YES|BTREE||idx", - "show_index|1|idx3|1|id|A|0|||YES|HASH||idx", - "show_index|1|idx4|1|id|A|0|||YES|BTREE||idx", - "show_index|1|idx5|1|id|A|0|||YES|BTREE||idx", - "show_index|1|idx6|1|id|A|0|||YES|HASH||", - "show_index|1|idx7|1|id|A|0|||YES|BTREE||", - )) - - // For show like with escape - testSQL = `show tables like 'SHOW\_test'` - result = tk.MustQuery(testSQL) - rows := result.Rows() - c.Check(rows, HasLen, 1) - c.Check(rows[0], DeepEquals, []interface{}{"SHOW_test"}) - - var ss stats - variable.RegisterStatistics(ss) - testSQL = "show status like 'character_set_results';" - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), NotNil) - - tk.MustQuery("SHOW PROCEDURE STATUS WHERE Db='test'").Check(testkit.Rows()) - tk.MustQuery("SHOW TRIGGERS WHERE `Trigger` ='test'").Check(testkit.Rows()) - tk.MustQuery("SHOW PROCESSLIST;").Check(testkit.Rows()) - tk.MustQuery("SHOW FULL PROCESSLIST;").Check(testkit.Rows()) - tk.MustQuery("SHOW EVENTS WHERE Db = 'test'").Check(testkit.Rows()) - tk.MustQuery("SHOW PLUGINS").Check(testkit.Rows()) - tk.MustQuery("SHOW PROFILES").Check(testkit.Rows()) - - // +-------------+--------------------+--------------+------------------+-------------------+ - // | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | - // +-------------+--------------------+--------------+------------------+-------------------+ - // | tidb-binlog | 400668057259474944 | | | | - // +-------------+--------------------+--------------+------------------+-------------------+ - result = tk.MustQuery("SHOW MASTER STATUS") - c.Check(result.Rows(), HasLen, 1) - row = result.Rows()[0] - c.Check(row, HasLen, 5) - c.Assert(row[1].(string) != "0", IsTrue) - - tk.MustQuery("SHOW PRIVILEGES") - - // Test show create database - testSQL = `create database show_test_DB` - tk.MustExec(testSQL) - testSQL = "show create database show_test_DB;" - tk.MustQuery(testSQL).Check(testutil.RowsWithSep("|", - "show_test_DB|CREATE DATABASE `show_test_DB` /* !40100 DEFAULT CHARACTER SET utf8mb4 */", - )) - - tk.MustExec("use show_test_DB") - result = tk.MustQuery("SHOW index from show_index from test where Column_name = 'c'") - c.Check(result.Rows(), HasLen, 1) - - // Test show full columns - // for issue https://github.com/pingcap/tidb/issues/4224 - tk.MustExec(`drop table if exists show_test_comment`) - tk.MustExec(`create table show_test_comment (id int not null default 0 comment "show_test_comment_id")`) - tk.MustQuery(`show full columns from show_test_comment`).Check(testutil.RowsWithSep("|", - "id|int(11)|binary|NO||0||select,insert,update,references|show_test_comment_id", - )) - - // Test show create table with AUTO_INCREMENT option - // for issue https://github.com/pingcap/tidb/issues/3747 - tk.MustExec(`drop table if exists show_auto_increment`) - tk.MustExec(`create table show_auto_increment (id int key auto_increment) auto_increment=4`) - tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|", - ""+ - "show_auto_increment CREATE TABLE `show_auto_increment` (\n"+ - " `id` int(11) NOT NULL AUTO_INCREMENT,\n"+ - " PRIMARY KEY (`id`)\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=4", - )) - // for issue https://github.com/pingcap/tidb/issues/4678 - autoIDStep := autoid.GetStep() - tk.MustExec("insert into show_auto_increment values(20)") - autoID := autoIDStep + 21 - tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|", - ""+ - "show_auto_increment CREATE TABLE `show_auto_increment` (\n"+ - " `id` int(11) NOT NULL AUTO_INCREMENT,\n"+ - " PRIMARY KEY (`id`)\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT="+strconv.Itoa(int(autoID)), - )) - tk.MustExec(`drop table show_auto_increment`) - tk.MustExec(`create table show_auto_increment (id int primary key auto_increment)`) - tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|", - ""+ - "show_auto_increment CREATE TABLE `show_auto_increment` (\n"+ - " `id` int(11) NOT NULL AUTO_INCREMENT,\n"+ - " PRIMARY KEY (`id`)\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", - )) - tk.MustExec("insert into show_auto_increment values(10)") - autoID = autoIDStep + 11 - tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|", - ""+ - "show_auto_increment CREATE TABLE `show_auto_increment` (\n"+ - " `id` int(11) NOT NULL AUTO_INCREMENT,\n"+ - " PRIMARY KEY (`id`)\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT="+strconv.Itoa(int(autoID)), - )) - - // Test show table with column's comment contain escape character - // for issue https://github.com/pingcap/tidb/issues/4411 - tk.MustExec(`drop table if exists show_escape_character`) - tk.MustExec(`create table show_escape_character(id int comment 'a\rb\nc\td\0ef')`) - tk.MustQuery(`show create table show_escape_character`).Check(testutil.RowsWithSep("|", - ""+ - "show_escape_character CREATE TABLE `show_escape_character` (\n"+ - " `id` int(11) DEFAULT NULL COMMENT 'a\\rb\\nc d\\0ef'\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", - )) - - // for issue https://github.com/pingcap/tidb/issues/4424 - tk.MustExec("drop table if exists show_test") - testSQL = `create table show_test( - a varchar(10) COMMENT 'a\nb\rc\td\0e' - ) COMMENT='a\nb\rc\td\0e';` - tk.MustExec(testSQL) - testSQL = "show create table show_test;" - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 1) - row = result.Rows()[0] - expectedRow = []interface{}{ - "show_test", "CREATE TABLE `show_test` (\n `a` varchar(10) DEFAULT NULL COMMENT 'a\\nb\\rc d\\0e'\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='a\\nb\\rc d\\0e'"} - for i, r := range row { - c.Check(r, Equals, expectedRow[i]) - } - - // for issue https://github.com/pingcap/tidb/issues/4425 - tk.MustExec("drop table if exists show_test") - testSQL = `create table show_test( - a varchar(10) DEFAULT 'a\nb\rc\td\0e' - );` - tk.MustExec(testSQL) - testSQL = "show create table show_test;" - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 1) - row = result.Rows()[0] - expectedRow = []interface{}{ - "show_test", "CREATE TABLE `show_test` (\n `a` varchar(10) DEFAULT 'a\\nb\\rc d\\0e'\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} - for i, r := range row { - c.Check(r, Equals, expectedRow[i]) - } - - // for issue https://github.com/pingcap/tidb/issues/4426 - tk.MustExec("drop table if exists show_test") - testSQL = `create table show_test( - a bit(1), - b bit(32) DEFAULT 0b0, - c bit(1) DEFAULT 0b1, - d bit(10) DEFAULT 0b1010 - );` - tk.MustExec(testSQL) - testSQL = "show create table show_test;" - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 1) - row = result.Rows()[0] - expectedRow = []interface{}{ - "show_test", "CREATE TABLE `show_test` (\n `a` bit(1) DEFAULT NULL,\n `b` bit(32) DEFAULT b'0',\n `c` bit(1) DEFAULT b'1',\n `d` bit(10) DEFAULT b'1010'\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"} - for i, r := range row { - c.Check(r, Equals, expectedRow[i]) - } - - // for issue #4255 - result = tk.MustQuery(`show function status like '%'`) - result.Check(result.Rows()) - result = tk.MustQuery(`show plugins like '%'`) - result.Check(result.Rows()) - - // for issue #4740 - testSQL = `drop table if exists t` - tk.MustExec(testSQL) - testSQL = `create table t (a int1, b int2, c int3, d int4, e int8)` - tk.MustExec(testSQL) - testSQL = `show create table t;` - result = tk.MustQuery(testSQL) - c.Check(result.Rows(), HasLen, 1) - row = result.Rows()[0] - expectedRow = []interface{}{ - "t", - "CREATE TABLE `t` (\n" + - " `a` tinyint(4) DEFAULT NULL,\n" + - " `b` smallint(6) DEFAULT NULL,\n" + - " `c` mediumint(9) DEFAULT NULL,\n" + - " `d` int(11) DEFAULT NULL,\n" + - " `e` bigint(20) DEFAULT NULL\n" + - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", - } - for i, r := range row { - c.Check(r, Equals, expectedRow[i]) - } - - // Test get default collate for a specified charset. - tk.MustExec(`drop table if exists t`) - tk.MustExec(`create table t (a int) default charset=utf8mb4`) - tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", - "t CREATE TABLE `t` (\n"+ - " `a` int(11) DEFAULT NULL\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", - )) - - // Test range partition - tk.MustExec(`drop table if exists t`) - tk.MustExec(`CREATE TABLE t (a int) PARTITION BY RANGE(a) ( - PARTITION p0 VALUES LESS THAN (10), - PARTITION p1 VALUES LESS THAN (20), - PARTITION p2 VALUES LESS THAN (MAXVALUE))`) - tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|", - "t CREATE TABLE `t` (\n"+ - " `a` int(11) DEFAULT NULL\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"+"\nPARTITION BY RANGE ( `a` ) (\n PARTITION p0 VALUES LESS THAN (10),\n PARTITION p1 VALUES LESS THAN (20),\n PARTITION p2 VALUES LESS THAN (MAXVALUE)\n)", - )) - - tk.MustExec(`drop table if exists t`) - _, err := tk.Exec(`CREATE TABLE t (x int, y char) PARTITION BY RANGE(y) ( - PARTITION p0 VALUES LESS THAN (10), - PARTITION p1 VALUES LESS THAN (20), - PARTITION p2 VALUES LESS THAN (MAXVALUE))`) - c.Assert(err, NotNil) - - // Test range columns partition - tk.MustExec(`drop table if exists t`) - tk.MustExec(`CREATE TABLE t (a int, b int, c char, d int) PARTITION BY RANGE COLUMNS(a,d,c) ( - PARTITION p0 VALUES LESS THAN (5,10,'ggg'), - PARTITION p1 VALUES LESS THAN (10,20,'mmm'), - PARTITION p2 VALUES LESS THAN (15,30,'sss'), - PARTITION p3 VALUES LESS THAN (50,MAXVALUE,MAXVALUE))`) - tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|", - "t CREATE TABLE `t` (\n"+ - " `a` int(11) DEFAULT NULL,\n"+ - " `b` int(11) DEFAULT NULL,\n"+ - " `c` char(1) DEFAULT NULL,\n"+ - " `d` int(11) DEFAULT NULL\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"+"\nPARTITION BY RANGE COLUMNS(a,d,c) (\n PARTITION p0 VALUES LESS THAN (5,10,\"ggg\"),\n PARTITION p1 VALUES LESS THAN (10,20,\"mmm\"),\n PARTITION p2 VALUES LESS THAN (15,30,\"sss\"),\n PARTITION p3 VALUES LESS THAN (50,MAXVALUE,MAXVALUE)\n)", - )) - - // Test hash partition - tk.MustExec(`drop table if exists t`) - tk.MustExec(`CREATE TABLE t (a int) PARTITION BY HASH(a) PARTITIONS 4`) - tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|", - "t CREATE TABLE `t` (\n"+ - " `a` int(11) DEFAULT NULL\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"+"\nPARTITION BY HASH( `a` )\nPARTITIONS 4", - )) - - // Test show create table compression type. - tk.MustExec(`drop table if exists t1`) - tk.MustExec(`CREATE TABLE t1 (c1 INT) COMPRESSION="zlib";`) - tk.MustQuery("show create table t1").Check(testutil.RowsWithSep("|", - "t1 CREATE TABLE `t1` (\n"+ - " `c1` int(11) DEFAULT NULL\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMPRESSION='zlib'", - )) - - // Test show create table year type - tk.MustExec(`drop table if exists t`) - tk.MustExec(`create table t(y year unsigned signed zerofill zerofill, x int, primary key(y));`) - tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", - "t CREATE TABLE `t` (\n"+ - " `y` year NOT NULL,\n"+ - " `x` int(11) DEFAULT NULL,\n"+ - " PRIMARY KEY (`y`)\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) - - // Test show create table with zerofill flag - tk.MustExec(`drop table if exists t`) - tk.MustExec(`create table t(id int primary key, val tinyint(10) zerofill);`) - tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", - "t CREATE TABLE `t` (\n"+ - " `id` int(11) NOT NULL,\n"+ - " `val` tinyint(10) UNSIGNED ZEROFILL DEFAULT NULL,\n"+ - " PRIMARY KEY (`id`)\n"+ - ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) - - // Test show columns with different types of default value - tk.MustExec(`drop table if exists t`) - tk.MustExec(`create table t( - c0 int default 1, - c1 int default b'010', - c2 bigint default x'A7', - c3 bit(8) default b'00110001', - c4 varchar(6) default b'00110001', - c5 varchar(6) default '\'C6\'', - c6 enum('s', 'm', 'l', 'xl') default 'xl', - c7 set('a', 'b', 'c', 'd') default 'a,c,c', - c8 datetime default current_timestamp on update current_timestamp, - c9 year default '2014' - );`) - tk.MustQuery(`show columns from t`).Check(testutil.RowsWithSep("|", - "c0|int(11)|YES||1|", - "c1|int(11)|YES||2|", - "c2|bigint(20)|YES||167|", - "c3|bit(8)|YES||b'110001'|", - "c4|varchar(6)|YES||1|", - "c5|varchar(6)|YES||'C6'|", - "c6|enum('s','m','l','xl')|YES||xl|", - "c7|set('a','b','c','d')|YES||a,c,c|", - "c8|datetime|YES||CURRENT_TIMESTAMP|on update CURRENT_TIMESTAMP", - "c9|year|YES||2014|", - )) -} - -func (s *testSuite) TestShowVisibility(c *C) { +func (s *testSuite2) TestShowVisibility(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("create database showdatabase") tk.MustExec("use showdatabase") @@ -498,7 +72,7 @@ func (s *testSuite) TestShowVisibility(c *C) { tk.MustExec("drop database showdatabase") } -func (s *testSuite) TestShowDatabasesInfoSchemaFirst(c *C) { +func (s *testSuite2) TestShowDatabasesInfoSchemaFirst(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustQuery("show databases").Check(testkit.Rows("INFORMATION_SCHEMA")) tk.MustExec(`create user 'show'@'%'`) @@ -532,22 +106,7 @@ type mockSessionManager struct { func (msm *mockSessionManager) Kill(cid uint64, query bool) { } -type stats struct { -} - -func (s stats) GetScope(status string) variable.ScopeFlag { return variable.DefaultStatusVarScopeFlag } - -func (s stats) Stats(vars *variable.SessionVars) (map[string]interface{}, error) { - m := make(map[string]interface{}) - var a, b interface{} - b = "123" - m["test_interface_nil"] = a - m["test_interface"] = b - m["test_interface_slice"] = []interface{}{"a", "b", "c"} - return m, nil -} - -func (s *testSuite) TestShowWarnings(c *C) { +func (s *testSuite2) TestShowWarnings(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") testSQL := `create table if not exists show_warnings (a int)` @@ -578,7 +137,7 @@ func (s *testSuite) TestShowWarnings(c *C) { tk.MustQuery("select @@warning_count").Check(testutil.RowsWithSep("|", "0")) } -func (s *testSuite) TestShowErrors(c *C) { +func (s *testSuite2) TestShowErrors(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") testSQL := `create table if not exists show_errors (a int)` @@ -589,7 +148,7 @@ func (s *testSuite) TestShowErrors(c *C) { tk.MustQuery("show errors").Check(testutil.RowsWithSep("|", "Error|1050|Table 'test.show_errors' already exists")) } -func (s *testSuite) TestIssue3641(c *C) { +func (s *testSuite2) TestIssue3641(c *C) { tk := testkit.NewTestKit(c, s.store) _, err := tk.Exec("show tables;") c.Assert(err.Error(), Equals, plannercore.ErrNoDB.Error()) @@ -598,7 +157,7 @@ func (s *testSuite) TestIssue3641(c *C) { } // TestShow2 is moved from session_test -func (s *testSuite) TestShow2(c *C) { +func (s *testSuite2) TestShow2(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -638,7 +197,7 @@ func (s *testSuite) TestShow2(c *C) { tk.MustQuery("show grants for current_user").Check(testkit.Rows(`GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'`)) } -func (s *testSuite) TestUnprivilegedShow(c *C) { +func (s *testSuite2) TestUnprivilegedShow(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("CREATE DATABASE testshow") @@ -669,7 +228,7 @@ func (s *testSuite) TestUnprivilegedShow(c *C) { } -func (s *testSuite) TestCollation(c *C) { +func (s *testSuite2) TestCollation(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -684,7 +243,7 @@ func (s *testSuite) TestCollation(c *C) { c.Assert(fields[5].Column.Tp, Equals, mysql.TypeLonglong) } -func (s *testSuite) TestShowTableStatus(c *C) { +func (s *testSuite2) TestShowTableStatus(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -724,7 +283,7 @@ func (s *testSuite) TestShowTableStatus(c *C) { c.Assert(rows[0].GetString(16), Equals, "partitioned") } -func (s *testSuite) TestShowSlow(c *C) { +func (s *testSuite2) TestShowSlow(c *C) { tk := testkit.NewTestKit(c, s.store) // The test result is volatile, because // 1. Slow queries is stored in domain, which may be affected by other tests. @@ -737,7 +296,7 @@ func (s *testSuite) TestShowSlow(c *C) { tk.MustQuery(`admin show slow top all 3`) } -func (s *testSuite) TestShowEscape(c *C) { +func (s *testSuite2) TestShowEscape(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") diff --git a/executor/simple_test.go b/executor/simple_test.go index bbceb9870b541..73e0958a5e5c4 100644 --- a/executor/simple_test.go +++ b/executor/simple_test.go @@ -28,7 +28,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestCharsetDatabase(c *C) { +func (s *testSuite3) TestCharsetDatabase(c *C) { tk := testkit.NewTestKit(c, s.store) testSQL := `create database if not exists cd_test_utf8 CHARACTER SET utf8 COLLATE utf8_bin;` tk.MustExec(testSQL) @@ -47,13 +47,13 @@ func (s *testSuite) TestCharsetDatabase(c *C) { tk.MustQuery(`select @@collation_database;`).Check(testkit.Rows("latin1_swedish_ci")) } -func (s *testSuite) TestDo(c *C) { +func (s *testSuite3) TestDo(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("do 1, @a:=1") tk.MustQuery("select @a").Check(testkit.Rows("1")) } -func (s *testSuite) TestTransaction(c *C) { +func (s *testSuite3) TestTransaction(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("begin") ctx := tk.Se.(sessionctx.Context) @@ -86,7 +86,7 @@ func inTxn(ctx sessionctx.Context) bool { return (ctx.GetSessionVars().Status & mysql.ServerStatusInTrans) > 0 } -func (s *testSuite) TestUser(c *C) { +func (s *testSuite3) TestUser(c *C) { tk := testkit.NewTestKit(c, s.store) // Make sure user test not in mysql.User. result := tk.MustQuery(`SELECT Password FROM mysql.User WHERE User="test" and Host="localhost"`) @@ -178,12 +178,6 @@ func (s *testSuite) TestUser(c *C) { tk.MustExec(createUserSQL) dropUserSQL = `DROP USER 'test1'@'localhost';` tk.MustExec(dropUserSQL) - tk.MustQuery("select * from mysql.db").Check(testkit.Rows( - "localhost test testDB Y Y Y Y Y Y Y N Y Y N N N N N N Y N N", - "localhost test testDB1 Y Y Y Y Y Y Y N Y Y N N N N N N Y N N", - "% dddb_% dduser Y Y Y Y Y Y Y N Y Y N N N N N N Y N N", - "localhost test testDBRevoke N N N N N N N N N N N N N N N N N N N", - )) // Test drop user meet error _, err = tk.Exec(dropUserSQL) @@ -199,7 +193,7 @@ func (s *testSuite) TestUser(c *C) { c.Assert(terror.ErrorEqual(err, executor.ErrCannotUser.GenWithStackByArgs("DROP USER", "")), IsTrue, Commentf("err %v", err)) } -func (s *testSuite) TestSetPwd(c *C) { +func (s *testSuite3) TestSetPwd(c *C) { tk := testkit.NewTestKit(c, s.store) createUserSQL := `CREATE USER 'testpwd'@'localhost' IDENTIFIED BY '';` @@ -232,7 +226,7 @@ func (s *testSuite) TestSetPwd(c *C) { } -func (s *testSuite) TestKillStmt(c *C) { +func (s *testSuite3) TestKillStmt(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("kill 1") @@ -241,7 +235,7 @@ func (s *testSuite) TestKillStmt(c *C) { result.Check(testkit.Rows("Warning 1105 Invalid operation. Please use 'KILL TIDB [CONNECTION | QUERY] connectionID' instead")) } -func (s *testSuite) TestFlushPrivileges(c *C) { +func (s *testSuite3) TestFlushPrivileges(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`CREATE USER 'testflush'@'localhost' IDENTIFIED BY '';`) @@ -266,7 +260,7 @@ func (s *testSuite) TestFlushPrivileges(c *C) { c.Check(err, IsNil) } -func (s *testSuite) TestDropStats(c *C) { +func (s *testSuite3) TestDropStats(c *C) { testKit := testkit.NewTestKit(c, s.store) testKit.MustExec("use test") testKit.MustExec("create table t (c1 int, c2 int)") @@ -298,7 +292,7 @@ func (s *testSuite) TestDropStats(c *C) { h.Lease = 0 } -func (s *testSuite) TestFlushTables(c *C) { +func (s *testSuite3) TestFlushTables(c *C) { tk := testkit.NewTestKit(c, s.store) _, err := tk.Exec("FLUSH TABLES") diff --git a/executor/statement_context_test.go b/executor/statement_context_test.go index 895e7a81e2df6..f4a56aa1dd0f5 100644 --- a/executor/statement_context_test.go +++ b/executor/statement_context_test.go @@ -28,7 +28,7 @@ const ( nonStrictModeSQL = "set sql_mode = ''" ) -func (s *testSuite) TestStatementContext(c *C) { +func (s *testSuite1) TestStatementContext(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table sc (a int)") diff --git a/executor/trace_test.go b/executor/trace_test.go index 453ce4a8703ef..ec298500a918d 100644 --- a/executor/trace_test.go +++ b/executor/trace_test.go @@ -18,7 +18,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestTraceExec(c *C) { +func (s *testSuite1) TestTraceExec(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") testSQL := `create table trace (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1);` diff --git a/executor/union_scan_test.go b/executor/union_scan_test.go index f0acbc1259869..9bb930fbd751c 100644 --- a/executor/union_scan_test.go +++ b/executor/union_scan_test.go @@ -18,7 +18,7 @@ import ( "github.com/pingcap/tidb/util/testkit" ) -func (s *testSuite) TestDirtyTransaction(c *C) { +func (s *testSuite2) TestDirtyTransaction(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -79,7 +79,7 @@ func (s *testSuite) TestDirtyTransaction(c *C) { tk.MustExec("commit") } -func (s *testSuite) TestUnionScanWithCastCondition(c *C) { +func (s *testSuite2) TestUnionScanWithCastCondition(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table ta (a varchar(20))") diff --git a/executor/write_test.go b/executor/write_test.go index 1df1c431874ec..71ac33b43ae64 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -38,7 +38,7 @@ type testBypassSuite struct{} func (s *testBypassSuite) SetUpSuite(c *C) { } -func (s *testSuite) TestInsert(c *C) { +func (s *testSuite2) TestInsert(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") testSQL := `drop table if exists insert_test;create table insert_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1);` @@ -273,7 +273,7 @@ func (s *testSuite) TestInsert(c *C) { tk.MustQuery("select * from t").Check(testkit.Rows("1 1")) } -func (s *testSuite) TestInsertAutoInc(c *C) { +func (s *testSuite2) TestInsertAutoInc(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") createSQL := `drop table if exists insert_autoinc_test; create table insert_autoinc_test (id int primary key auto_increment, c1 int);` @@ -406,7 +406,7 @@ func (s *testSuite) TestInsertAutoInc(c *C) { r.Check(testkit.Rows(rowStr4, rowStr1, rowStr2, rowStr3, rowStr5, rowStr6, rowStr7, rowStr8)) } -func (s *testSuite) TestInsertIgnore(c *C) { +func (s *testSuite2) TestInsertIgnore(c *C) { var cfg kv.InjectionConfig tk := testkit.NewTestKit(c, kv.NewInjectedStore(s.store, &cfg)) tk.MustExec("use test") @@ -520,7 +520,7 @@ commit;` tk.MustQuery(testSQL).Check(testkit.Rows("0")) } -func (s *testSuite) TestInsertOnDup(c *C) { +func (s *testSuite2) TestInsertOnDup(c *C) { var cfg kv.InjectionConfig tk := testkit.NewTestKit(c, kv.NewInjectedStore(s.store, &cfg)) tk.MustExec("use test") @@ -681,7 +681,7 @@ commit;` tk.MustQuery(`SELECT * FROM t1 order by f1;`).Check(testkit.Rows("1 0", "2 2")) } -func (s *testSuite) TestInsertIgnoreOnDup(c *C) { +func (s *testSuite2) TestInsertIgnoreOnDup(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") testSQL := `drop table if exists t; @@ -704,7 +704,7 @@ func (s *testSuite) TestInsertIgnoreOnDup(c *C) { r.Check(testkit.Rows("1 1", "2 2")) } -func (s *testSuite) TestReplace(c *C) { +func (s *testSuite2) TestReplace(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") testSQL := `drop table if exists replace_test; @@ -855,7 +855,7 @@ func (s *testSuite) TestReplace(c *C) { tk.CheckLastMessage("Records: 1 Duplicates: 1 Warnings: 0") } -func (s *testSuite) TestPartitionedTableReplace(c *C) { +func (s *testSuite2) TestPartitionedTableReplace(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") testSQL := `drop table if exists replace_test; @@ -994,7 +994,7 @@ func (s *testSuite) TestPartitionedTableReplace(c *C) { r.Check(testkit.Rows("111 2")) } -func (s *testSuite) TestHashPartitionedTableReplace(c *C) { +func (s *testSuite2) TestHashPartitionedTableReplace(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("set @@session.tidb_enable_table_partition = '1';") @@ -1304,7 +1304,7 @@ func (s *testSuite) TestUpdate(c *C) { tk.MustExec("set @@sql_mode=@orig_sql_mode;") } -func (s *testSuite) TestPartitionedTableUpdate(c *C) { +func (s *testSuite2) TestPartitionedTableUpdate(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -1412,7 +1412,7 @@ func (s *testSuite) TestPartitionedTableUpdate(c *C) { } // TestUpdateCastOnlyModifiedValues for issue #4514. -func (s *testSuite) TestUpdateCastOnlyModifiedValues(c *C) { +func (s *testSuite2) TestUpdateCastOnlyModifiedValues(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table update_modified (col_1 int, col_2 enum('a', 'b'))") @@ -1447,7 +1447,7 @@ func (s *testSuite) TestUpdateCastOnlyModifiedValues(c *C) { r.Check(testkit.Rows(`{"a": "测试"}`)) } -func (s *testSuite) fillMultiTableForUpdate(tk *testkit.TestKit) { +func (s *testSuite2) fillMultiTableForUpdate(tk *testkit.TestKit) { // Create and fill table items tk.MustExec("CREATE TABLE items (id int, price TEXT);") tk.MustExec(`insert into items values (11, "items_price_11"), (12, "items_price_12"), (13, "items_price_13");`) @@ -1458,7 +1458,7 @@ func (s *testSuite) fillMultiTableForUpdate(tk *testkit.TestKit) { tk.CheckExecResult(3, 0) } -func (s *testSuite) TestMultipleTableUpdate(c *C) { +func (s *testSuite2) TestMultipleTableUpdate(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") s.fillMultiTableForUpdate(tk) @@ -1561,7 +1561,7 @@ func (s *testSuite) TestDelete(c *C) { tk.CheckExecResult(1, 0) } -func (s *testSuite) TestPartitionedTableDelete(c *C) { +func (s *testSuite2) TestPartitionedTableDelete(c *C) { createTable := `CREATE TABLE test.t (id int not null default 1, name varchar(255), index(id)) PARTITION BY RANGE ( id ) ( PARTITION p0 VALUES LESS THAN (6), @@ -1614,7 +1614,7 @@ func (s *testSuite) TestPartitionedTableDelete(c *C) { tk.MustExec(`drop table t1;`) } -func (s *testSuite) fillDataMultiTable(tk *testkit.TestKit) { +func (s *testSuite2) fillDataMultiTable(tk *testkit.TestKit) { tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2, t3") // Create and fill table t1 @@ -1631,7 +1631,7 @@ func (s *testSuite) fillDataMultiTable(tk *testkit.TestKit) { tk.CheckExecResult(3, 0) } -func (s *testSuite) TestMultiTableDelete(c *C) { +func (s *testSuite2) TestMultiTableDelete(c *C) { tk := testkit.NewTestKit(c, s.store) s.fillDataMultiTable(tk) @@ -1643,7 +1643,7 @@ func (s *testSuite) TestMultiTableDelete(c *C) { c.Assert(r.Rows(), HasLen, 3) } -func (s *testSuite) TestQualifiedDelete(c *C) { +func (s *testSuite2) TestQualifiedDelete(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1") @@ -1679,7 +1679,7 @@ func (s *testSuite) TestQualifiedDelete(c *C) { c.Assert(err, NotNil) } -func (s *testSuite) TestLoadData(c *C) { +func (s *testSuite2) TestLoadData(c *C) { trivialMsg := "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0" tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -1845,7 +1845,7 @@ func (s *testSuite) TestLoadData(c *C) { checkCases(tests, ld, c, tk, ctx, selectSQL, deleteSQL) } -func (s *testSuite) TestLoadDataEscape(c *C) { +func (s *testSuite2) TestLoadDataEscape(c *C) { trivialMsg := "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0" tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test; drop table if exists load_data_test;") @@ -1874,7 +1874,7 @@ func (s *testSuite) TestLoadDataEscape(c *C) { } // TestLoadDataSpecifiedColumns reuse TestLoadDataEscape's test case :-) -func (s *testSuite) TestLoadDataSpecifiedColumns(c *C) { +func (s *testSuite2) TestLoadDataSpecifiedColumns(c *C) { trivialMsg := "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0" tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test; drop table if exists load_data_test;") @@ -1901,7 +1901,7 @@ func (s *testSuite) TestLoadDataSpecifiedColumns(c *C) { checkCases(tests, ld, c, tk, ctx, selectSQL, deleteSQL) } -func (s *testSuite) TestLoadDataIgnoreLines(c *C) { +func (s *testSuite2) TestLoadDataIgnoreLines(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test; drop table if exists load_data_test;") tk.MustExec("CREATE TABLE load_data_test (id INT NOT NULL PRIMARY KEY, value TEXT NOT NULL) CHARACTER SET utf8") @@ -1920,7 +1920,7 @@ func (s *testSuite) TestLoadDataIgnoreLines(c *C) { checkCases(tests, ld, c, tk, ctx, selectSQL, deleteSQL) } -func (s *testSuite) TestBatchInsertDelete(c *C) { +func (s *testSuite2) TestBatchInsertDelete(c *C) { originLimit := atomic.LoadUint64(&kv.TxnEntryCountLimit) defer func() { atomic.StoreUint64(&kv.TxnEntryCountLimit, originLimit) @@ -2037,7 +2037,7 @@ func (s *testSuite) TestBatchInsertDelete(c *C) { r.Check(testkit.Rows("0")) } -func (s *testSuite) TestNullDefault(c *C) { +func (s *testSuite2) TestNullDefault(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test; drop table if exists test_null_default;") tk.MustExec("set timestamp = 1234") @@ -2094,7 +2094,7 @@ func (s *testBypassSuite) TestLatch(c *C) { } // TestIssue4067 Test issue https://github.com/pingcap/tidb/issues/4067 -func (s *testSuite) TestIssue4067(c *C) { +func (s *testSuite2) TestIssue4067(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1, t2") @@ -2108,7 +2108,7 @@ func (s *testSuite) TestIssue4067(c *C) { tk.MustQuery("select * from t1").Check(nil) } -func (s *testSuite) TestInsertCalculatedValue(c *C) { +func (s *testSuite2) TestInsertCalculatedValue(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -2224,7 +2224,7 @@ func (s *testSuite) TestInsertCalculatedValue(c *C) { tk.MustQuery("select * from t").Check(testkit.Rows("4 0 2")) } -func (s *testSuite) TestDataTooLongErrMsg(c *C) { +func (s *testSuite2) TestDataTooLongErrMsg(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table t(a varchar(2));") @@ -2237,7 +2237,7 @@ func (s *testSuite) TestDataTooLongErrMsg(c *C) { c.Assert(err.Error(), Equals, "[types:1406]Data too long for column 'a' at row 1") } -func (s *testSuite) TestUpdateSelect(c *C) { +func (s *testSuite2) TestUpdateSelect(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table msg (id varchar(8), b int, status int, primary key (id, b))") @@ -2249,7 +2249,7 @@ func (s *testSuite) TestUpdateSelect(c *C) { tk.MustExec("admin check table msg") } -func (s *testSuite) TestUpdateDelete(c *C) { +func (s *testSuite2) TestUpdateDelete(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("CREATE TABLE ttt (id bigint(20) NOT NULL, host varchar(30) NOT NULL, PRIMARY KEY (id), UNIQUE KEY i_host (host));") @@ -2269,7 +2269,7 @@ func (s *testSuite) TestUpdateDelete(c *C) { tk.MustExec("drop table ttt") } -func (s *testSuite) TestUpdateAffectRowCnt(c *C) { +func (s *testSuite2) TestUpdateAffectRowCnt(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table a(id int auto_increment, a int default null, primary key(id))") @@ -2288,7 +2288,7 @@ func (s *testSuite) TestUpdateAffectRowCnt(c *C) { tk.CheckLastMessage("Rows matched: 2 Changed: 2 Warnings: 0") } -func (s *testSuite) TestReplaceLog(c *C) { +func (s *testSuite2) TestReplaceLog(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec(`create table testLog (a int not null primary key, b int unique key);`) @@ -2323,7 +2323,7 @@ func (s *testSuite) TestReplaceLog(c *C) { // TestRebaseIfNeeded is for issue 7422. // There is no need to do the rebase when updating a record if the auto-increment ID not changed. // This could make the auto ID increasing speed slower. -func (s *testSuite) TestRebaseIfNeeded(c *C) { +func (s *testSuite2) TestRebaseIfNeeded(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec(`create table t (a int not null primary key auto_increment, b int unique key);`) @@ -2355,7 +2355,7 @@ func (s *testSuite) TestRebaseIfNeeded(c *C) { tk.MustQuery(`select a from t where b = 6;`).Check(testkit.Rows("30003")) } -func (s *testSuite) TestDeferConstraintCheckForInsert(c *C) { +func (s *testSuite2) TestDeferConstraintCheckForInsert(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec(`use test`) tk.MustExec(`drop table if exists t;create table t (i int key);`) @@ -2369,7 +2369,7 @@ func (s *testSuite) TestDeferConstraintCheckForInsert(c *C) { tk.MustQuery(`select * from t;`).Check(testkit.Rows("2")) } -func (s *testSuite) TestDefEnumInsert(c *C) { +func (s *testSuite2) TestDefEnumInsert(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("create table test (id int, prescription_type enum('a','b','c','d','e','f') NOT NULL, primary key(id));") diff --git a/privilege/privileges/privileges_test.go b/privilege/privileges/privileges_test.go index b0a6ebb543320..3dec73867a627 100644 --- a/privilege/privileges/privileges_test.go +++ b/privilege/privileges/privileges_test.go @@ -243,6 +243,7 @@ func (s *testPrivilegeSuite) TestShowGrants(c *C) { // This should now return an error gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}) + c.Assert(err, NotNil) // cant show grants for non-existent errNonexistingGrant := terror.ClassPrivilege.New(mysql.ErrNonexistingGrant, mysql.MySQLErrName[mysql.ErrNonexistingGrant]) c.Assert(terror.ErrorEqual(err, errNonexistingGrant), IsTrue) diff --git a/sessionctx/variable/varsutil_test.go b/sessionctx/variable/varsutil_test.go index e109a76987879..8fcf3c4d15f92 100644 --- a/sessionctx/variable/varsutil_test.go +++ b/sessionctx/variable/varsutil_test.go @@ -106,11 +106,13 @@ func (s *testVarsutilSuite) TestVarsutil(c *C) { // 0 converts to OFF SetSessionSystemVar(v, "foreign_key_checks", types.NewStringDatum("0")) val, err = GetSessionSystemVar(v, "foreign_key_checks") + c.Assert(err, IsNil) c.Assert(val, Equals, "OFF") // 1/ON is not supported (generates a warning and sets to OFF) SetSessionSystemVar(v, "foreign_key_checks", types.NewStringDatum("1")) val, err = GetSessionSystemVar(v, "foreign_key_checks") + c.Assert(err, IsNil) c.Assert(val, Equals, "OFF") SetSessionSystemVar(v, "sql_mode", types.NewStringDatum("strict_trans_tables")) diff --git a/store/tikv/gcworker/gc_worker_test.go b/store/tikv/gcworker/gc_worker_test.go index 8c7720acfe201..1bf14628ba45b 100644 --- a/store/tikv/gcworker/gc_worker_test.go +++ b/store/tikv/gcworker/gc_worker_test.go @@ -86,6 +86,7 @@ func (s *testGCWorkerSuite) TestPrepareGC(c *C) { close(s.gcWorker.done) ok, _, err := s.gcWorker.prepare() c.Assert(err, IsNil) + c.Assert(ok, IsFalse) lastRun, err := s.gcWorker.loadTime(gcLastRunTimeKey) c.Assert(err, IsNil) c.Assert(lastRun, NotNil) diff --git a/table/tables/tables.go b/table/tables/tables.go index 0945aa87f29a0..356099ac08b85 100644 --- a/table/tables/tables.go +++ b/table/tables/tables.go @@ -949,6 +949,9 @@ func (t *tableCommon) Seek(ctx sessionctx.Context, h int64) (int64, bool, error) } seekKey := tablecodec.EncodeRowKeyWithHandle(t.physicalTableID, h) iter, err := txn.Iter(seekKey, t.RecordPrefix().PrefixNext()) + if err != nil { + return 0, false, errors.Trace(err) + } if !iter.Valid() || !iter.Key().HasPrefix(t.RecordPrefix()) { // No more records in the table, skip to the end. return 0, false, nil diff --git a/util/admin/admin_test.go b/util/admin/admin_test.go index 3447647e6b74c..e4da87fa9a806 100644 --- a/util/admin/admin_test.go +++ b/util/admin/admin_test.go @@ -331,10 +331,10 @@ func (s *testSuite) TestScan(c *C) { idxRow2 := &RecordData{Handle: int64(2), Values: types.MakeDatums(int64(20))} kvIndex := tables.NewIndex(tb.Meta().ID, tb.Meta(), indices[0].Meta()) sc := &stmtctx.StatementContext{TimeZone: time.Local} - idxRows, nextVals, err := ScanIndexData(sc, txn, kvIndex, idxRow1.Values, 2) + idxRows, _, err := ScanIndexData(sc, txn, kvIndex, idxRow1.Values, 2) c.Assert(err, IsNil) c.Assert(idxRows, DeepEquals, []*RecordData{idxRow1, idxRow2}) - idxRows, nextVals, err = ScanIndexData(sc, txn, kvIndex, idxRow1.Values, 1) + idxRows, nextVals, err := ScanIndexData(sc, txn, kvIndex, idxRow1.Values, 1) c.Assert(err, IsNil) c.Assert(idxRows, DeepEquals, []*RecordData{idxRow1}) idxRows, nextVals, err = ScanIndexData(sc, txn, kvIndex, nextVals, 1) diff --git a/util/ranger/detacher.go b/util/ranger/detacher.go index f020a24b0e446..0ab586b53eafe 100644 --- a/util/ranger/detacher.go +++ b/util/ranger/detacher.go @@ -331,7 +331,7 @@ func DetachSimpleCondAndBuildRangeForIndex(sctx sessionctx.Context, conditions [ newTpSlice = append(newTpSlice, newFieldType(col.RetType)) } ranges, accessConds, _, _, err = detachCNFCondAndBuildRangeForIndex(sctx, conditions, cols, newTpSlice, lengths, false) - return ranges, accessConds, nil + return ranges, accessConds, errors.Trace(err) } func removeAccessConditions(conditions, accessConds []expression.Expression) []expression.Expression { diff --git a/util/testkit/testkit.go b/util/testkit/testkit.go index 221f1bff5ae2e..f8a023e3cf943 100644 --- a/util/testkit/testkit.go +++ b/util/testkit/testkit.go @@ -185,6 +185,15 @@ func (tk *TestKit) MustQuery(sql string, args ...interface{}) *Result { return tk.ResultSetToResult(rs, comment) } +// ExecToErr executes a sql statement and discard results. +func (tk *TestKit) ExecToErr(sql string, args ...interface{}) error { + res, err := tk.Exec(sql, args...) + if res != nil { + tk.c.Assert(res.Close(), check.IsNil) + } + return err +} + // ResultSetToResult converts sqlexec.RecordSet to testkit.Result. // It is used to check results of execute statement in binary mode. func (tk *TestKit) ResultSetToResult(rs sqlexec.RecordSet, comment check.CommentInterface) *Result {