diff --git a/ddl/db_partition_test.go b/ddl/db_partition_test.go index da187483e8ea6..647c421ab6b0d 100644 --- a/ddl/db_partition_test.go +++ b/ddl/db_partition_test.go @@ -224,7 +224,7 @@ func (s *testIntegrationSuite3) TestCreateTableWithPartition(c *C) { partition p0 values less than (to_seconds('2004-01-01')), partition p1 values less than (to_seconds('2005-01-01')));`) tk.MustQuery("show create table t26").Check( - testkit.Rows("t26 CREATE TABLE `t26` (\n `a` date DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\nPARTITION BY RANGE ( TO_SECONDS(`a`) ) (\n PARTITION `p0` VALUES LESS THAN (63240134400),\n PARTITION `p1` VALUES LESS THAN (63271756800)\n)")) + testkit.Rows("t26 CREATE TABLE `t26` (\n `a` date DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\nPARTITION BY RANGE (TO_SECONDS(`a`))\n(PARTITION `p0` VALUES LESS THAN (63240134400),\n PARTITION `p1` VALUES LESS THAN (63271756800))")) tk.MustExec(`create table t27 (a bigint unsigned not null) partition by range(a) ( partition p0 values less than (10), diff --git a/ddl/partition.go b/ddl/partition.go index 9b13710e87709..ef81b7da5b371 100644 --- a/ddl/partition.go +++ b/ddl/partition.go @@ -491,6 +491,9 @@ func buildHashPartitionDefinitions(_ sessionctx.Context, defs []*ast.PartitionDe def := defs[i] definitions[i].Name = def.Name definitions[i].Comment, _ = def.Comment() + if err := setPartitionPlacementFromOptions(&definitions[i], def.Options); err != nil { + return nil, err + } } } return definitions, nil diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index 546b0bb5c7023..f4c4eb54e69b3 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -250,9 +250,9 @@ func (s *testDBSuite6) TestSkipPlacementValidation(c *C) { tk.MustQuery("show create table t_range_p").Check(testkit.Rows("t_range_p CREATE TABLE `t_range_p` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`y` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n)", + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000))", )) // Test for `ALTER` @@ -273,17 +273,17 @@ func (s *testDBSuite6) TestSkipPlacementValidation(c *C) { tk.MustQuery("show create table t_range_p").Check(testkit.Rows("t_range_p CREATE TABLE `t_range_p` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`y` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`y` */\n)", + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`y` */)", )) tk.MustExec("alter table t_range_p PARTITION p1 placement policy x;") tk.MustQuery("show create table t_range_p").Check(testkit.Rows("t_range_p CREATE TABLE `t_range_p` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`y` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`y` */\n)", + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`y` */)", )) tk.MustExec("SET PLACEMENT_CHECKS = 1;") @@ -921,10 +921,9 @@ func (s *testDBSuite6) TestPolicyInheritance(c *C) { tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" + " `a` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] CONSTRAINTS=\"[+zone=hangzhou]\" */\n" + - "PARTITION BY RANGE ( `a` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (200)\n" + - ")")) + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (200))")) tk.MustExec("drop table if exists t") // partition's specified placement rules will override the default one. @@ -932,10 +931,9 @@ func (s *testDBSuite6) TestPolicyInheritance(c *C) { tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" + " `a` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] CONSTRAINTS=\"[+zone=hangzhou]\" */\n" + - "PARTITION BY RANGE ( `a` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100) /*T![placement] CONSTRAINTS=\"[+zone=suzhou]\" */,\n" + - " PARTITION `p1` VALUES LESS THAN (200)\n" + - ")")) + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100) /*T![placement] CONSTRAINTS=\"[+zone=suzhou]\" */,\n" + + " PARTITION `p1` VALUES LESS THAN (200))")) tk.MustExec("drop table if exists t") // test partition override table's placement rules. @@ -944,10 +942,9 @@ func (s *testDBSuite6) TestPolicyInheritance(c *C) { tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" + " `a` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] CONSTRAINTS=\"[+zone=suzhou]\" */\n" + - "PARTITION BY RANGE ( `a` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100) /*T![placement] CONSTRAINTS=\"[+zone=changzhou]\" */,\n" + - " PARTITION `p1` VALUES LESS THAN (200)\n" + - ")")) + "PARTITION BY RANGE (`a`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100) /*T![placement] CONSTRAINTS=\"[+zone=changzhou]\" */,\n" + + " PARTITION `p1` VALUES LESS THAN (200))")) } func (s *testDBSuite6) TestDatabasePlacement(c *C) { @@ -1126,10 +1123,9 @@ func (s *testDBSuite6) TestAlterTablePlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) // alter with policy tk.MustExec("alter table tp placement policy p1") @@ -1137,10 +1133,9 @@ func (s *testDBSuite6) TestAlterTablePlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`p1` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) tb, err := tk.Se.GetInfoSchema().(infoschema.InfoSchema).TableByName(model.NewCIStr("test"), model.NewCIStr("tp")) c.Assert(err, IsNil) @@ -1153,10 +1148,9 @@ func (s *testDBSuite6) TestAlterTablePlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PRIMARY_REGION=\"r2\" REGIONS=\"r1,r2\" */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) // reset with placement policy 'default' tk.MustExec("alter table tp placement policy default") @@ -1164,10 +1158,9 @@ func (s *testDBSuite6) TestAlterTablePlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) // error invalid policy err = tk.ExecToErr("alter table tp placement policy px") @@ -1186,10 +1179,9 @@ func (s *testDBSuite6) TestAlterTablePlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) } func (s *testDBSuite6) TestDropTablePartitionGCPlacement(c *C) { @@ -1278,10 +1270,9 @@ func (s *testDBSuite6) TestAlterTablePartitionPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`p0` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) // alter with policy tk.MustExec("alter table tp partition p0 placement policy p1") @@ -1289,10 +1280,9 @@ func (s *testDBSuite6) TestAlterTablePartitionPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`p0` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) tb, err := tk.Se.GetInfoSchema().(infoschema.InfoSchema).TableByName(model.NewCIStr("test"), model.NewCIStr("tp")) c.Assert(err, IsNil) @@ -1305,20 +1295,18 @@ func (s *testDBSuite6) TestAlterTablePartitionPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`p0` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + - " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PRIMARY_REGION=\"r2\" REGIONS=\"r1,r2\" */\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + + " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PRIMARY_REGION=\"r2\" REGIONS=\"r1,r2\" */)")) tk.MustExec("alter table tp partition p1 primary_region='r3' regions='r3,r4'") tk.MustQuery("show create table tp").Check(testkit.Rows("" + "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`p0` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + - " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PRIMARY_REGION=\"r3\" REGIONS=\"r3,r4\" */\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + + " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PRIMARY_REGION=\"r3\" REGIONS=\"r3,r4\" */)")) // reset with placement policy 'default' tk.MustExec("alter table tp partition p1 placement policy default") @@ -1326,20 +1314,18 @@ func (s *testDBSuite6) TestAlterTablePartitionPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`p0` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) tk.MustExec("alter table tp partition p0 placement policy default") tk.MustQuery("show create table tp").Check(testkit.Rows("" + "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`p0` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) // error invalid policy err = tk.ExecToErr("alter table tp partition p1 placement policy px") @@ -1362,10 +1348,9 @@ func (s *testDBSuite6) TestAlterTablePartitionPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`p0` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) } func (s *testDBSuite6) TestAddPartitionWithPlacement(c *C) { @@ -1389,10 +1374,9 @@ func (s *testDBSuite6) TestAddPartitionWithPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000))")) // Add partitions tk.MustExec(`alter table tp add partition ( @@ -1404,13 +1388,12 @@ func (s *testDBSuite6) TestAddPartitionWithPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000),\n" + - " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + - " PARTITION `p3` VALUES LESS THAN (100000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */,\n" + - " PARTITION `p4` VALUES LESS THAN (1000000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000),\n" + + " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + + " PARTITION `p3` VALUES LESS THAN (100000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */,\n" + + " PARTITION `p4` VALUES LESS THAN (1000000))")) tb, err := tk.Se.GetInfoSchema().(infoschema.InfoSchema).TableByName(model.NewCIStr("test"), model.NewCIStr("tp")) c.Assert(err, IsNil) @@ -1433,13 +1416,12 @@ func (s *testDBSuite6) TestAddPartitionWithPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000),\n" + - " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + - " PARTITION `p3` VALUES LESS THAN (100000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */,\n" + - " PARTITION `p4` VALUES LESS THAN (1000000)\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000),\n" + + " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PLACEMENT POLICY=`p1` */,\n" + + " PARTITION `p3` VALUES LESS THAN (100000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */,\n" + + " PARTITION `p4` VALUES LESS THAN (1000000))")) } func (s *testDBSuite6) TestTruncateTableWithPlacement(c *C) { @@ -1497,11 +1479,10 @@ func (s *testDBSuite6) TestTruncateTableWithPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`p1` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + - " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + + " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */)")) tk.MustExec("TRUNCATE TABLE tp") newTp, err := tk.Se.GetInfoSchema().(infoschema.InfoSchema).TableByName(model.NewCIStr("test"), model.NewCIStr("tp")) @@ -1632,12 +1613,11 @@ func (s *testDBSuite6) TestTruncateTablePartitionWithPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`p1` */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + - " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PLACEMENT POLICY=`p3` */,\n" + - " PARTITION `p3` VALUES LESS THAN (100000) /*T![placement] PRIMARY_REGION=\"r2\" REGIONS=\"r2\" */\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + + " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PLACEMENT POLICY=`p3` */,\n" + + " PARTITION `p3` VALUES LESS THAN (100000) /*T![placement] PRIMARY_REGION=\"r2\" REGIONS=\"r2\" */)")) } func (s *testDBSuite6) TestTruncatePartitionGCWithPlacement(c *C) { @@ -1759,11 +1739,10 @@ func (s *testDBSuite6) TestExchangePartitionWithPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1\" */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + - " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + + " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */)")) tp, err = tk.Se.GetInfoSchema().(infoschema.InfoSchema).TableByName(model.NewCIStr("test"), model.NewCIStr("tp")) c.Assert(err, IsNil) c.Assert(tp.Meta().ID, Equals, tpID) @@ -1786,11 +1765,10 @@ func (s *testDBSuite6) TestExchangePartitionWithPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1\" */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + - " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + + " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */)")) tp, err = tk.Se.GetInfoSchema().(infoschema.InfoSchema).TableByName(model.NewCIStr("test"), model.NewCIStr("tp")) c.Assert(err, IsNil) c.Assert(tp.Meta().ID, Equals, tpID) @@ -1813,11 +1791,10 @@ func (s *testDBSuite6) TestExchangePartitionWithPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1\" */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + - " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + + " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */)")) tp, err = tk.Se.GetInfoSchema().(infoschema.InfoSchema).TableByName(model.NewCIStr("test"), model.NewCIStr("tp")) c.Assert(err, IsNil) c.Assert(tp.Meta().ID, Equals, tpID) @@ -1840,11 +1817,10 @@ func (s *testDBSuite6) TestExchangePartitionWithPlacement(c *C) { "tp CREATE TABLE `tp` (\n" + " `id` int(11) DEFAULT NULL\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1\" */\n" + - "PARTITION BY RANGE ( `id` ) (\n" + - " PARTITION `p0` VALUES LESS THAN (100),\n" + - " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + - " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */\n" + - ")")) + "PARTITION BY RANGE (`id`)\n" + + "(PARTITION `p0` VALUES LESS THAN (100),\n" + + " PARTITION `p1` VALUES LESS THAN (1000) /*T![placement] PLACEMENT POLICY=`p2` */,\n" + + " PARTITION `p2` VALUES LESS THAN (10000) /*T![placement] PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" */)")) tp, err = tk.Se.GetInfoSchema().(infoschema.InfoSchema).TableByName(model.NewCIStr("test"), model.NewCIStr("tp")) c.Assert(err, IsNil) c.Assert(tp.Meta().ID, Equals, tpID) diff --git a/executor/seqtest/seq_executor_serial_test.go b/executor/seqtest/seq_executor_serial_test.go index 2ff7ca574480e..6b0f3de5f6a2c 100644 --- a/executor/seqtest/seq_executor_serial_test.go +++ b/executor/seqtest/seq_executor_serial_test.go @@ -497,7 +497,7 @@ func TestShow(t *testing.T) { 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)", + ") 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))", )) tk.MustExec(`drop table if exists t`) @@ -529,8 +529,8 @@ func TestShow(t *testing.T) { 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", - )) + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ + "PARTITION BY HASH (`a`) PARTITIONS 4")) // Test show create table compression type. tk.MustExec(`drop table if exists t1`) diff --git a/executor/show.go b/executor/show.go index 86ace8956dfda..7bb135d56230e 100644 --- a/executor/show.go +++ b/executor/show.go @@ -1235,58 +1235,54 @@ func appendPartitionInfo(partitionInfo *model.PartitionInfo, buf *bytes.Buffer, if partitionInfo == nil { return } + // Since MySQL 5.1/5.5 is very old and TiDB aims for 5.7/8.0 compatibility, we will not + // include the /*!50100 or /*!50500 comments for TiDB. + // This also solves the issue with comments within comments that would happen for + // PLACEMENT POLICY options. if partitionInfo.Type == model.PartitionTypeHash { - fmt.Fprintf(buf, "\nPARTITION BY HASH( %s )", partitionInfo.Expr) - fmt.Fprintf(buf, "\nPARTITIONS %d", partitionInfo.Num) - return + defaultPartitionDefinitions := true + for i, def := range partitionInfo.Definitions { + if def.Name.O != fmt.Sprintf("p%d", i) { + defaultPartitionDefinitions = false + break + } + if len(def.Comment) > 0 || def.DirectPlacementOpts != nil || def.PlacementPolicyRef != nil { + defaultPartitionDefinitions = false + break + } + } + + if defaultPartitionDefinitions { + fmt.Fprintf(buf, "\nPARTITION BY HASH (%s) PARTITIONS %d", partitionInfo.Expr, partitionInfo.Num) + return + } } - // this if statement takes care of range columns case - if partitionInfo.Columns != nil && partitionInfo.Type == model.PartitionTypeRange { - buf.WriteString("\nPARTITION BY RANGE COLUMNS(") + // this if statement takes care of lists/range columns case + if partitionInfo.Columns != nil { + // partitionInfo.Type == model.PartitionTypeRange || partitionInfo.Type == model.PartitionTypeList + // Notice that MySQL uses two spaces between LIST and COLUMNS... + fmt.Fprintf(buf, "\nPARTITION BY %s COLUMNS(", partitionInfo.Type.String()) for i, col := range partitionInfo.Columns { - buf.WriteString(col.L) + buf.WriteString(stringutil.Escape(col.O, sqlMode)) if i < len(partitionInfo.Columns)-1 { buf.WriteString(",") } } - buf.WriteString(") (\n") - } else if partitionInfo.Type == model.PartitionTypeList { - if len(partitionInfo.Columns) == 0 { - fmt.Fprintf(buf, "\nPARTITION BY %s (%s) (\n", partitionInfo.Type.String(), partitionInfo.Expr) - } else { - colsName := "" - for _, col := range partitionInfo.Columns { - if len(colsName) > 0 { - colsName += "," - } - colsName += col.L - } - fmt.Fprintf(buf, "\nPARTITION BY LIST COLUMNS(%s) (\n", colsName) - } + buf.WriteString(")\n(") } else { - fmt.Fprintf(buf, "\nPARTITION BY %s ( %s ) (\n", partitionInfo.Type.String(), partitionInfo.Expr) + fmt.Fprintf(buf, "\nPARTITION BY %s (%s)\n(", partitionInfo.Type.String(), partitionInfo.Expr) } - if partitionInfo.Type == model.PartitionTypeRange { - for i, def := range partitionInfo.Definitions { - lessThans := strings.Join(def.LessThan, ",") - fmt.Fprintf(buf, " PARTITION `%s` VALUES LESS THAN (%s)", def.Name, lessThans) - if def.DirectPlacementOpts != nil { - // add direct placement info here - appendDirectPlacementInfo(def.DirectPlacementOpts, buf) - } - if def.PlacementPolicyRef != nil { - // add placement ref info here - fmt.Fprintf(buf, " /*T![placement] PLACEMENT POLICY=%s */", stringutil.Escape(def.PlacementPolicyRef.Name.O, sqlMode)) - } - if i < len(partitionInfo.Definitions)-1 { - buf.WriteString(",\n") - } else { - buf.WriteString("\n") - } + + for i, def := range partitionInfo.Definitions { + if i > 0 { + fmt.Fprintf(buf, ",\n ") } - buf.WriteString(")") - } else if partitionInfo.Type == model.PartitionTypeList { - for i, def := range partitionInfo.Definitions { + fmt.Fprintf(buf, "PARTITION %s", stringutil.Escape(def.Name.O, sqlMode)) + // PartitionTypeHash does not have any VALUES definition + if partitionInfo.Type == model.PartitionTypeRange { + lessThans := strings.Join(def.LessThan, ",") + fmt.Fprintf(buf, " VALUES LESS THAN (%s)", lessThans) + } else if partitionInfo.Type == model.PartitionTypeList { values := bytes.NewBuffer(nil) for j, inValues := range def.InValues { if j > 0 { @@ -1300,23 +1296,21 @@ func appendPartitionInfo(partitionInfo *model.PartitionInfo, buf *bytes.Buffer, values.WriteString(strings.Join(inValues, ",")) } } - fmt.Fprintf(buf, " PARTITION `%s` VALUES IN (%s)", def.Name, values.String()) - if def.DirectPlacementOpts != nil { - // add direct placement info here - appendDirectPlacementInfo(def.DirectPlacementOpts, buf) - } - if def.PlacementPolicyRef != nil { - // add placement ref info here - fmt.Fprintf(buf, " /*T![placement] PLACEMENT POLICY=%s */", stringutil.Escape(def.PlacementPolicyRef.Name.O, sqlMode)) - } - if i < len(partitionInfo.Definitions)-1 { - buf.WriteString(",\n") - } else { - buf.WriteString("\n") - } + fmt.Fprintf(buf, " VALUES IN (%s)", values.String()) + } + if len(def.Comment) > 0 { + buf.WriteString(fmt.Sprintf(" COMMENT '%s'", format.OutputFormat(def.Comment))) + } + if def.DirectPlacementOpts != nil { + // add direct placement info here + appendDirectPlacementInfo(def.DirectPlacementOpts, buf) + } + if def.PlacementPolicyRef != nil { + // add placement ref info here + fmt.Fprintf(buf, " /*T![placement] PLACEMENT POLICY=%s */", stringutil.Escape(def.PlacementPolicyRef.Name.O, sqlMode)) } - buf.WriteString(")") } + buf.WriteString(")") } // ConstructResultOfShowCreateDatabase constructs the result for show create database. diff --git a/executor/show_test.go b/executor/show_test.go index aa877e21ddc93..7373e1b67910e 100644 --- a/executor/show_test.go +++ b/executor/show_test.go @@ -776,20 +776,19 @@ func (s *testSuite5) TestShowCreateTable(c *C) { " KEY `IDX_RoundId` (`ROUND_ID`),\n"+ " KEY `IDX_UserId_EndTime` (`USER_ID`,`END_TIME`)\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=505488\n"+ - "PARTITION BY RANGE ( MONTH(`end_time`) ) (\n"+ - " PARTITION `p1` VALUES LESS THAN (2),\n"+ - " PARTITION `p2` VALUES LESS THAN (3),\n"+ - " PARTITION `p3` VALUES LESS THAN (4),\n"+ - " PARTITION `p4` VALUES LESS THAN (5),\n"+ - " PARTITION `p5` VALUES LESS THAN (6),\n"+ - " PARTITION `p6` VALUES LESS THAN (7),\n"+ - " PARTITION `p7` VALUES LESS THAN (8),\n"+ - " PARTITION `p8` VALUES LESS THAN (9),\n"+ - " PARTITION `p9` VALUES LESS THAN (10),\n"+ - " PARTITION `p10` VALUES LESS THAN (11),\n"+ - " PARTITION `p11` VALUES LESS THAN (12),\n"+ - " PARTITION `p12` VALUES LESS THAN (MAXVALUE)\n"+ - ")")) + "PARTITION BY RANGE (MONTH(`end_time`))\n"+ + "(PARTITION `p1` VALUES LESS THAN (2),\n"+ + " PARTITION `p2` VALUES LESS THAN (3),\n"+ + " PARTITION `p3` VALUES LESS THAN (4),\n"+ + " PARTITION `p4` VALUES LESS THAN (5),\n"+ + " PARTITION `p5` VALUES LESS THAN (6),\n"+ + " PARTITION `p6` VALUES LESS THAN (7),\n"+ + " PARTITION `p7` VALUES LESS THAN (8),\n"+ + " PARTITION `p8` VALUES LESS THAN (9),\n"+ + " PARTITION `p9` VALUES LESS THAN (10),\n"+ + " PARTITION `p10` VALUES LESS THAN (11),\n"+ + " PARTITION `p11` VALUES LESS THAN (12),\n"+ + " PARTITION `p12` VALUES LESS THAN (MAXVALUE))")) // for issue #11831 tk.MustExec("create table ttt4(a varchar(123) default null collate utf8mb4_unicode_ci)engine=innodb default charset=utf8mb4 collate=utf8mb4_unicode_ci;") @@ -932,12 +931,11 @@ func (s *testSuite5) TestShowCreateTable(c *C) { " `name` varchar(10) DEFAULT NULL,\n"+ " UNIQUE KEY `idx` (`id`)\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ - "PARTITION BY LIST (`id`) (\n"+ - " PARTITION `p0` VALUES IN (3,5,6,9,17),\n"+ - " PARTITION `p1` VALUES IN (1,2,10,11,19,20),\n"+ - " PARTITION `p2` VALUES IN (4,12,13,14,18),\n"+ - " PARTITION `p3` VALUES IN (7,8,15,16,NULL)\n"+ - ")")) + "PARTITION BY LIST (`id`)\n"+ + "(PARTITION `p0` VALUES IN (3,5,6,9,17),\n"+ + " PARTITION `p1` VALUES IN (1,2,10,11,19,20),\n"+ + " PARTITION `p2` VALUES IN (4,12,13,14,18),\n"+ + " PARTITION `p3` VALUES IN (7,8,15,16,NULL))")) // Test show list column partition table tk.MustExec(`DROP TABLE IF EXISTS t`) tk.MustExec(`create table t (id int, name varchar(10), unique index idx (id)) partition by list columns (id) ( @@ -952,12 +950,11 @@ func (s *testSuite5) TestShowCreateTable(c *C) { " `name` varchar(10) DEFAULT NULL,\n"+ " UNIQUE KEY `idx` (`id`)\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ - "PARTITION BY LIST COLUMNS(id) (\n"+ - " PARTITION `p0` VALUES IN (3,5,6,9,17),\n"+ - " PARTITION `p1` VALUES IN (1,2,10,11,19,20),\n"+ - " PARTITION `p2` VALUES IN (4,12,13,14,18),\n"+ - " PARTITION `p3` VALUES IN (7,8,15,16,NULL)\n"+ - ")")) + "PARTITION BY LIST COLUMNS(`id`)\n"+ + "(PARTITION `p0` VALUES IN (3,5,6,9,17),\n"+ + " PARTITION `p1` VALUES IN (1,2,10,11,19,20),\n"+ + " PARTITION `p2` VALUES IN (4,12,13,14,18),\n"+ + " PARTITION `p3` VALUES IN (7,8,15,16,NULL))")) tk.MustExec(`DROP TABLE IF EXISTS t`) tk.MustExec(`create table t (id int, name varchar(10), unique index idx (id, name)) partition by list columns (id, name) ( partition p0 values in ((3, '1'), (5, '5')), @@ -968,10 +965,9 @@ func (s *testSuite5) TestShowCreateTable(c *C) { " `name` varchar(10) DEFAULT NULL,\n"+ " UNIQUE KEY `idx` (`id`,`name`)\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ - "PARTITION BY LIST COLUMNS(id,name) (\n"+ - " PARTITION `p0` VALUES IN ((3,\"1\"),(5,\"5\")),\n"+ - " PARTITION `p1` VALUES IN ((1,\"1\"))\n"+ - ")")) + "PARTITION BY LIST COLUMNS(`id`,`name`)\n"+ + "(PARTITION `p0` VALUES IN ((3,\"1\"),(5,\"5\")),\n"+ + " PARTITION `p1` VALUES IN ((1,\"1\")))")) tk.MustExec(`DROP TABLE IF EXISTS t`) tk.MustExec(`create table t (id int primary key, v varchar(255) not null, key idx_v (v) comment 'foo\'bar')`) tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", @@ -981,6 +977,30 @@ func (s *testSuite5) TestShowCreateTable(c *C) { " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,\n"+ " KEY `idx_v` (`v`) COMMENT 'foo''bar'\n"+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) + + // For issue #29922 + tk.MustExec("CREATE TABLE `thash` (\n `id` bigint unsigned NOT NULL,\n `data` varchar(255) DEFAULT NULL,\n PRIMARY KEY (`id`)\n)\nPARTITION BY HASH (`id`)\n(PARTITION pEven COMMENT = \"Even ids\",\n PARTITION pOdd COMMENT = \"Odd ids\");") + tk.MustQuery("show create table `thash`").Check(testutil.RowsWithSep("|", ""+ + "thash CREATE TABLE `thash` (\n"+ + " `id` bigint(20) unsigned NOT NULL,\n"+ + " `data` varchar(255) DEFAULT NULL,\n"+ + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ + "PARTITION BY HASH (`id`)\n"+ + "(PARTITION `pEven` COMMENT 'Even ids',\n"+ + " PARTITION `pOdd` COMMENT 'Odd ids')", + )) + // empty edge case + tk.MustExec("drop table if exists `thash`") + tk.MustExec("CREATE TABLE `thash` (\n `id` bigint unsigned NOT NULL,\n `data` varchar(255) DEFAULT NULL,\n PRIMARY KEY (`id`)\n)\nPARTITION BY HASH (`id`);") + tk.MustQuery("show create table `thash`").Check(testutil.RowsWithSep("|", ""+ + "thash CREATE TABLE `thash` (\n"+ + " `id` bigint(20) unsigned NOT NULL,\n"+ + " `data` varchar(255) DEFAULT NULL,\n"+ + " PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ + "PARTITION BY HASH (`id`) PARTITIONS 1", + )) } func (s *testSuite5) TestShowCreateTablePlacement(c *C) { @@ -1006,6 +1026,7 @@ func (s *testSuite5) TestShowCreateTablePlacement(c *C) { tk.MustExec("create placement policy x " + "FOLLOWERS=2 " + "CONSTRAINTS=\"[+disk=ssd]\" ") + defer tk.MustExec(`DROP PLACEMENT POLICY IF EXISTS x`) tk.MustExec("create table t(a int)" + "PLACEMENT POLICY=\"x\"") tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", @@ -1026,8 +1047,132 @@ func (s *testSuite5) TestShowCreateTablePlacement(c *C) { "/*T![placement] PLACEMENT POLICY=`x` */", )) + // Partitioned tables tk.MustExec(`DROP TABLE IF EXISTS t`) - tk.MustExec(`DROP PLACEMENT POLICY if exists x`) + tk.MustExec("set @old_list_part = @@tidb_enable_list_partition") + defer tk.MustExec("set @@tidb_enable_list_partition = @old_list_part") + tk.MustExec("set tidb_enable_list_partition = 1") + tk.MustExec("create table t(a int, b varchar(255))" + + "/*T![placement] PLACEMENT POLICY=\"x\" */" + + "PARTITION BY LIST (a)\n" + + "(PARTITION pLow VALUES in (1,2,3,5,8) COMMENT 'a comment' placement policy 'x'," + + " PARTITION pMid VALUES in (9) COMMENT 'another comment'," + + "partition pMax values IN (10,11,12) PRIMARY_REGION = 'us-west-1' REGIONS = 'us-west-1,us-west-2')") + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+ + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` varchar(255) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`x` */\n"+ + "PARTITION BY LIST (`a`)\n"+ + "(PARTITION `pLow` VALUES IN (1,2,3,5,8) COMMENT 'a comment' /*T![placement] PLACEMENT POLICY=`x` */,\n"+ + " PARTITION `pMid` VALUES IN (9) COMMENT 'another comment',\n"+ + " PARTITION `pMax` VALUES IN (10,11,12) /*T![placement] PRIMARY_REGION=\"us-west-1\" REGIONS=\"us-west-1,us-west-2\" */)", + )) + + tk.MustExec(`DROP TABLE IF EXISTS t`) + tk.MustExec("create table t(a int, b varchar(255))" + + "PARTITION BY LIST COLUMNS (b)\n" + + "(PARTITION pLow VALUES in ('1','2','3','5','8') COMMENT 'a comment' placement policy 'x'," + + "partition pMax values IN ('10','11','12') PRIMARY_REGION = 'us-west-1' REGIONS = 'us-west-1,us-west-2')") + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+ + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` varchar(255) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ + "PARTITION BY LIST COLUMNS(`b`)\n"+ + "(PARTITION `pLow` VALUES IN (\"1\",\"2\",\"3\",\"5\",\"8\") COMMENT 'a comment' /*T![placement] PLACEMENT POLICY=`x` */,\n"+ + " PARTITION `pMax` VALUES IN (\"10\",\"11\",\"12\") /*T![placement] PRIMARY_REGION=\"us-west-1\" REGIONS=\"us-west-1,us-west-2\" */)", + )) + + tk.MustExec(`DROP TABLE IF EXISTS t`) + tk.MustExec("create table t(a int, b varchar(255))" + + "PARTITION BY LIST COLUMNS (a,b)\n" + + "(PARTITION pLow VALUES in ((1,'1'),(2,'2'),(3,'3'),(5,'5'),(8,'8')) COMMENT 'a comment' placement policy 'x'," + + "partition pMax values IN ((10,'10'),(11,'11'),(12,'12')) PRIMARY_REGION = 'us-west-1' REGIONS = 'us-west-1,us-west-2')") + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+ + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` varchar(255) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ + "PARTITION BY LIST COLUMNS(`a`,`b`)\n"+ + "(PARTITION `pLow` VALUES IN ((1,\"1\"),(2,\"2\"),(3,\"3\"),(5,\"5\"),(8,\"8\")) COMMENT 'a comment' /*T![placement] PLACEMENT POLICY=`x` */,\n"+ + " PARTITION `pMax` VALUES IN ((10,\"10\"),(11,\"11\"),(12,\"12\")) /*T![placement] PRIMARY_REGION=\"us-west-1\" REGIONS=\"us-west-1,us-west-2\" */)", + )) + + tk.MustExec(`DROP TABLE IF EXISTS t`) + tk.MustExec("create table t(a int, b varchar(255))" + + "PARTITION BY RANGE (a)\n" + + "(PARTITION pLow VALUES less than (1000000) COMMENT 'a comment' placement policy 'x'," + + "partition pMax values LESS THAN (MAXVALUE) PRIMARY_REGION = 'us-west-1' REGIONS = 'us-west-1,us-west-2')") + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+ + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` varchar(255) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ + "PARTITION BY RANGE (`a`)\n"+ + "(PARTITION `pLow` VALUES LESS THAN (1000000) COMMENT 'a comment' /*T![placement] PLACEMENT POLICY=`x` */,\n"+ + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE) /*T![placement] PRIMARY_REGION=\"us-west-1\" REGIONS=\"us-west-1,us-west-2\" */)", + )) + + tk.MustExec(`DROP TABLE IF EXISTS t`) + tk.MustExec("create table t(a int, b varchar(255))" + + "PARTITION BY RANGE COLUMNS (b)\n" + + "(PARTITION pLow VALUES less than ('1000000') COMMENT 'a comment' placement policy 'x'," + + "partition pMax values LESS THAN (MAXVALUE) PRIMARY_REGION = 'us-west-1' REGIONS = 'us-west-1,us-west-2')") + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+ + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` varchar(255) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ + "PARTITION BY RANGE COLUMNS(`b`)\n"+ + "(PARTITION `pLow` VALUES LESS THAN (\"1000000\") COMMENT 'a comment' /*T![placement] PLACEMENT POLICY=`x` */,\n"+ + " PARTITION `pMax` VALUES LESS THAN (MAXVALUE) /*T![placement] PRIMARY_REGION=\"us-west-1\" REGIONS=\"us-west-1,us-west-2\" */)", + )) + + tk.MustExec(`DROP TABLE IF EXISTS t`) + // RANGE COLUMNS with multiple columns is not supported! + tk.MustExec("create table t(a int, b varchar(255))" + + "/*T![placement] PLACEMENT POLICY=\"x\" */" + + "PARTITION BY RANGE COLUMNS (a,b)\n" + + "(PARTITION pLow VALUES less than (1000000,'1000000') COMMENT 'a comment' placement policy 'x'," + + " PARTITION pMidLow VALUES less than (1000000,MAXVALUE) COMMENT 'another comment' placement policy 'x'," + + " PARTITION pMadMax VALUES less than (MAXVALUE,'1000000') COMMENT ='Not a comment' placement policy 'x'," + + "partition pMax values LESS THAN (MAXVALUE, MAXVALUE) PRIMARY_REGION = 'us-west-1' REGIONS = 'us-west-1,us-west-2')") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 8200 Unsupported partition type RANGE, treat as normal table")) + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+ + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` varchar(255) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`x` */", + )) + + tk.MustExec(`DROP TABLE IF EXISTS t`) + tk.MustExec("create table t(a int, b varchar(255))" + + "/*T![placement] PLACEMENT POLICY=\"x\" */" + + "PARTITION BY HASH (a) PARTITIONS 2") + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+ + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` varchar(255) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY=`x` */\n"+ + "PARTITION BY HASH (`a`) PARTITIONS 2", + )) + + tk.MustExec(`DROP TABLE IF EXISTS t`) + tk.MustExec("create table t(a int, b varchar(255))" + + "PARTITION BY HASH (a)\n" + + "(PARTITION pLow COMMENT 'a comment' placement policy 'x'," + + "partition pMax PRIMARY_REGION = 'us-west-1' REGIONS = 'us-west-1,us-west-2')") + tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+ + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` varchar(255) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+ + "PARTITION BY HASH (`a`)\n"+ + "(PARTITION `pLow` COMMENT 'a comment' /*T![placement] PLACEMENT POLICY=`x` */,\n"+ + " PARTITION `pMax` /*T![placement] PRIMARY_REGION=\"us-west-1\" REGIONS=\"us-west-1,us-west-2\" */)", + )) + tk.MustExec(`DROP TABLE t`) } func (s *testAutoRandomSuite) TestShowCreateTableAutoRandom(c *C) { diff --git a/table/tables/partition_test.go b/table/tables/partition_test.go index 8c3061c333aca..7807746ed76ac 100644 --- a/table/tables/partition_test.go +++ b/table/tables/partition_test.go @@ -430,12 +430,12 @@ func TestTimeZoneChange(t *testing.T) { " `id` int(11) NOT NULL,\n" + " `creation_dt` timestamp DEFAULT CURRENT_TIMESTAMP\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + - "PARTITION BY RANGE ( UNIX_TIMESTAMP(`creation_dt`) ) (\n" + - " PARTITION `p5` VALUES LESS THAN (1578035400),\n" + - " PARTITION `p6` VALUES LESS THAN (1578035700),\n" + - " PARTITION `p7` VALUES LESS THAN (1578036000),\n" + - " PARTITION `p8` VALUES LESS THAN (1578036300),\n" + - " PARTITION `p9` VALUES LESS THAN (MAXVALUE)\n)")) + "PARTITION BY RANGE (UNIX_TIMESTAMP(`creation_dt`))\n" + + "(PARTITION `p5` VALUES LESS THAN (1578035400),\n" + + " PARTITION `p6` VALUES LESS THAN (1578035700),\n" + + " PARTITION `p7` VALUES LESS THAN (1578036000),\n" + + " PARTITION `p8` VALUES LESS THAN (1578036300),\n" + + " PARTITION `p9` VALUES LESS THAN (MAXVALUE))")) tk.MustExec("DROP TABLE timezone_test") // Note that the result of "show create table" varies with time_zone. @@ -445,12 +445,12 @@ func TestTimeZoneChange(t *testing.T) { " `id` int(11) NOT NULL,\n" + " `creation_dt` timestamp DEFAULT CURRENT_TIMESTAMP\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" + - "PARTITION BY RANGE ( UNIX_TIMESTAMP(`creation_dt`) ) (\n" + - " PARTITION `p5` VALUES LESS THAN (1578064200),\n" + - " PARTITION `p6` VALUES LESS THAN (1578064500),\n" + - " PARTITION `p7` VALUES LESS THAN (1578064800),\n" + - " PARTITION `p8` VALUES LESS THAN (1578065100),\n" + - " PARTITION `p9` VALUES LESS THAN (MAXVALUE)\n)")) + "PARTITION BY RANGE (UNIX_TIMESTAMP(`creation_dt`))\n" + + "(PARTITION `p5` VALUES LESS THAN (1578064200),\n" + + " PARTITION `p6` VALUES LESS THAN (1578064500),\n" + + " PARTITION `p7` VALUES LESS THAN (1578064800),\n" + + " PARTITION `p8` VALUES LESS THAN (1578065100),\n" + + " PARTITION `p9` VALUES LESS THAN (MAXVALUE))")) // Change time zone and insert data, check the data locates in the correct partition. tk.MustExec("SET @@time_zone = 'Asia/Shanghai'")