// Copyright 2020 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, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ddl_test import ( "context" "fmt" "sort" . "github.com/pingcap/check" "github.com/pingcap/failpoint" "github.com/pingcap/tidb/ddl/placement" mysql "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/util/testkit" "github.com/pingcap/tidb/util/testutil" ) // TODO: Remove in https://github.com/pingcap/tidb/issues/27971 or change to use SQL PLACEMENT POLICY func (s *testDBSuite1) TestPlacementPolicyCache(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.Se.GetSessionVars().EnableAlterPlacement = true tk.MustExec("set @@tidb_enable_exchange_partition = 1") defer func() { tk.MustExec("set @@tidb_enable_exchange_partition = 0") tk.MustExec("drop table if exists t1") tk.MustExec("drop table if exists t2") tk.Se.GetSessionVars().EnableAlterPlacement = false }() initTable := func() []string { tk.MustExec("drop table if exists t2") tk.MustExec("drop table if exists t1") tk.MustExec(`create table t1(id int) partition by range(id) (partition p0 values less than (100), partition p1 values less than (200))`) is := s.dom.InfoSchema() tb, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) c.Assert(err, IsNil) partDefs := tb.Meta().GetPartitionInfo().Definitions sort.Slice(partDefs, func(i, j int) bool { return partDefs[i].Name.L < partDefs[j].Name.L }) rows := []string{} for k, v := range partDefs { ptID := placement.GroupID(v.ID) is.SetBundle(&placement.Bundle{ ID: ptID, Rules: []*placement.Rule{{Count: k}}, }) rows = append(rows, fmt.Sprintf("%s 0 test t1 %s %d ", ptID, v.Name.L, k)) } return rows } // test drop _ = initTable() //tk.MustQuery("select * from information_schema.placement_policy order by REPLICAS").Check(testkit.Rows(rows...)) tk.MustExec("alter table t1 drop partition p0") //tk.MustQuery("select * from information_schema.placement_policy").Check(testkit.Rows(rows[1:]...)) _ = initTable() //tk.MustQuery("select * from information_schema.placement_policy order by REPLICAS").Check(testkit.Rows(rows...)) tk.MustExec("drop table t1") //tk.MustQuery("select * from information_schema.placement_policy").Check(testkit.Rows()) // test truncate _ = initTable() //tk.MustQuery("select * from information_schema.placement_policy order by REPLICAS").Check(testkit.Rows(rows...)) tk.MustExec("alter table t1 truncate partition p0") //tk.MustQuery("select * from information_schema.placement_policy").Check(testkit.Rows(rows[1:]...)) _ = initTable() //tk.MustQuery("select * from information_schema.placement_policy order by REPLICAS").Check(testkit.Rows(rows...)) tk.MustExec("truncate table t1") //tk.MustQuery("select * from information_schema.placement_policy").Check(testkit.Rows()) // test exchange _ = initTable() //tk.MustQuery("select * from information_schema.placement_policy order by REPLICAS").Check(testkit.Rows(rows...)) tk.MustExec("create table t2(id int)") tk.MustExec("alter table t1 exchange partition p0 with table t2") //tk.MustQuery("select * from information_schema.placement_policy").Check(testkit.Rows()) } func (s *testSerialDBSuite) TestTxnScopeConstraint(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") tk.MustExec("drop table if exists t1") tk.Se.GetSessionVars().EnableAlterPlacement = true defer func() { tk.MustExec("drop table if exists t1") tk.Se.GetSessionVars().EnableAlterPlacement = false }() tk.MustExec(`create table t1 (c int) PARTITION BY RANGE (c) ( PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11), PARTITION p2 VALUES LESS THAN (16), PARTITION p3 VALUES LESS THAN (21) );`) is := s.dom.InfoSchema() tb, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) c.Assert(err, IsNil) partDefs := tb.Meta().GetPartitionInfo().Definitions for _, def := range partDefs { if def.Name.String() == "p0" { groupID := placement.GroupID(def.ID) is.SetBundle(&placement.Bundle{ ID: groupID, Rules: []*placement.Rule{ { GroupID: groupID, Role: placement.Leader, Count: 1, Constraints: []placement.Constraint{ { Key: placement.DCLabelKey, Op: placement.In, Values: []string{"sh"}, }, }, }, }, }) } else if def.Name.String() == "p2" { groupID := placement.GroupID(def.ID) is.SetBundle(&placement.Bundle{ ID: groupID, Rules: []*placement.Rule{ { GroupID: groupID, Role: placement.Follower, Count: 3, Constraints: []placement.Constraint{ { Key: placement.DCLabelKey, Op: placement.In, Values: []string{"sh"}, }, }, }, }, }) } } testCases := []struct { name string sql string txnScope string zone string disableAutoCommit bool err error }{ { name: "Insert into PARTITION p0 with global txnScope", sql: "insert into t1 (c) values (1)", txnScope: "global", zone: "", err: nil, }, { name: "insert into PARTITION p0 with wrong txnScope", sql: "insert into t1 (c) values (1)", txnScope: "local", zone: "bj", err: fmt.Errorf(".*out of txn_scope.*"), }, { name: "insert into PARTITION p1 with local txnScope", sql: "insert into t1 (c) values (10)", txnScope: "local", zone: "bj", err: fmt.Errorf(".*doesn't have placement policies with txn_scope.*"), }, { name: "insert into PARTITION p1 with global txnScope", sql: "insert into t1 (c) values (10)", txnScope: "global", err: nil, }, { name: "insert into PARTITION p2 with local txnScope", sql: "insert into t1 (c) values (15)", txnScope: "local", zone: "bj", err: fmt.Errorf(".*leader placement policy is not defined.*"), }, { name: "insert into PARTITION p2 with global txnScope", sql: "insert into t1 (c) values (15)", txnScope: "global", zone: "", err: nil, }, { name: "insert into PARTITION p0 with wrong txnScope and autocommit off", sql: "insert into t1 (c) values (1)", txnScope: "local", zone: "bj", disableAutoCommit: true, err: fmt.Errorf(".*out of txn_scope.*"), }, } for _, testcase := range testCases { c.Log(testcase.name) failpoint.Enable("tikvclient/injectTxnScope", fmt.Sprintf(`return("%v")`, testcase.zone)) se, err := session.CreateSession4Test(s.store) c.Check(err, IsNil) tk.Se = se tk.MustExec("use test") tk.MustExec("set global tidb_enable_local_txn = on;") tk.MustExec(fmt.Sprintf("set @@txn_scope = %v", testcase.txnScope)) if testcase.disableAutoCommit { tk.MustExec("set @@autocommit = 0") tk.MustExec("begin") tk.MustExec(testcase.sql) _, err = tk.Exec("commit") } else { _, err = tk.Exec(testcase.sql) } if testcase.err == nil { c.Assert(err, IsNil) } else { c.Assert(err, NotNil) c.Assert(err.Error(), Matches, testcase.err.Error()) } tk.MustExec("set global tidb_enable_local_txn = off;") failpoint.Disable("tikvclient/injectTxnScope") } } func (s *testDBSuite6) TestCreateSchemaWithPlacement(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("drop schema if exists SchemaDirectPlacementTest") tk.MustExec("drop schema if exists SchemaPolicyPlacementTest") tk.Se.GetSessionVars().EnableAlterPlacement = true defer func() { tk.MustExec("drop schema if exists SchemaDirectPlacementTest") tk.MustExec("drop schema if exists SchemaPolicyPlacementTest") tk.MustExec("drop placement policy if exists PolicySchemaTest") tk.MustExec("drop placement policy if exists PolicyTableTest") tk.Se.GetSessionVars().EnableAlterPlacement = false }() tk.MustExec(`CREATE SCHEMA SchemaDirectPlacementTest PRIMARY_REGION='nl' REGIONS = "se,nz,nl" FOLLOWERS=3`) tk.MustQuery("SHOW CREATE SCHEMA schemadirectplacementtest").Check(testkit.Rows("SchemaDirectPlacementTest CREATE DATABASE `SchemaDirectPlacementTest` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ /*T![placement] PRIMARY_REGION=\"nl\" REGIONS=\"se,nz,nl\" FOLLOWERS=3 */")) tk.MustQuery("SELECT * FROM information_schema.placement_rules WHERE SCHEMA_NAME='SchemaDirectPlacementTest'").Check(testkit.Rows(" def SchemaDirectPlacementTest nl se,nz,nl 3 0")) tk.MustExec(`CREATE PLACEMENT POLICY PolicySchemaTest LEADER_CONSTRAINTS = "[+region=nl]" FOLLOWER_CONSTRAINTS="[+region=se]" FOLLOWERS=4 LEARNER_CONSTRAINTS="[+region=be]" LEARNERS=4`) tk.MustExec(`CREATE PLACEMENT POLICY PolicyTableTest LEADER_CONSTRAINTS = "[+region=tl]" FOLLOWER_CONSTRAINTS="[+region=tf]" FOLLOWERS=2 LEARNER_CONSTRAINTS="[+region=tle]" LEARNERS=1`) tk.MustQuery("SHOW PLACEMENT like 'POLICY %PolicySchemaTest%'").Check(testkit.Rows("POLICY PolicySchemaTest LEADER_CONSTRAINTS=\"[+region=nl]\" FOLLOWERS=4 FOLLOWER_CONSTRAINTS=\"[+region=se]\" LEARNERS=4 LEARNER_CONSTRAINTS=\"[+region=be]\" NULL")) tk.MustQuery("SHOW PLACEMENT like 'POLICY %PolicyTableTest%'").Check(testkit.Rows("POLICY PolicyTableTest LEADER_CONSTRAINTS=\"[+region=tl]\" FOLLOWERS=2 FOLLOWER_CONSTRAINTS=\"[+region=tf]\" LEARNERS=1 LEARNER_CONSTRAINTS=\"[+region=tle]\" NULL")) tk.MustExec("CREATE SCHEMA SchemaPolicyPlacementTest PLACEMENT POLICY = `PolicySchemaTest`") tk.MustQuery("SHOW CREATE SCHEMA SCHEMAPOLICYPLACEMENTTEST").Check(testkit.Rows("SchemaPolicyPlacementTest CREATE DATABASE `SchemaPolicyPlacementTest` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ /*T![placement] PLACEMENT POLICY=`PolicySchemaTest` */")) tk.MustExec(`CREATE TABLE SchemaDirectPlacementTest.UseSchemaDefault (a int unsigned primary key, b varchar(255))`) tk.MustQuery(`SHOW CREATE TABLE SchemaDirectPlacementTest.UseSchemaDefault`).Check(testkit.Rows( "UseSchemaDefault CREATE TABLE `UseSchemaDefault` (\n" + " `a` int(10) unsigned NOT NULL,\n" + " `b` varchar(255) DEFAULT NULL,\n" + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PRIMARY_REGION=\"nl\" REGIONS=\"se,nz,nl\" FOLLOWERS=3 */")) tk.MustQuery("SELECT CATALOG_NAME, SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.schemata WHERE SCHEMA_NAME='SchemaDirectPlacementTest'").Check(testkit.Rows(`def SchemaDirectPlacementTest utf8mb4 utf8mb4_bin PRIMARY_REGION="nl" REGIONS="se,nz,nl" FOLLOWERS=3`)) tk.MustQuery("SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.Tables WHERE TABLE_SCHEMA='SchemaDirectPlacementTest' AND TABLE_NAME = 'UseSchemaDefault'").Check(testkit.Rows(`def SchemaDirectPlacementTest UseSchemaDefault PRIMARY_REGION="nl" REGIONS="se,nz,nl" FOLLOWERS=3`)) tk.MustExec(`CREATE TABLE SchemaDirectPlacementTest.UseDirectPlacement (a int unsigned primary key, b varchar(255)) PRIMARY_REGION="se" REGIONS="se"`) tk.MustQuery(`SHOW CREATE TABLE SchemaDirectPlacementTest.UseDirectPlacement`).Check(testkit.Rows( "UseDirectPlacement CREATE TABLE `UseDirectPlacement` (\n" + " `a` int(10) unsigned NOT NULL,\n" + " `b` varchar(255) DEFAULT NULL,\n" + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PRIMARY_REGION=\"se\" REGIONS=\"se\" */")) tk.MustQuery("SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.Tables WHERE TABLE_SCHEMA='SchemaDirectPlacementTest' AND TABLE_NAME = 'UseDirectPlacement'").Check(testkit.Rows("def SchemaDirectPlacementTest UseDirectPlacement PRIMARY_REGION=\"se\" REGIONS=\"se\"")) tk.MustExec(`CREATE TABLE SchemaPolicyPlacementTest.UseSchemaDefault (a int unsigned primary key, b varchar(255))`) tk.MustQuery(`SHOW CREATE TABLE SchemaPolicyPlacementTest.UseSchemaDefault`).Check(testkit.Rows( "UseSchemaDefault CREATE TABLE `UseSchemaDefault` (\n" + " `a` int(10) unsigned NOT NULL,\n" + " `b` varchar(255) DEFAULT NULL,\n" + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`PolicySchemaTest` */")) tk.MustQuery("SELECT CATALOG_NAME, SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.schemata WHERE SCHEMA_NAME='SchemaPolicyPlacementTest'").Check(testkit.Rows(`def SchemaPolicyPlacementTest utf8mb4 utf8mb4_bin PolicySchemaTest `)) tk.MustQuery("SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.Tables WHERE TABLE_SCHEMA='SchemaPolicyPlacementTest' AND TABLE_NAME = 'UseSchemaDefault'").Check(testkit.Rows(`def SchemaPolicyPlacementTest UseSchemaDefault PolicySchemaTest `)) tk.MustExec(`CREATE TABLE SchemaPolicyPlacementTest.UsePolicy (a int unsigned primary key, b varchar(255)) PLACEMENT POLICY = "PolicyTableTest"`) tk.MustQuery(`SHOW CREATE TABLE SchemaPolicyPlacementTest.UsePolicy`).Check(testkit.Rows( "UsePolicy CREATE TABLE `UsePolicy` (\n" + " `a` int(10) unsigned NOT NULL,\n" + " `b` varchar(255) DEFAULT NULL,\n" + " PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`PolicyTableTest` */")) tk.MustQuery("SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.Tables WHERE TABLE_SCHEMA='SchemaPolicyPlacementTest' AND TABLE_NAME = 'UsePolicy'").Check(testkit.Rows(`def SchemaPolicyPlacementTest UsePolicy PolicyTableTest `)) is := s.dom.InfoSchema() db, ok := is.SchemaByName(model.NewCIStr("SchemaDirectPlacementTest")) c.Assert(ok, IsTrue) c.Assert(db.PlacementPolicyRef, IsNil) c.Assert(db.DirectPlacementOpts, NotNil) c.Assert(db.DirectPlacementOpts.PrimaryRegion, Matches, "nl") c.Assert(db.DirectPlacementOpts.Regions, Matches, "se,nz,nl") c.Assert(db.DirectPlacementOpts.Followers, Equals, uint64(3)) c.Assert(db.DirectPlacementOpts.Learners, Equals, uint64(0)) db, ok = is.SchemaByName(model.NewCIStr("SchemaPolicyPlacementTest")) c.Assert(ok, IsTrue) c.Assert(db.PlacementPolicyRef, NotNil) c.Assert(db.DirectPlacementOpts, IsNil) c.Assert(db.PlacementPolicyRef.Name.O, Equals, "PolicySchemaTest") } func (s *testDBSuite6) TestAlterDBPlacement(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("drop database if exists TestAlterDB;") tk.MustExec("create database TestAlterDB;") tk.MustExec("use TestAlterDB") tk.MustExec("drop placement policy if exists alter_x") tk.MustExec("drop placement policy if exists alter_y") tk.MustExec("create placement policy alter_x PRIMARY_REGION=\"cn-east-1\", REGIONS=\"cn-east-1\";") defer tk.MustExec("drop placement policy if exists alter_x") tk.MustExec("create placement policy alter_y PRIMARY_REGION=\"cn-east-2\", REGIONS=\"cn-east-2\";") defer tk.MustExec("drop placement policy if exists alter_y") defer tk.MustExec(`DROP DATABASE IF EXISTS TestAlterDB;`) // Must drop tables before policy // Policy Test // Test for Non-Exist policy tk.MustGetErrCode("ALTER DATABASE TestAlterDB PLACEMENT POLICY=`alter_z`;", mysql.ErrPlacementPolicyNotExists) tk.MustQuery("SELECT CATALOG_NAME, SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.schemata WHERE SCHEMA_NAME='TestAlterDB'").Check(testkit.Rows(`def TestAlterDB utf8mb4 utf8mb4_bin `)) tk.MustExec("ALTER DATABASE TestAlterDB PLACEMENT POLICY=`alter_x`;") // Test for information_schema.schemata tk.MustQuery("SELECT CATALOG_NAME, SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.schemata WHERE SCHEMA_NAME='TestAlterDB'").Check(testkit.Rows(`def TestAlterDB utf8mb4 utf8mb4_bin alter_x `)) // Test for Show Create Database tk.MustQuery(`show create database TestAlterDB`).Check(testutil.RowsWithSep("|", "TestAlterDB CREATE DATABASE `TestAlterDB` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ "+ "/*T![placement] PLACEMENT POLICY=`alter_x` */", )) // Test for Alter Placement Policy affect table created. tk.MustExec("create table t(a int);") 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 "+ "/*T![placement] PLACEMENT POLICY=`alter_x` */", )) tk.MustQuery("SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.Tables WHERE TABLE_SCHEMA='TestAlterDB' AND TABLE_NAME = 't'").Check(testkit.Rows(`def TestAlterDB t alter_x `)) // Test for Alter Default Placement Policy, And will not update the old table options. tk.MustExec("ALTER DATABASE TestAlterDB DEFAULT PLACEMENT POLICY=`alter_y`;") tk.MustExec("create table t2(a int);") 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 "+ "/*T![placement] PLACEMENT POLICY=`alter_x` */", )) tk.MustQuery(`show create table t2`).Check(testutil.RowsWithSep("|", "t2 CREATE TABLE `t2` (\n"+ " `a` int(11) DEFAULT NULL\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin "+ "/*T![placement] PLACEMENT POLICY=`alter_y` */", )) tk.MustQuery("SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.Tables WHERE TABLE_SCHEMA='TestAlterDB' AND TABLE_NAME = 't2'").Check(testkit.Rows(`def TestAlterDB t2 alter_y `)) // Reset Test tk.MustExec("drop database if exists TestAlterDB;") tk.MustExec("create database TestAlterDB;") tk.MustExec("use TestAlterDB") // DirectOption Test tk.MustExec("ALTER DATABASE TestAlterDB PRIMARY_REGION=\"se\" FOLLOWERS=2 REGIONS=\"se\";") // Test for information_schema.schemata tk.MustQuery("SELECT CATALOG_NAME, SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.schemata WHERE SCHEMA_NAME='TestAlterDB'").Check(testkit.Rows(`def TestAlterDB utf8mb4 utf8mb4_bin PRIMARY_REGION="se" REGIONS="se" FOLLOWERS=2`)) // Test for Show Create Database tk.MustQuery(`show create database TestAlterDB`).Check(testutil.RowsWithSep("|", "TestAlterDB CREATE DATABASE `TestAlterDB` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ "+ "/*T![placement] PRIMARY_REGION=\"se\" REGIONS=\"se\" FOLLOWERS=2 */", )) // Test for Alter Placement Rule affect table created. tk.MustExec("create table t3(a int);") tk.MustQuery(`show create table t3`).Check(testutil.RowsWithSep("|", "t3 CREATE TABLE `t3` (\n"+ " `a` int(11) DEFAULT NULL\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin "+ "/*T![placement] PRIMARY_REGION=\"se\" REGIONS=\"se\" FOLLOWERS=2 */", )) tk.MustQuery("SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.Tables WHERE TABLE_SCHEMA='TestAlterDB' AND TABLE_NAME = 't3'").Check(testkit.Rows("def TestAlterDB t3 PRIMARY_REGION=\"se\" REGIONS=\"se\" FOLLOWERS=2")) // Test for override default option tk.MustExec("create table t4(a int) PLACEMENT POLICY=\"alter_x\";") tk.MustQuery(`show create table t4`).Check(testutil.RowsWithSep("|", "t4 CREATE TABLE `t4` (\n"+ " `a` int(11) DEFAULT NULL\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin "+ "/*T![placement] PLACEMENT POLICY=`alter_x` */", )) tk.MustQuery("SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TIDB_PLACEMENT_POLICY_NAME, TIDB_DIRECT_PLACEMENT FROM information_schema.Tables WHERE TABLE_SCHEMA='TestAlterDB' AND TABLE_NAME = 't4'").Check(testkit.Rows(`def TestAlterDB t4 alter_x `)) // Hybrid Test // Test for alter both policy and direct options. tk.MustQuery(`show create database TestAlterDB`).Check(testutil.RowsWithSep("|", "TestAlterDB CREATE DATABASE `TestAlterDB` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ "+ "/*T![placement] PRIMARY_REGION=\"se\" REGIONS=\"se\" FOLLOWERS=2 */", )) tk.MustGetErrCode("ALTER DATABASE TestAlterDB PLACEMENT POLICY=`alter_x` FOLLOWERS=2;", mysql.ErrPlacementPolicyWithDirectOption) tk.MustGetErrCode("ALTER DATABASE TestAlterDB DEFAULT PLACEMENT POLICY=`alter_y` PRIMARY_REGION=\"se\" FOLLOWERS=2;", mysql.ErrPlacementPolicyWithDirectOption) tk.MustQuery(`show create database TestAlterDB`).Check(testutil.RowsWithSep("|", "TestAlterDB CREATE DATABASE `TestAlterDB` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ "+ "/*T![placement] PRIMARY_REGION=\"se\" REGIONS=\"se\" FOLLOWERS=2 */", )) // Test for change direct options to policy. tk.MustExec("ALTER DATABASE TestAlterDB PLACEMENT POLICY=`alter_x`;") tk.MustQuery(`show create database TestAlterDB`).Check(testutil.RowsWithSep("|", "TestAlterDB CREATE DATABASE `TestAlterDB` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ "+ "/*T![placement] PLACEMENT POLICY=`alter_x` */", )) // Test for change policy to direct options. tk.MustExec("ALTER DATABASE TestAlterDB PRIMARY_REGION=\"se\" FOLLOWERS=2 REGIONS=\"se\" ;") tk.MustQuery(`show create database TestAlterDB`).Check(testutil.RowsWithSep("|", "TestAlterDB CREATE DATABASE `TestAlterDB` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ "+ "/*T![placement] PRIMARY_REGION=\"se\" REGIONS=\"se\" FOLLOWERS=2 */", )) } func (s *testDBSuite6) TestEnablePlacementCheck(c *C) { tk := testkit.NewTestKit(c, s.store) se, err := session.CreateSession4Test(s.store) c.Assert(err, IsNil) _, err = se.Execute(context.Background(), "set @@global.tidb_enable_alter_placement=1") c.Assert(err, IsNil) tk.MustExec("drop database if exists TestPlacementDB;") tk.MustExec("create database TestPlacementDB;") tk.MustExec("use TestPlacementDB;") tk.MustExec("drop placement policy if exists placement_x;") tk.MustExec("create placement policy placement_x PRIMARY_REGION=\"cn-east-1\", REGIONS=\"cn-east-1\";") se.GetSessionVars().EnableAlterPlacement = true tk.MustExec("create table t(c int) partition by range (c) (partition p1 values less than (200) followers=2);") defer func() { tk.MustExec("drop database if exists TestPlacementDB;") tk.MustExec("drop placement policy if exists placement_x;") }() tk.Se.GetSessionVars().EnableAlterPlacement = false tk.MustGetErrCode("create database TestPlacementDB2 followers=2;", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter database TestPlacementDB placement policy=placement_x", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("create table t (c int) FOLLOWERS=2;", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t voters=2;", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("create table m (c int) partition by range (c) (partition p1 values less than (200) followers=2);", mysql.ErrUnsupportedDDLOperation) tk.MustGetErrCode("alter table t partition p1 placement policy=\"placement_x\";", mysql.ErrUnsupportedDDLOperation) }