github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/db_partition_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package dbs_test
    15  
    16  import (
    17  	"context"
    18  	"fmt"
    19  	"math"
    20  	"math/rand"
    21  	"strings"
    22  	"sync/atomic"
    23  	"time"
    24  
    25  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    26  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    27  	"github.com/whtcorpsinc/BerolinaSQL/perceptron"
    28  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    29  	. "github.com/whtcorpsinc/check"
    30  	"github.com/whtcorpsinc/errors"
    31  	"github.com/whtcorpsinc/failpoint"
    32  	"github.com/whtcorpsinc/milevadb/blockcodec"
    33  	"github.com/whtcorpsinc/milevadb/causet"
    34  	"github.com/whtcorpsinc/milevadb/causet/blocks"
    35  	"github.com/whtcorpsinc/milevadb/dbs"
    36  	"github.com/whtcorpsinc/milevadb/dbs/solitonutil"
    37  	"github.com/whtcorpsinc/milevadb/ekv"
    38  	tmysql "github.com/whtcorpsinc/milevadb/errno"
    39  	"github.com/whtcorpsinc/milevadb/petri"
    40  	"github.com/whtcorpsinc/milevadb/soliton/admin"
    41  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    42  	"github.com/whtcorpsinc/milevadb/soliton/testkit"
    43  	"github.com/whtcorpsinc/milevadb/spacetime"
    44  	"github.com/whtcorpsinc/milevadb/stochastik"
    45  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    46  	"github.com/whtcorpsinc/milevadb/types"
    47  )
    48  
    49  func (s *testIntegrationSuite3) TestCreateBlockWithPartition(c *C) {
    50  	tk := testkit.NewTestKit(c, s.causetstore)
    51  	tk.MustInterDirc("use test;")
    52  	tk.MustInterDirc("drop causet if exists tp;")
    53  	tk.MustInterDirc(`CREATE TABLE tp (a int) PARTITION BY RANGE(a) (
    54  	PARTITION p0 VALUES LESS THAN (10),
    55  	PARTITION p1 VALUES LESS THAN (20),
    56  	PARTITION p2 VALUES LESS THAN (MAXVALUE)
    57  	);`)
    58  	ctx := tk.Se.(stochastikctx.Context)
    59  	is := petri.GetPetri(ctx).SchemaReplicant()
    60  	tbl, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("tp"))
    61  	c.Assert(err, IsNil)
    62  	c.Assert(tbl.Meta().Partition, NotNil)
    63  	part := tbl.Meta().Partition
    64  	c.Assert(part.Type, Equals, perceptron.PartitionTypeRange)
    65  	c.Assert(part.Expr, Equals, "`a`")
    66  	for _, FIDelef := range part.Definitions {
    67  		c.Assert(FIDelef.ID, Greater, int64(0))
    68  	}
    69  	c.Assert(part.Definitions, HasLen, 3)
    70  	c.Assert(part.Definitions[0].LessThan[0], Equals, "10")
    71  	c.Assert(part.Definitions[0].Name.L, Equals, "p0")
    72  	c.Assert(part.Definitions[1].LessThan[0], Equals, "20")
    73  	c.Assert(part.Definitions[1].Name.L, Equals, "p1")
    74  	c.Assert(part.Definitions[2].LessThan[0], Equals, "MAXVALUE")
    75  	c.Assert(part.Definitions[2].Name.L, Equals, "p2")
    76  
    77  	tk.MustInterDirc("drop causet if exists employees;")
    78  	sql1 := `create causet employees (
    79  	id int not null,
    80  	hired int not null
    81  	)
    82  	partition by range( hired ) (
    83  		partition p1 values less than (1991),
    84  		partition p2 values less than (1996),
    85  		partition p2 values less than (2001)
    86  	);`
    87  	tk.MustGetErrCode(sql1, tmysql.ErrSameNamePartition)
    88  
    89  	sql2 := `create causet employees (
    90  	id int not null,
    91  	hired int not null
    92  	)
    93  	partition by range( hired ) (
    94  		partition p1 values less than (1998),
    95  		partition p2 values less than (1996),
    96  		partition p3 values less than (2001)
    97  	);`
    98  	tk.MustGetErrCode(sql2, tmysql.ErrRangeNotIncreasing)
    99  
   100  	sql3 := `create causet employees (
   101  	id int not null,
   102  	hired int not null
   103  	)
   104  	partition by range( hired ) (
   105  		partition p1 values less than (1998),
   106  		partition p2 values less than maxvalue,
   107  		partition p3 values less than (2001)
   108  	);`
   109  	tk.MustGetErrCode(sql3, tmysql.ErrPartitionMaxvalue)
   110  
   111  	sql4 := `create causet t4 (
   112  	a int not null,
   113  	b int not null
   114  	)
   115  	partition by range( a ) (
   116  		partition p1 values less than maxvalue,
   117  		partition p2 values less than (1991),
   118  		partition p3 values less than (1995)
   119  	);`
   120  	tk.MustGetErrCode(sql4, tmysql.ErrPartitionMaxvalue)
   121  
   122  	_, err = tk.InterDirc(`CREATE TABLE rc (
   123  		a INT NOT NULL,
   124  		b INT NOT NULL,
   125  		c INT NOT NULL
   126  	)
   127  	partition by range defCausumns(a,b,c) (
   128  	partition p0 values less than (10,5,1),
   129  	partition p2 values less than (50,maxvalue,10),
   130  	partition p3 values less than (65,30,13),
   131  	partition p4 values less than (maxvalue,30,40)
   132  	);`)
   133  	c.Assert(err, IsNil)
   134  
   135  	sql6 := `create causet employees (
   136  	id int not null,
   137  	hired int not null
   138  	)
   139  	partition by range( hired ) (
   140  		 partition p0 values less than (6 , 10)
   141  	);`
   142  	tk.MustGetErrCode(sql6, tmysql.ErrTooManyValues)
   143  
   144  	sql7 := `create causet t7 (
   145  	a int not null,
   146  	b int not null
   147  	)
   148  	partition by range( a ) (
   149  		partition p1 values less than (1991),
   150  		partition p2 values less than maxvalue,
   151  		partition p3 values less than maxvalue,
   152  		partition p4 values less than (1995),
   153  		partition p5 values less than maxvalue
   154  	);`
   155  	tk.MustGetErrCode(sql7, tmysql.ErrPartitionMaxvalue)
   156  
   157  	sql18 := `create causet t8 (
   158  	a int not null,
   159  	b int not null
   160  	)
   161  	partition by range( a ) (
   162  		partition p1 values less than (19xx91),
   163  		partition p2 values less than maxvalue
   164  	);`
   165  	tk.MustGetErrCode(sql18, allegrosql.ErrBadField)
   166  
   167  	sql9 := `create TABLE t9 (
   168  	defCaus1 int
   169  	)
   170  	partition by range( case when defCaus1 > 0 then 10 else 20 end ) (
   171  		partition p0 values less than (2),
   172  		partition p1 values less than (6)
   173  	);`
   174  	tk.MustGetErrCode(sql9, tmysql.ErrPartitionFunctionIsNotAllowed)
   175  
   176  	_, err = tk.InterDirc(`CREATE TABLE t9 (
   177  		a INT NOT NULL,
   178  		b INT NOT NULL,
   179  		c INT NOT NULL
   180  	)
   181  	partition by range defCausumns(a) (
   182  	partition p0 values less than (10),
   183  	partition p2 values less than (20),
   184  	partition p3 values less than (20)
   185  	);`)
   186  	c.Assert(dbs.ErrRangeNotIncreasing.Equal(err), IsTrue)
   187  
   188  	tk.MustGetErrCode(`create TABLE t10 (c1 int,c2 int) partition by range(c1 / c2 ) (partition p0 values less than (2));`, tmysql.ErrPartitionFunctionIsNotAllowed)
   189  
   190  	tk.MustInterDirc(`create TABLE t11 (c1 int,c2 int) partition by range(c1 div c2 ) (partition p0 values less than (2));`)
   191  	tk.MustInterDirc(`create TABLE t12 (c1 int,c2 int) partition by range(c1 + c2 ) (partition p0 values less than (2));`)
   192  	tk.MustInterDirc(`create TABLE t13 (c1 int,c2 int) partition by range(c1 - c2 ) (partition p0 values less than (2));`)
   193  	tk.MustInterDirc(`create TABLE t14 (c1 int,c2 int) partition by range(c1 * c2 ) (partition p0 values less than (2));`)
   194  	tk.MustInterDirc(`create TABLE t15 (c1 int,c2 int) partition by range( abs(c1) ) (partition p0 values less than (2));`)
   195  	tk.MustInterDirc(`create TABLE t16 (c1 int) partition by range( c1) (partition p0 values less than (10));`)
   196  
   197  	tk.MustGetErrCode(`create TABLE t17 (c1 int,c2 float) partition by range(c1 + c2 ) (partition p0 values less than (2));`, tmysql.ErrPartitionFuncNotAllowed)
   198  	tk.MustGetErrCode(`create TABLE t18 (c1 int,c2 float) partition by range( floor(c2) ) (partition p0 values less than (2));`, tmysql.ErrPartitionFuncNotAllowed)
   199  	tk.MustInterDirc(`create TABLE t19 (c1 int,c2 float) partition by range( floor(c1) ) (partition p0 values less than (2));`)
   200  
   201  	tk.MustInterDirc(`create TABLE t20 (c1 int,c2 bit(10)) partition by range(c2) (partition p0 values less than (10));`)
   202  	tk.MustInterDirc(`create TABLE t21 (c1 int,c2 year) partition by range( c2 ) (partition p0 values less than (2000));`)
   203  
   204  	tk.MustGetErrCode(`create TABLE t24 (c1 float) partition by range( c1 ) (partition p0 values less than (2000));`, tmysql.ErrFieldTypeNotAllowedAsPartitionField)
   205  
   206  	// test check order. The allegrosql below have 2 problem: 1. ErrFieldTypeNotAllowedAsPartitionField  2. ErrPartitionMaxvalue , allegrosql will return ErrPartitionMaxvalue.
   207  	tk.MustGetErrCode(`create TABLE t25 (c1 float) partition by range( c1 ) (partition p1 values less than maxvalue,partition p0 values less than (2000));`, tmysql.ErrPartitionMaxvalue)
   208  
   209  	// Fix issue 7362.
   210  	tk.MustInterDirc("create causet test_partition(id bigint, name varchar(255), primary key(id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY RANGE  COLUMNS(id) (PARTITION p1 VALUES LESS THAN (10) ENGINE = InnoDB);")
   211  
   212  	// 'Less than' in partition memex could be a constant memex, notice that
   213  	// the SHOW result changed.
   214  	tk.MustInterDirc(`create causet t26 (a date)
   215  			  partition by range(to_seconds(a))(
   216  			  partition p0 values less than (to_seconds('2004-01-01')),
   217  			  partition p1 values less than (to_seconds('2005-01-01')));`)
   218  	tk.MustQuery("show create causet t26").Check(
   219  		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)"))
   220  	tk.MustInterDirc(`create causet t27 (a bigint unsigned not null)
   221  		  partition by range(a) (
   222  		  partition p0 values less than (10),
   223  		  partition p1 values less than (100),
   224  		  partition p2 values less than (1000),
   225  		  partition p3 values less than (18446744073709551000),
   226  		  partition p4 values less than (18446744073709551614)
   227  		);`)
   228  	tk.MustInterDirc(`create causet t28 (a bigint unsigned not null)
   229  		  partition by range(a) (
   230  		  partition p0 values less than (10),
   231  		  partition p1 values less than (100),
   232  		  partition p2 values less than (1000),
   233  		  partition p3 values less than (18446744073709551000 + 1),
   234  		  partition p4 values less than (18446744073709551000 + 10)
   235  		);`)
   236  
   237  	tk.MustInterDirc("set @@milevadb_enable_block_partition = 1")
   238  	tk.MustInterDirc("set @@milevadb_enable_block_partition = 1")
   239  	tk.MustInterDirc(`create causet t30 (
   240  		  a int,
   241  		  b float,
   242  		  c varchar(30))
   243  		  partition by range defCausumns (a, b)
   244  		  (partition p0 values less than (10, 10.0))`)
   245  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 8200 Unsupported partition type, treat as normal causet"))
   246  
   247  	tk.MustGetErrCode(`create causet t31 (a int not null) partition by range( a );`, tmysql.ErrPartitionsMustBeDefined)
   248  	tk.MustGetErrCode(`create causet t32 (a int not null) partition by range defCausumns( a );`, tmysql.ErrPartitionsMustBeDefined)
   249  	tk.MustGetErrCode(`create causet t33 (a int, b int) partition by hash(a) partitions 0;`, tmysql.ErrNoParts)
   250  	tk.MustGetErrCode(`create causet t33 (a timestamp, b int) partition by hash(a) partitions 30;`, tmysql.ErrFieldTypeNotAllowedAsPartitionField)
   251  	tk.MustGetErrCode(`CREATE TABLE t34 (c0 INT) PARTITION BY HASH((CASE WHEN 0 THEN 0 ELSE c0 END )) PARTITIONS 1;`, tmysql.ErrPartitionFunctionIsNotAllowed)
   252  	tk.MustGetErrCode(`CREATE TABLE t0(c0 INT) PARTITION BY HASH((c0<CURRENT_USER())) PARTITIONS 1;`, tmysql.ErrPartitionFunctionIsNotAllowed)
   253  	// TODO: fix this one
   254  	// tk.MustGetErrCode(`create causet t33 (a timestamp, b int) partition by hash(unix_timestamp(a)) partitions 30;`, tmysql.ErrPartitionFuncNotAllowed)
   255  
   256  	// Fix issue 8647
   257  	tk.MustGetErrCode(`CREATE TABLE trb8 (
   258  		id int(11) DEFAULT NULL,
   259  		name varchar(50) DEFAULT NULL,
   260  		purchased date DEFAULT NULL
   261  	) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
   262  	PARTITION BY RANGE ( year(notexist.purchased) - 1 ) (
   263  		PARTITION p0 VALUES LESS THAN (1990),
   264  		PARTITION p1 VALUES LESS THAN (1995),
   265  		PARTITION p2 VALUES LESS THAN (2000),
   266  		PARTITION p3 VALUES LESS THAN (2005)
   267  	);`, tmysql.ErrBadField)
   268  
   269  	// Fix a timezone dependent check bug introduced in https://github.com/whtcorpsinc/milevadb/pull/10655
   270  	tk.MustInterDirc(`create causet t34 (dt timestamp(3)) partition by range (floor(unix_timestamp(dt))) (
   271  		partition p0 values less than (unix_timestamp('2020-04-04 00:00:00')),
   272  		partition p1 values less than (unix_timestamp('2020-04-05 00:00:00')));`)
   273  
   274  	tk.MustGetErrCode(`create causet t34 (dt timestamp(3)) partition by range (unix_timestamp(date(dt))) (
   275  		partition p0 values less than (unix_timestamp('2020-04-04 00:00:00')),
   276  		partition p1 values less than (unix_timestamp('2020-04-05 00:00:00')));`, tmysql.ErrWrongExprInPartitionFunc)
   277  
   278  	tk.MustGetErrCode(`create causet t34 (dt datetime) partition by range (unix_timestamp(dt)) (
   279  		partition p0 values less than (unix_timestamp('2020-04-04 00:00:00')),
   280  		partition p1 values less than (unix_timestamp('2020-04-05 00:00:00')));`, tmysql.ErrWrongExprInPartitionFunc)
   281  
   282  	// Fix https://github.com/whtcorpsinc/milevadb/issues/16333
   283  	tk.MustInterDirc(`create causet t35 (dt timestamp) partition by range (unix_timestamp(dt))
   284  (partition p0 values less than (unix_timestamp('2020-04-15 00:00:00')));`)
   285  
   286  	tk.MustInterDirc(`drop causet if exists too_long_identifier`)
   287  	tk.MustGetErrCode(`create causet too_long_identifier(a int)
   288  partition by range (a)
   289  (partition p0pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp values less than (10));`, tmysql.ErrTooLongIdent)
   290  
   291  	tk.MustInterDirc(`drop causet if exists too_long_identifier`)
   292  	tk.MustInterDirc("create causet too_long_identifier(a int) partition by range(a) (partition p0 values less than(10))")
   293  	tk.MustGetErrCode("alter causet too_long_identifier add partition "+
   294  		"(partition p0pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp values less than(20))", tmysql.ErrTooLongIdent)
   295  
   296  	tk.MustInterDirc(`create causet t36 (a date, b datetime) partition by range (EXTRACT(YEAR_MONTH FROM a)) (
   297      partition p0 values less than (200),
   298      partition p1 values less than (300),
   299      partition p2 values less than maxvalue)`)
   300  }
   301  
   302  func (s *testIntegrationSuite2) TestCreateBlockWithHashPartition(c *C) {
   303  	tk := testkit.NewTestKit(c, s.causetstore)
   304  	tk.MustInterDirc("use test;")
   305  	tk.MustInterDirc("drop causet if exists employees;")
   306  	tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1")
   307  	tk.MustInterDirc(`
   308  	create causet employees (
   309  		id int not null,
   310  		fname varchar(30),
   311  		lname varchar(30),
   312  		hired date not null default '1970-01-01',
   313  		separated date not null default '9999-12-31',
   314  		job_code int,
   315  		store_id int
   316  	)
   317  	partition by hash(store_id) partitions 4;`)
   318  
   319  	tk.MustInterDirc("drop causet if exists employees;")
   320  	tk.MustInterDirc(`
   321  	create causet employees (
   322  		id int not null,
   323  		fname varchar(30),
   324  		lname varchar(30),
   325  		hired date not null default '1970-01-01',
   326  		separated date not null default '9999-12-31',
   327  		job_code int,
   328  		store_id int
   329  	)
   330  	partition by hash( year(hired) ) partitions 4;`)
   331  
   332  	// This query makes milevadb OOM without partition count check.
   333  	tk.MustGetErrCode(`CREATE TABLE employees (
   334      id INT NOT NULL,
   335      fname VARCHAR(30),
   336      lname VARCHAR(30),
   337      hired DATE NOT NULL DEFAULT '1970-01-01',
   338      separated DATE NOT NULL DEFAULT '9999-12-31',
   339      job_code INT,
   340      store_id INT
   341  ) PARTITION BY HASH(store_id) PARTITIONS 102400000000;`, tmysql.ErrTooManyPartitions)
   342  
   343  	tk.MustInterDirc("CREATE TABLE t_linear (a int, b varchar(128)) PARTITION BY LINEAR HASH(a) PARTITIONS 4")
   344  	tk.MustGetErrCode("select * from t_linear partition (p0)", tmysql.ErrPartitionClauseOnNonpartitioned)
   345  
   346  	tk.MustInterDirc(`CREATE TABLE t_sub (a int, b varchar(128)) PARTITION BY RANGE( a ) SUBPARTITION BY HASH( a )
   347                                     SUBPARTITIONS 2 (
   348                                         PARTITION p0 VALUES LESS THAN (100),
   349                                         PARTITION p1 VALUES LESS THAN (200),
   350                                         PARTITION p2 VALUES LESS THAN MAXVALUE)`)
   351  	tk.MustGetErrCode("select * from t_sub partition (p0)", tmysql.ErrPartitionClauseOnNonpartitioned)
   352  
   353  	// Fix create partition causet using extract() function as partition key.
   354  	tk.MustInterDirc("create causet t2 (a date, b datetime) partition by hash (EXTRACT(YEAR_MONTH FROM a)) partitions 7")
   355  }
   356  
   357  func (s *testIntegrationSuite1) TestCreateBlockWithRangeDeferredCausetPartition(c *C) {
   358  	tk := testkit.NewTestKit(c, s.causetstore)
   359  	tk.MustInterDirc("use test;")
   360  	tk.MustInterDirc("drop causet if exists log_message_1;")
   361  	tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1")
   362  	tk.MustInterDirc(`
   363  create causet log_message_1 (
   364      add_time datetime not null default '2000-01-01 00:00:00',
   365      log_level int unsigned not null default '0',
   366      log_host varchar(32) not null,
   367      service_name varchar(32) not null,
   368      message varchar(2000)
   369  ) partition by range defCausumns(add_time)(
   370      partition p201403 values less than ('2020-04-01'),
   371      partition p201404 values less than ('2020-05-01'),
   372      partition p201405 values less than ('2020-06-01'),
   373      partition p201406 values less than ('2020-07-01'),
   374      partition p201407 values less than ('2020-08-01'),
   375      partition p201408 values less than ('2020-09-01'),
   376      partition p201409 values less than ('2020-10-01'),
   377      partition p201410 values less than ('2020-11-01')
   378  )`)
   379  	tk.MustInterDirc("drop causet if exists log_message_1;")
   380  	tk.MustInterDirc(`
   381  	create causet log_message_1 (
   382  		id int not null,
   383  		fname varchar(30),
   384  		lname varchar(30),
   385  		hired date not null default '1970-01-01',
   386  		separated date not null default '9999-12-31',
   387  		job_code int,
   388  		store_id int
   389  	)
   390  	partition by hash( year(hired) ) partitions 4;`)
   391  
   392  	tk.MustInterDirc("drop causet if exists t")
   393  
   394  	type testCase struct {
   395  		allegrosql string
   396  		err        *terror.Error
   397  	}
   398  
   399  	cases := []testCase{
   400  		{
   401  			"create causet t (id int) partition by range defCausumns (id);",
   402  			ast.ErrPartitionsMustBeDefined,
   403  		},
   404  		{
   405  			"create causet t (id int) partition by range defCausumns (id) (partition p0 values less than (1, 2));",
   406  			ast.ErrPartitionDeferredCausetList,
   407  		},
   408  		{
   409  			"create causet t (a int) partition by range defCausumns (b) (partition p0 values less than (1, 2));",
   410  			ast.ErrPartitionDeferredCausetList,
   411  		},
   412  		{
   413  			"create causet t (a int) partition by range defCausumns (b) (partition p0 values less than (1));",
   414  			dbs.ErrFieldNotFoundPart,
   415  		},
   416  		{
   417  			"create causet t (id timestamp) partition by range defCausumns (id) (partition p0 values less than ('2020-01-09 11:23:34'));",
   418  			dbs.ErrNotAllowedTypeInPartition,
   419  		},
   420  		{
   421  			`create causet t29 (
   422  				a decimal
   423  			)
   424  			partition by range defCausumns (a)
   425  			(partition p0 values less than (0));`,
   426  			dbs.ErrNotAllowedTypeInPartition,
   427  		},
   428  		{
   429  			"create causet t (id text) partition by range defCausumns (id) (partition p0 values less than ('abc'));",
   430  			dbs.ErrNotAllowedTypeInPartition,
   431  		},
   432  		// create as normal causet, warning.
   433  		//	{
   434  		//		"create causet t (a int, b varchar(64)) partition by range defCausumns (a, b) (" +
   435  		//			"partition p0 values less than (1, 'a')," +
   436  		//			"partition p1 values less than (1, 'a'))",
   437  		//		dbs.ErrRangeNotIncreasing,
   438  		//	},
   439  		{
   440  			"create causet t (a int, b varchar(64)) partition by range defCausumns ( b) (" +
   441  				"partition p0 values less than ( 'a')," +
   442  				"partition p1 values less than ('a'))",
   443  			dbs.ErrRangeNotIncreasing,
   444  		},
   445  		// create as normal causet, warning.
   446  		//	{
   447  		//		"create causet t (a int, b varchar(64)) partition by range defCausumns (a, b) (" +
   448  		//			"partition p0 values less than (1, 'b')," +
   449  		//			"partition p1 values less than (1, 'a'))",
   450  		//		dbs.ErrRangeNotIncreasing,
   451  		//	},
   452  		{
   453  			"create causet t (a int, b varchar(64)) partition by range defCausumns (b) (" +
   454  				"partition p0 values less than ('b')," +
   455  				"partition p1 values less than ('a'))",
   456  			dbs.ErrRangeNotIncreasing,
   457  		},
   458  		// create as normal causet, warning.
   459  		//		{
   460  		//			"create causet t (a int, b varchar(64)) partition by range defCausumns (a, b) (" +
   461  		//				"partition p0 values less than (1, maxvalue)," +
   462  		//				"partition p1 values less than (1, 'a'))",
   463  		//			dbs.ErrRangeNotIncreasing,
   464  		//		},
   465  		{
   466  			"create causet t (a int, b varchar(64)) partition by range defCausumns ( b) (" +
   467  				"partition p0 values less than (  maxvalue)," +
   468  				"partition p1 values less than ('a'))",
   469  			dbs.ErrRangeNotIncreasing,
   470  		},
   471  		{
   472  			"create causet t (defCaus datetime not null default '2000-01-01')" +
   473  				"partition by range defCausumns (defCaus) (" +
   474  				"PARTITION p0 VALUES LESS THAN (20190905)," +
   475  				"PARTITION p1 VALUES LESS THAN (20190906));",
   476  			dbs.ErrWrongTypeDeferredCausetValue,
   477  		},
   478  	}
   479  	for i, t := range cases {
   480  		_, err := tk.InterDirc(t.allegrosql)
   481  		c.Assert(t.err.Equal(err), IsTrue, Commentf(
   482  			"case %d fail, allegrosql = `%s`\nexpected error = `%v`\n  actual error = `%v`",
   483  			i, t.allegrosql, t.err, err,
   484  		))
   485  	}
   486  
   487  	tk.MustInterDirc("create causet t1 (a int, b char(3)) partition by range defCausumns (a, b) (" +
   488  		"partition p0 values less than (1, 'a')," +
   489  		"partition p1 values less than (2, maxvalue))")
   490  
   491  	tk.MustInterDirc("create causet t2 (a int, b char(3)) partition by range defCausumns (b) (" +
   492  		"partition p0 values less than ( 'a')," +
   493  		"partition p1 values less than (maxvalue))")
   494  }
   495  
   496  func (s *testIntegrationSuite3) TestCreateBlockWithKeyPartition(c *C) {
   497  	tk := testkit.NewTestKit(c, s.causetstore)
   498  	tk.MustInterDirc("use test;")
   499  	tk.MustInterDirc("drop causet if exists tm1;")
   500  	tk.MustInterDirc(`create causet tm1
   501  	(
   502  		s1 char(32) primary key
   503  	)
   504  	partition by key(s1) partitions 10;`)
   505  
   506  	tk.MustInterDirc(`drop causet if exists tm2`)
   507  	tk.MustInterDirc(`create causet tm2 (a char(5), unique key(a(5))) partition by key() partitions 5;`)
   508  }
   509  
   510  func (s *testIntegrationSuite5) TestAlterBlockAddPartition(c *C) {
   511  	tk := testkit.NewTestKit(c, s.causetstore)
   512  	tk.MustInterDirc("use test;")
   513  	tk.MustInterDirc("drop causet if exists employees;")
   514  	tk.MustInterDirc(`create causet employees (
   515  	id int not null,
   516  	hired date not null
   517  	)
   518  	partition by range( year(hired) ) (
   519  		partition p1 values less than (1991),
   520  		partition p2 values less than (1996),
   521  		partition p3 values less than (2001)
   522  	);`)
   523  	tk.MustInterDirc(`alter causet employees add partition (
   524      partition p4 values less than (2010),
   525      partition p5 values less than MAXVALUE
   526  	);`)
   527  
   528  	ctx := tk.Se.(stochastikctx.Context)
   529  	is := petri.GetPetri(ctx).SchemaReplicant()
   530  	tbl, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("employees"))
   531  	c.Assert(err, IsNil)
   532  	c.Assert(tbl.Meta().Partition, NotNil)
   533  	part := tbl.Meta().Partition
   534  	c.Assert(part.Type, Equals, perceptron.PartitionTypeRange)
   535  
   536  	c.Assert(part.Expr, Equals, "YEAR(`hired`)")
   537  	c.Assert(part.Definitions, HasLen, 5)
   538  	c.Assert(part.Definitions[0].LessThan[0], Equals, "1991")
   539  	c.Assert(part.Definitions[0].Name, Equals, perceptron.NewCIStr("p1"))
   540  	c.Assert(part.Definitions[1].LessThan[0], Equals, "1996")
   541  	c.Assert(part.Definitions[1].Name, Equals, perceptron.NewCIStr("p2"))
   542  	c.Assert(part.Definitions[2].LessThan[0], Equals, "2001")
   543  	c.Assert(part.Definitions[2].Name, Equals, perceptron.NewCIStr("p3"))
   544  	c.Assert(part.Definitions[3].LessThan[0], Equals, "2010")
   545  	c.Assert(part.Definitions[3].Name, Equals, perceptron.NewCIStr("p4"))
   546  	c.Assert(part.Definitions[4].LessThan[0], Equals, "MAXVALUE")
   547  	c.Assert(part.Definitions[4].Name, Equals, perceptron.NewCIStr("p5"))
   548  
   549  	tk.MustInterDirc("drop causet if exists block1;")
   550  	tk.MustInterDirc("create causet block1(a int)")
   551  	sql1 := `alter causet block1 add partition (
   552  		partition p1 values less than (2010),
   553  		partition p2 values less than maxvalue
   554  	);`
   555  	tk.MustGetErrCode(sql1, tmysql.ErrPartitionMgmtOnNonpartitioned)
   556  	tk.MustInterDirc(`create causet block_MustBeDefined (
   557  	id int not null,
   558  	hired date not null
   559  	)
   560  	partition by range( year(hired) ) (
   561  		partition p1 values less than (1991),
   562  		partition p2 values less than (1996),
   563  		partition p3 values less than (2001)
   564  	);`)
   565  	sql2 := "alter causet block_MustBeDefined add partition"
   566  	tk.MustGetErrCode(sql2, tmysql.ErrPartitionsMustBeDefined)
   567  	tk.MustInterDirc("drop causet if exists block2;")
   568  	tk.MustInterDirc(`create causet block2 (
   569  
   570  	id int not null,
   571  	hired date not null
   572  	)
   573  	partition by range( year(hired) ) (
   574  	partition p1 values less than (1991),
   575  	partition p2 values less than maxvalue
   576  	);`)
   577  
   578  	sql3 := `alter causet block2 add partition (
   579  		partition p3 values less than (2010)
   580  	);`
   581  	tk.MustGetErrCode(sql3, tmysql.ErrPartitionMaxvalue)
   582  
   583  	tk.MustInterDirc("drop causet if exists block3;")
   584  	tk.MustInterDirc(`create causet block3 (
   585  	id int not null,
   586  	hired date not null
   587  	)
   588  	partition by range( year(hired) ) (
   589  	partition p1 values less than (1991),
   590  	partition p2 values less than (2001)
   591  	);`)
   592  
   593  	sql4 := `alter causet block3 add partition (
   594  		partition p3 values less than (1993)
   595  	);`
   596  	tk.MustGetErrCode(sql4, tmysql.ErrRangeNotIncreasing)
   597  
   598  	sql5 := `alter causet block3 add partition (
   599  		partition p1 values less than (1993)
   600  	);`
   601  	tk.MustGetErrCode(sql5, tmysql.ErrSameNamePartition)
   602  
   603  	sql6 := `alter causet block3 add partition (
   604  		partition p1 values less than (1993),
   605  		partition p1 values less than (1995)
   606  	);`
   607  	tk.MustGetErrCode(sql6, tmysql.ErrSameNamePartition)
   608  
   609  	sql7 := `alter causet block3 add partition (
   610  		partition p4 values less than (1993),
   611  		partition p1 values less than (1995),
   612  		partition p5 values less than maxvalue
   613  	);`
   614  	tk.MustGetErrCode(sql7, tmysql.ErrSameNamePartition)
   615  
   616  	sql8 := "alter causet block3 add partition (partition p6);"
   617  	tk.MustGetErrCode(sql8, tmysql.ErrPartitionRequiresValues)
   618  
   619  	sql9 := "alter causet block3 add partition (partition p7 values in (2020));"
   620  	tk.MustGetErrCode(sql9, tmysql.ErrPartitionWrongValues)
   621  
   622  	sql10 := "alter causet block3 add partition partitions 4;"
   623  	tk.MustGetErrCode(sql10, tmysql.ErrPartitionsMustBeDefined)
   624  
   625  	tk.MustInterDirc("alter causet block3 add partition (partition p3 values less than (2001 + 10))")
   626  
   627  	// less than value can be negative or memex.
   628  	tk.MustInterDirc(`CREATE TABLE tt5 (
   629  		c3 bigint(20) NOT NULL
   630  	) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
   631  	PARTITION BY RANGE ( c3 ) (
   632  		PARTITION p0 VALUES LESS THAN (-3),
   633  		PARTITION p1 VALUES LESS THAN (-2)
   634  	);`)
   635  	tk.MustInterDirc(`ALTER TABLE tt5 add partition ( partition p2 values less than (-1) );`)
   636  	tk.MustInterDirc(`ALTER TABLE tt5 add partition ( partition p3 values less than (5-1) );`)
   637  
   638  	// Test add partition for the causet partition by range defCausumns.
   639  	tk.MustInterDirc("drop causet if exists t;")
   640  	tk.MustInterDirc("create causet t (a datetime) partition by range defCausumns (a) (partition p1 values less than ('2020-06-01'), partition p2 values less than ('2020-07-01'));")
   641  	allegrosql := "alter causet t add partition ( partition p3 values less than ('2020-07-01'));"
   642  	tk.MustGetErrCode(allegrosql, tmysql.ErrRangeNotIncreasing)
   643  	tk.MustInterDirc("alter causet t add partition ( partition p3 values less than ('2020-08-01'));")
   644  
   645  	// Add partition value's type should be the same with the defCausumn's type.
   646  	tk.MustInterDirc("drop causet if exists t;")
   647  	tk.MustInterDirc(`create causet t (
   648  		defCaus date not null default '2000-01-01')
   649                  partition by range defCausumns (defCaus) (
   650  		PARTITION p0 VALUES LESS THAN ('20190905'),
   651  		PARTITION p1 VALUES LESS THAN ('20190906'));`)
   652  	allegrosql = "alter causet t add partition (partition p2 values less than (20190907));"
   653  	tk.MustGetErrCode(allegrosql, tmysql.ErrWrongTypeDeferredCausetValue)
   654  }
   655  
   656  func (s *testIntegrationSuite5) TestAlterBlockDropPartition(c *C) {
   657  	tk := testkit.NewTestKit(c, s.causetstore)
   658  	tk.MustInterDirc("use test")
   659  	tk.MustInterDirc("drop causet if exists employees")
   660  	tk.MustInterDirc(`create causet employees (
   661  	id int not null,
   662  	hired int not null
   663  	)
   664  	partition by range( hired ) (
   665  		partition p1 values less than (1991),
   666  		partition p2 values less than (1996),
   667  		partition p3 values less than (2001)
   668  	);`)
   669  
   670  	tk.MustInterDirc("alter causet employees drop partition p3;")
   671  	ctx := tk.Se.(stochastikctx.Context)
   672  	is := petri.GetPetri(ctx).SchemaReplicant()
   673  	tbl, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("employees"))
   674  	c.Assert(err, IsNil)
   675  	c.Assert(tbl.Meta().GetPartitionInfo(), NotNil)
   676  	part := tbl.Meta().Partition
   677  	c.Assert(part.Type, Equals, perceptron.PartitionTypeRange)
   678  	c.Assert(part.Expr, Equals, "`hired`")
   679  	c.Assert(part.Definitions, HasLen, 2)
   680  	c.Assert(part.Definitions[0].LessThan[0], Equals, "1991")
   681  	c.Assert(part.Definitions[0].Name, Equals, perceptron.NewCIStr("p1"))
   682  	c.Assert(part.Definitions[1].LessThan[0], Equals, "1996")
   683  	c.Assert(part.Definitions[1].Name, Equals, perceptron.NewCIStr("p2"))
   684  
   685  	tk.MustInterDirc("drop causet if exists block1;")
   686  	tk.MustInterDirc("create causet block1 (a int);")
   687  	sql1 := "alter causet block1 drop partition p10;"
   688  	tk.MustGetErrCode(sql1, tmysql.ErrPartitionMgmtOnNonpartitioned)
   689  
   690  	tk.MustInterDirc("drop causet if exists block2;")
   691  	tk.MustInterDirc(`create causet block2 (
   692  	id int not null,
   693  	hired date not null
   694  	)
   695  	partition by range( year(hired) ) (
   696  		partition p1 values less than (1991),
   697  		partition p2 values less than (1996),
   698  		partition p3 values less than (2001)
   699  	);`)
   700  	sql2 := "alter causet block2 drop partition p10;"
   701  	tk.MustGetErrCode(sql2, tmysql.ErrDropPartitionNonExistent)
   702  
   703  	tk.MustInterDirc("drop causet if exists block3;")
   704  	tk.MustInterDirc(`create causet block3 (
   705  	id int not null
   706  	)
   707  	partition by range( id ) (
   708  		partition p1 values less than (1991)
   709  	);`)
   710  	sql3 := "alter causet block3 drop partition p1;"
   711  	tk.MustGetErrCode(sql3, tmysql.ErrDropLastPartition)
   712  
   713  	tk.MustInterDirc("drop causet if exists block4;")
   714  	tk.MustInterDirc(`create causet block4 (
   715  	id int not null
   716  	)
   717  	partition by range( id ) (
   718  		partition p1 values less than (10),
   719  		partition p2 values less than (20),
   720  		partition p3 values less than MAXVALUE
   721  	);`)
   722  
   723  	tk.MustInterDirc("alter causet block4 drop partition p2;")
   724  	is = petri.GetPetri(ctx).SchemaReplicant()
   725  	tbl, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("block4"))
   726  	c.Assert(err, IsNil)
   727  	c.Assert(tbl.Meta().GetPartitionInfo(), NotNil)
   728  	part = tbl.Meta().Partition
   729  	c.Assert(part.Type, Equals, perceptron.PartitionTypeRange)
   730  	c.Assert(part.Expr, Equals, "`id`")
   731  	c.Assert(part.Definitions, HasLen, 2)
   732  	c.Assert(part.Definitions[0].LessThan[0], Equals, "10")
   733  	c.Assert(part.Definitions[0].Name, Equals, perceptron.NewCIStr("p1"))
   734  	c.Assert(part.Definitions[1].LessThan[0], Equals, "MAXVALUE")
   735  	c.Assert(part.Definitions[1].Name, Equals, perceptron.NewCIStr("p3"))
   736  
   737  	tk.MustInterDirc("drop causet if exists tr;")
   738  	tk.MustInterDirc(` create causet tr(
   739  		id int, name varchar(50),
   740  		purchased date
   741  	)
   742  	partition by range( year(purchased) ) (
   743      	partition p0 values less than (1990),
   744      	partition p1 values less than (1995),
   745      	partition p2 values less than (2000),
   746      	partition p3 values less than (2005),
   747      	partition p4 values less than (2010),
   748      	partition p5 values less than (2020)
   749     	);`)
   750  	tk.MustInterDirc(`INSERT INTO tr VALUES
   751  	(1, 'desk organiser', '2003-10-15'),
   752  	(2, 'alarm clock', '1997-11-05'),
   753  	(3, 'chair', '2009-03-10'),
   754  	(4, 'bookcase', '1989-01-10'),
   755  	(5, 'exercise bike', '2020-05-09'),
   756  	(6, 'sofa', '1987-06-05'),
   757  	(7, 'espresso maker', '2011-11-22'),
   758  	(8, 'aquarium', '1992-08-04'),
   759  	(9, 'study desk', '2006-09-16'),
   760  	(10, 'lava lamp', '1998-12-25');`)
   761  	result := tk.MustQuery("select * from tr where purchased between '1995-01-01' and '1999-12-31';")
   762  	result.Check(testkit.Rows(`2 alarm clock 1997-11-05`, `10 lava lamp 1998-12-25`))
   763  	tk.MustInterDirc("alter causet tr drop partition p2;")
   764  	result = tk.MustQuery("select * from tr where purchased between '1995-01-01' and '1999-12-31';")
   765  	result.Check(testkit.Rows())
   766  
   767  	result = tk.MustQuery("select * from tr where purchased between '2010-01-01' and '2020-12-31';")
   768  	result.Check(testkit.Rows(`5 exercise bike 2020-05-09`, `7 espresso maker 2011-11-22`))
   769  	tk.MustInterDirc("alter causet tr drop partition p5;")
   770  	result = tk.MustQuery("select * from tr where purchased between '2010-01-01' and '2020-12-31';")
   771  	result.Check(testkit.Rows())
   772  
   773  	tk.MustInterDirc("alter causet tr drop partition p4;")
   774  	result = tk.MustQuery("select * from tr where purchased between '2005-01-01' and '2009-12-31';")
   775  	result.Check(testkit.Rows())
   776  
   777  	tk.MustInterDirc("drop causet if exists block4;")
   778  	tk.MustInterDirc(`create causet block4 (
   779  		id int not null
   780  	)
   781  	partition by range( id ) (
   782  		partition Par1 values less than (1991),
   783  		partition pAR2 values less than (1992),
   784  		partition Par3 values less than (1995),
   785  		partition PaR5 values less than (1996)
   786  	);`)
   787  	tk.MustInterDirc("alter causet block4 drop partition Par2;")
   788  	tk.MustInterDirc("alter causet block4 drop partition PAR5;")
   789  	sql4 := "alter causet block4 drop partition PAR0;"
   790  	tk.MustGetErrCode(sql4, tmysql.ErrDropPartitionNonExistent)
   791  
   792  	tk.MustInterDirc("CREATE TABLE t1 (a int(11), b varchar(64)) PARTITION BY HASH(a) PARTITIONS 3")
   793  	tk.MustGetErrCode("alter causet t1 drop partition p2", tmysql.ErrOnlyOnRangeListPartition)
   794  }
   795  
   796  func (s *testIntegrationSuite5) TestMultiPartitionDropAndTruncate(c *C) {
   797  	tk := testkit.NewTestKit(c, s.causetstore)
   798  	tk.MustInterDirc("use test")
   799  	tk.MustInterDirc("drop causet if exists employees")
   800  	tk.MustInterDirc(`create causet employees (
   801  	hired int not null
   802  	)
   803  	partition by range( hired ) (
   804  		partition p1 values less than (1991),
   805  		partition p2 values less than (1996),
   806  		partition p3 values less than (2001),
   807  		partition p4 values less than (2006),
   808  		partition p5 values less than (2011)
   809  	);`)
   810  	tk.MustInterDirc(`INSERT INTO employees VALUES (1990), (1995), (2000), (2005), (2010)`)
   811  
   812  	tk.MustInterDirc("alter causet employees drop partition p1, p2;")
   813  	result := tk.MustQuery("select * from employees;")
   814  	result.Sort().Check(testkit.Rows(`2000`, `2005`, `2010`))
   815  
   816  	tk.MustInterDirc("alter causet employees truncate partition p3, p4")
   817  	result = tk.MustQuery("select * from employees;")
   818  	result.Check(testkit.Rows(`2010`))
   819  }
   820  
   821  func (s *testIntegrationSuite7) TestAlterBlockExchangePartition(c *C) {
   822  	tk := testkit.NewTestKit(c, s.causetstore)
   823  	tk.MustInterDirc("use test")
   824  	tk.MustInterDirc("drop causet if exists e")
   825  	tk.MustInterDirc("drop causet if exists e2")
   826  	tk.MustInterDirc(`CREATE TABLE e (
   827  		id INT NOT NULL
   828  	)
   829      PARTITION BY RANGE (id) (
   830          PARTITION p0 VALUES LESS THAN (50),
   831          PARTITION p1 VALUES LESS THAN (100),
   832          PARTITION p2 VALUES LESS THAN (150),
   833          PARTITION p3 VALUES LESS THAN (MAXVALUE)
   834  	);`)
   835  	tk.MustInterDirc(`CREATE TABLE e2 (
   836  		id INT NOT NULL
   837  	);`)
   838  	tk.MustInterDirc(`INSERT INTO e VALUES (1669),(337),(16),(2005)`)
   839  	tk.MustInterDirc("ALTER TABLE e EXCHANGE PARTITION p0 WITH TABLE e2")
   840  	tk.MustQuery("select * from e2").Check(testkit.Rows("16"))
   841  	tk.MustQuery("select * from e").Check(testkit.Rows("1669", "337", "2005"))
   842  	// validation test for range partition
   843  	tk.MustGetErrCode("ALTER TABLE e EXCHANGE PARTITION p1 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition)
   844  	tk.MustGetErrCode("ALTER TABLE e EXCHANGE PARTITION p2 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition)
   845  	tk.MustGetErrCode("ALTER TABLE e EXCHANGE PARTITION p3 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition)
   846  
   847  	tk.MustInterDirc("drop causet if exists e3")
   848  
   849  	tk.MustInterDirc(`CREATE TABLE e3 (
   850  		id int not null
   851  	) PARTITION BY HASH (id)
   852  	PARTITIONS 4;`)
   853  	tk.MustGetErrCode("ALTER TABLE e EXCHANGE PARTITION p1 WITH TABLE e3;", tmysql.ErrPartitionExchangePartBlock)
   854  	tk.MustInterDirc("truncate causet e2")
   855  	tk.MustInterDirc(`INSERT INTO e3 VALUES (1),(5)`)
   856  
   857  	tk.MustInterDirc("ALTER TABLE e3 EXCHANGE PARTITION p1 WITH TABLE e2;")
   858  	tk.MustQuery("select * from e3 partition(p0)").Check(testkit.Rows())
   859  	tk.MustQuery("select * from e2").Check(testkit.Rows("1", "5"))
   860  
   861  	// validation test for hash partition
   862  	tk.MustGetErrCode("ALTER TABLE e3 EXCHANGE PARTITION p0 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition)
   863  	tk.MustGetErrCode("ALTER TABLE e3 EXCHANGE PARTITION p2 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition)
   864  	tk.MustGetErrCode("ALTER TABLE e3 EXCHANGE PARTITION p3 WITH TABLE e2", tmysql.ErrRowDoesNotMatchPartition)
   865  
   866  	// without validation test
   867  	tk.MustInterDirc("ALTER TABLE e3 EXCHANGE PARTITION p0 with TABLE e2 WITHOUT VALIDATION")
   868  
   869  	tk.MustQuery("select * from e3 partition(p0)").Check(testkit.Rows("1", "5"))
   870  	tk.MustQuery("select * from e2").Check(testkit.Rows())
   871  
   872  	// more boundary test of range partition
   873  	// for partition p0
   874  	tk.MustInterDirc(`create causet e4 (a int) partition by range(a) (
   875  		partition p0 values less than (3),
   876  		partition p1 values less than (6),
   877          PARTITION p2 VALUES LESS THAN (9),
   878          PARTITION p3 VALUES LESS THAN (MAXVALUE)
   879  		);`)
   880  	tk.MustInterDirc(`create causet e5(a int);`)
   881  
   882  	tk.MustInterDirc("insert into e5 values (1)")
   883  
   884  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p1 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   885  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p2 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   886  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p3 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   887  	tk.MustInterDirc("ALTER TABLE e4 EXCHANGE PARTITION p0 with TABLE e5")
   888  	tk.MustQuery("select * from e4 partition(p0)").Check(testkit.Rows("1"))
   889  
   890  	// for partition p1
   891  	tk.MustInterDirc("insert into e5 values (3)")
   892  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p0 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   893  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p2 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   894  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p3 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   895  	tk.MustInterDirc("ALTER TABLE e4 EXCHANGE PARTITION p1 with TABLE e5")
   896  	tk.MustQuery("select * from e4 partition(p1)").Check(testkit.Rows("3"))
   897  
   898  	// for partition p2
   899  	tk.MustInterDirc("insert into e5 values (6)")
   900  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p0 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   901  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p1 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   902  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p3 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   903  	tk.MustInterDirc("ALTER TABLE e4 EXCHANGE PARTITION p2 with TABLE e5")
   904  	tk.MustQuery("select * from e4 partition(p2)").Check(testkit.Rows("6"))
   905  
   906  	// for partition p3
   907  	tk.MustInterDirc("insert into e5 values (9)")
   908  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p0 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   909  	tk.MustGetErrCode("ALTER TABLE e4 EXCHANGE PARTITION p1 WITH TABLE e5", tmysql.ErrRowDoesNotMatchPartition)
   910  	tk.MustGetErrCode("alter causet e4 exchange partition p2 with causet e5", tmysql.ErrRowDoesNotMatchPartition)
   911  	tk.MustInterDirc("ALTER TABLE e4 EXCHANGE PARTITION p3 with TABLE e5")
   912  	tk.MustQuery("select * from e4 partition(p3)").Check(testkit.Rows("9"))
   913  
   914  	// for defCausumns range partition
   915  	tk.MustInterDirc(`create causet e6 (a varchar(3)) partition by range defCausumns (a) (
   916  		partition p0 values less than ('3'),
   917  		partition p1 values less than ('6')
   918  	);`)
   919  	tk.MustInterDirc(`create causet e7 (a varchar(3));`)
   920  	tk.MustInterDirc(`insert into e6 values ('1');`)
   921  	tk.MustInterDirc(`insert into e7 values ('2');`)
   922  	tk.MustInterDirc("alter causet e6 exchange partition p0 with causet e7")
   923  
   924  	tk.MustQuery("select * from e6 partition(p0)").Check(testkit.Rows("2"))
   925  	tk.MustQuery("select * from e7").Check(testkit.Rows("1"))
   926  	tk.MustGetErrCode("alter causet e6 exchange partition p1 with causet e7", tmysql.ErrRowDoesNotMatchPartition)
   927  
   928  	// test exchange partition from different databases
   929  	tk.MustInterDirc("create causet e8 (a int) partition by hash(a) partitions 2;")
   930  	tk.MustInterDirc("create database if not exists exchange_partition")
   931  	tk.MustInterDirc("insert into e8 values (1), (3), (5)")
   932  	tk.MustInterDirc("use exchange_partition;")
   933  	tk.MustInterDirc("create causet e9 (a int);")
   934  	tk.MustInterDirc("insert into e9 values (7), (9)")
   935  	tk.MustInterDirc("alter causet test.e8 exchange partition p1 with causet e9")
   936  
   937  	tk.MustInterDirc("insert into e9 values (11)")
   938  	tk.MustQuery("select * from e9").Check(testkit.Rows("1", "3", "5", "11"))
   939  	tk.MustInterDirc("insert into test.e8 values (11)")
   940  	tk.MustQuery("select * from test.e8").Check(testkit.Rows("7", "9", "11"))
   941  
   942  	tk.MustInterDirc("use test")
   943  	tk.MustInterDirc("create causet e10 (a int) partition by hash(a) partitions 2")
   944  	tk.MustInterDirc("insert into e10 values (0), (2), (4)")
   945  	tk.MustInterDirc("create causet e11 (a int)")
   946  	tk.MustInterDirc("insert into e11 values (1), (3)")
   947  	tk.MustInterDirc("alter causet e10 exchange partition p1 with causet e11")
   948  	tk.MustInterDirc("insert into e11 values (5)")
   949  	tk.MustQuery("select * from e11").Check(testkit.Rows("5"))
   950  	tk.MustInterDirc("insert into e10 values (5), (6)")
   951  	tk.MustQuery("select * from e10 partition(p0)").Check(testkit.Rows("0", "2", "4", "6"))
   952  	tk.MustQuery("select * from e10 partition(p1)").Check(testkit.Rows("1", "3", "5"))
   953  
   954  	// test for defCausumn id
   955  	tk.MustInterDirc("create causet e12 (a int(1), b int, index (a)) partition by hash(a) partitions 3")
   956  	tk.MustInterDirc("create causet e13 (a int(8), b int, index (a));")
   957  	tk.MustInterDirc("alter causet e13 drop defCausumn b")
   958  	tk.MustInterDirc("alter causet e13 add defCausumn b int")
   959  	tk.MustGetErrCode("alter causet e12 exchange partition p0 with causet e13", tmysql.ErrPartitionExchangeDifferentOption)
   960  	// test for index id
   961  	tk.MustInterDirc("create causet e14 (a int, b int, index(a));")
   962  	tk.MustInterDirc("alter causet e12 drop index a")
   963  	tk.MustInterDirc("alter causet e12 add index (a);")
   964  	tk.MustGetErrCode("alter causet e12 exchange partition p0 with causet e14", tmysql.ErrPartitionExchangeDifferentOption)
   965  
   966  	// test for tiflash replica
   967  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil)
   968  	defer failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount")
   969  
   970  	tk.MustInterDirc("create causet e15 (a int) partition by hash(a) partitions 1;")
   971  	tk.MustInterDirc("create causet e16 (a int)")
   972  	tk.MustInterDirc("alter causet e15 set tiflash replica 1;")
   973  	tk.MustInterDirc("alter causet e16 set tiflash replica 2;")
   974  
   975  	e15 := testGetBlockByName(c, s.ctx, "test", "e15")
   976  	partition := e15.Meta().Partition
   977  
   978  	err := petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true)
   979  	c.Assert(err, IsNil)
   980  
   981  	e16 := testGetBlockByName(c, s.ctx, "test", "e16")
   982  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, e16.Meta().ID, true)
   983  	c.Assert(err, IsNil)
   984  
   985  	tk.MustGetErrCode("alter causet e15 exchange partition p0 with causet e16", tmysql.ErrBlocksDifferentMetadata)
   986  	tk.MustInterDirc("drop causet e15, e16")
   987  
   988  	tk.MustInterDirc("create causet e15 (a int) partition by hash(a) partitions 1;")
   989  	tk.MustInterDirc("create causet e16 (a int)")
   990  	tk.MustInterDirc("alter causet e15 set tiflash replica 1;")
   991  	tk.MustInterDirc("alter causet e16 set tiflash replica 1;")
   992  
   993  	e15 = testGetBlockByName(c, s.ctx, "test", "e15")
   994  	partition = e15.Meta().Partition
   995  
   996  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true)
   997  	c.Assert(err, IsNil)
   998  
   999  	e16 = testGetBlockByName(c, s.ctx, "test", "e16")
  1000  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, e16.Meta().ID, true)
  1001  	c.Assert(err, IsNil)
  1002  
  1003  	tk.MustInterDirc("alter causet e15 exchange partition p0 with causet e16")
  1004  
  1005  	e15 = testGetBlockByName(c, s.ctx, "test", "e15")
  1006  
  1007  	partition = e15.Meta().Partition
  1008  
  1009  	c.Assert(e15.Meta().TiFlashReplica, NotNil)
  1010  	c.Assert(e15.Meta().TiFlashReplica.Available, IsTrue)
  1011  	c.Assert(e15.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID})
  1012  
  1013  	e16 = testGetBlockByName(c, s.ctx, "test", "e16")
  1014  	c.Assert(e16.Meta().TiFlashReplica, NotNil)
  1015  	c.Assert(e16.Meta().TiFlashReplica.Available, IsTrue)
  1016  
  1017  	tk.MustInterDirc("drop causet e15, e16")
  1018  	tk.MustInterDirc("create causet e15 (a int) partition by hash(a) partitions 1;")
  1019  	tk.MustInterDirc("create causet e16 (a int)")
  1020  	tk.MustInterDirc("alter causet e16 set tiflash replica 1;")
  1021  
  1022  	tk.MustInterDirc("alter causet e15 set tiflash replica 1 location labels 'a', 'b';")
  1023  
  1024  	tk.MustGetErrCode("alter causet e15 exchange partition p0 with causet e16", tmysql.ErrBlocksDifferentMetadata)
  1025  
  1026  	tk.MustInterDirc("alter causet e16 set tiflash replica 1 location labels 'a', 'b';")
  1027  
  1028  	e15 = testGetBlockByName(c, s.ctx, "test", "e15")
  1029  	partition = e15.Meta().Partition
  1030  
  1031  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true)
  1032  	c.Assert(err, IsNil)
  1033  
  1034  	e16 = testGetBlockByName(c, s.ctx, "test", "e16")
  1035  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, e16.Meta().ID, true)
  1036  	c.Assert(err, IsNil)
  1037  
  1038  	tk.MustInterDirc("alter causet e15 exchange partition p0 with causet e16")
  1039  }
  1040  
  1041  func (s *testIntegrationSuite4) TestExchangePartitionBlockCompatiable(c *C) {
  1042  	type testCase struct {
  1043  		ptALLEGROSQL       string
  1044  		ntALLEGROSQL       string
  1045  		exchangeALLEGROSQL string
  1046  		err                *terror.Error
  1047  	}
  1048  	cases := []testCase{
  1049  		{
  1050  			"create causet pt (id int not null) partition by hash (id) partitions 4;",
  1051  			"create causet nt (id int(1) not null);",
  1052  			"alter causet pt exchange partition p0 with causet nt;",
  1053  			nil,
  1054  		},
  1055  		{
  1056  			"create causet pt1 (id int not null, fname varchar(3)) partition by hash (id) partitions 4;",
  1057  			"create causet nt1 (id int not null, fname varchar(4));",
  1058  			"alter causet pt1 exchange partition p0 with causet nt1;",
  1059  			dbs.ErrBlocksDifferentMetadata,
  1060  		},
  1061  		{
  1062  			"create causet pt2 (id int not null, salary decimal) partition by hash(id) partitions 4;",
  1063  			"create causet nt2 (id int not null, salary decimal(3,2));",
  1064  			"alter causet pt2 exchange partition p0 with causet nt2;",
  1065  			dbs.ErrBlocksDifferentMetadata,
  1066  		},
  1067  		{
  1068  			"create causet pt3 (id int not null, salary decimal) partition by hash(id) partitions 1;",
  1069  			"create causet nt3 (id int not null, salary decimal(10, 1));",
  1070  			"alter causet pt3 exchange partition p0 with causet nt3",
  1071  			dbs.ErrBlocksDifferentMetadata,
  1072  		},
  1073  		{
  1074  			"create causet pt4 (id int not null) partition by hash(id) partitions 1;",
  1075  			"create causet nt4 (id1 int not null);",
  1076  			"alter causet pt4 exchange partition p0 with causet nt4;",
  1077  			dbs.ErrBlocksDifferentMetadata,
  1078  		},
  1079  		{
  1080  			"create causet pt5 (id int not null, primary key (id)) partition by hash(id) partitions 1;",
  1081  			"create causet nt5 (id int not null);",
  1082  			"alter causet pt5 exchange partition p0 with causet nt5;",
  1083  			dbs.ErrBlocksDifferentMetadata,
  1084  		},
  1085  		{
  1086  			"create causet pt6 (id int not null, salary decimal, index idx (id, salary)) partition by hash(id) partitions 1;",
  1087  			"create causet nt6 (id int not null, salary decimal, index idx (salary, id));",
  1088  			"alter causet pt6 exchange partition p0 with causet nt6;",
  1089  			dbs.ErrBlocksDifferentMetadata,
  1090  		},
  1091  		{
  1092  			"create causet pt7 (id int not null, index idx (id) invisible) partition by hash(id) partitions 1;",
  1093  			"create causet nt7 (id int not null, index idx (id));",
  1094  			"alter causet pt7 exchange partition p0 with causet nt7;",
  1095  			nil,
  1096  		},
  1097  		{
  1098  			"create causet pt8 (id int not null, index idx (id)) partition by hash(id) partitions 1;",
  1099  			"create causet nt8 (id int not null, index id_idx (id));",
  1100  			"alter causet pt8 exchange partition p0 with causet nt8;",
  1101  			dbs.ErrBlocksDifferentMetadata,
  1102  		},
  1103  		{
  1104  			// foreign key test
  1105  			// Partition causet doesn't support to add foreign keys in allegrosql
  1106  			"create causet pt9 (id int not null primary key auto_increment,t_id int not null) partition by hash(id) partitions 1;",
  1107  			"create causet nt9 (id int not null primary key auto_increment, t_id int not null,foreign key fk_id (t_id) references pt5(id));",
  1108  			"alter causet pt9 exchange partition p0 with causet nt9;",
  1109  			dbs.ErrPartitionExchangeForeignKey,
  1110  		},
  1111  		{
  1112  			// Generated defCausumn (virtual)
  1113  			"create causet pt10 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname,' ')) virtual) partition by hash(id) partitions 1;",
  1114  			"create causet nt10 (id int not null, lname varchar(30), fname varchar(100));",
  1115  			"alter causet pt10 exchange partition p0 with causet nt10;",
  1116  			dbs.ErrUnsupportedOnGeneratedDeferredCauset,
  1117  		},
  1118  		{
  1119  			"create causet pt11 (id int not null, lname varchar(30), fname varchar(100)) partition by hash(id) partitions 1;",
  1120  			"create causet nt11 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) virtual);",
  1121  			"alter causet pt11 exchange partition p0 with causet nt11;",
  1122  			dbs.ErrUnsupportedOnGeneratedDeferredCauset,
  1123  		},
  1124  		{
  1125  
  1126  			"create causet pt12 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname,' ')) stored) partition by hash(id) partitions 1;",
  1127  			"create causet nt12 (id int not null, lname varchar(30), fname varchar(100));",
  1128  			"alter causet pt12 exchange partition p0 with causet nt12;",
  1129  			dbs.ErrBlocksDifferentMetadata,
  1130  		},
  1131  		{
  1132  			"create causet pt13 (id int not null, lname varchar(30), fname varchar(100)) partition by hash(id) partitions 1;",
  1133  			"create causet nt13 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) stored);",
  1134  			"alter causet pt13 exchange partition p0 with causet nt13;",
  1135  			dbs.ErrBlocksDifferentMetadata,
  1136  		},
  1137  		{
  1138  			"create causet pt14 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) virtual) partition by hash(id) partitions 1;",
  1139  			"create causet nt14 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) virtual);",
  1140  			"alter causet pt14 exchange partition p0 with causet nt14;",
  1141  			nil,
  1142  		},
  1143  		{
  1144  			// unique index
  1145  			"create causet pt15 (id int not null, unique index uk_id (id)) partition by hash(id) partitions 1;",
  1146  			"create causet nt15 (id int not null, index uk_id (id));",
  1147  			"alter causet pt15 exchange partition p0 with causet nt15",
  1148  			dbs.ErrBlocksDifferentMetadata,
  1149  		},
  1150  		{
  1151  			// auto_increment
  1152  			"create causet pt16 (id int not null primary key auto_increment) partition by hash(id) partitions 1;",
  1153  			"create causet nt16 (id int not null primary key);",
  1154  			"alter causet pt16 exchange partition p0 with causet nt16;",
  1155  			dbs.ErrBlocksDifferentMetadata,
  1156  		},
  1157  		{
  1158  			// default
  1159  			"create causet pt17 (id int not null default 1) partition by hash(id) partitions 1;",
  1160  			"create causet nt17 (id int not null);",
  1161  			"alter causet pt17 exchange partition p0 with causet nt17;",
  1162  			nil,
  1163  		},
  1164  		{
  1165  			// view test
  1166  			"create causet pt18 (id int not null) partition by hash(id) partitions 1;",
  1167  			"create view nt18 as select id from nt17;",
  1168  			"alter causet pt18 exchange partition p0 with causet nt18",
  1169  			dbs.ErrCheckNoSuchBlock,
  1170  		},
  1171  		{
  1172  			"create causet pt19 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) stored) partition by hash(id) partitions 1;",
  1173  			"create causet nt19 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) virtual);",
  1174  			"alter causet pt19 exchange partition p0 with causet nt19;",
  1175  			dbs.ErrUnsupportedOnGeneratedDeferredCauset,
  1176  		},
  1177  		{
  1178  			"create causet pt20 (id int not null) partition by hash(id) partitions 1;",
  1179  			"create causet nt20 (id int default null);",
  1180  			"alter causet pt20 exchange partition p0 with causet nt20;",
  1181  			dbs.ErrBlocksDifferentMetadata,
  1182  		},
  1183  		{
  1184  			// unsigned
  1185  			"create causet pt21 (id int unsigned) partition by hash(id) partitions 1;",
  1186  			"create causet nt21 (id int);",
  1187  			"alter causet pt21 exchange partition p0 with causet nt21;",
  1188  			dbs.ErrBlocksDifferentMetadata,
  1189  		},
  1190  		{
  1191  			// zerofill
  1192  			"create causet pt22 (id int) partition by hash(id) partitions 1;",
  1193  			"create causet nt22 (id int zerofill);",
  1194  			"alter causet pt22 exchange partition p0 with causet nt22;",
  1195  			dbs.ErrBlocksDifferentMetadata,
  1196  		},
  1197  		{
  1198  			"create causet pt23 (id int, lname varchar(10) charset binary) partition by hash(id) partitions 1;",
  1199  			"create causet nt23 (id int, lname varchar(10));",
  1200  			"alter causet pt23 exchange partition p0 with causet nt23;",
  1201  			dbs.ErrBlocksDifferentMetadata,
  1202  		},
  1203  		{
  1204  			"create causet pt25 (id int, a datetime on uFIDelate current_timestamp) partition by hash(id) partitions 1;",
  1205  			"create causet nt25 (id int, a datetime);",
  1206  			"alter causet pt25 exchange partition p0 with causet nt25;",
  1207  			nil,
  1208  		},
  1209  		{
  1210  			"create causet pt26 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(lname, ' ')) virtual) partition by hash(id) partitions 1;",
  1211  			"create causet nt26 (id int not null, lname varchar(30), fname varchar(100) generated always as (concat(id, ' ')) virtual);",
  1212  			"alter causet pt26 exchange partition p0 with causet nt26;",
  1213  			dbs.ErrBlocksDifferentMetadata,
  1214  		},
  1215  		{
  1216  			"create causet pt27 (a int key, b int, index(a)) partition by hash(a) partitions 1;",
  1217  			"create causet nt27 (a int not null, b int, index(a));",
  1218  			"alter causet pt27 exchange partition p0 with causet nt27;",
  1219  			dbs.ErrBlocksDifferentMetadata,
  1220  		},
  1221  	}
  1222  
  1223  	tk := testkit.NewTestKit(c, s.causetstore)
  1224  	tk.MustInterDirc("use test")
  1225  	for i, t := range cases {
  1226  		tk.MustInterDirc(t.ptALLEGROSQL)
  1227  		tk.MustInterDirc(t.ntALLEGROSQL)
  1228  		if t.err != nil {
  1229  			_, err := tk.InterDirc(t.exchangeALLEGROSQL)
  1230  			c.Assert(terror.ErrorEqual(err, t.err), IsTrue, Commentf(
  1231  				"case %d fail, allegrosql = `%s`\nexpected error = `%v`\n  actual error = `%v`",
  1232  				i, t.exchangeALLEGROSQL, t.err, err,
  1233  			))
  1234  		} else {
  1235  			tk.MustInterDirc(t.exchangeALLEGROSQL)
  1236  		}
  1237  	}
  1238  }
  1239  
  1240  func (s *testIntegrationSuite7) TestExchangePartitionExpressIndex(c *C) {
  1241  	tk := testkit.NewTestKit(c, s.causetstore)
  1242  	tk.MustInterDirc("use test")
  1243  	tk.MustInterDirc("drop causet if exists pt1;")
  1244  	tk.MustInterDirc("create causet pt1(a int, b int, c int) PARTITION BY hash (a) partitions 1;")
  1245  	tk.MustInterDirc("alter causet pt1 add index idx((a+c));")
  1246  
  1247  	tk.MustInterDirc("drop causet if exists nt1;")
  1248  	tk.MustInterDirc("create causet nt1(a int, b int, c int);")
  1249  	tk.MustGetErrCode("alter causet pt1 exchange partition p0 with causet nt1;", tmysql.ErrBlocksDifferentMetadata)
  1250  
  1251  	tk.MustInterDirc("alter causet nt1 add defCausumn (`_V$_idx_0` bigint(20) generated always as (a+b) virtual);")
  1252  	tk.MustGetErrCode("alter causet pt1 exchange partition p0 with causet nt1;", tmysql.ErrBlocksDifferentMetadata)
  1253  
  1254  	// test different memex index when memex returns same field type
  1255  	tk.MustInterDirc("alter causet nt1 drop defCausumn `_V$_idx_0`;")
  1256  	tk.MustInterDirc("alter causet nt1 add index idx((b-c));")
  1257  	tk.MustGetErrCode("alter causet pt1 exchange partition p0 with causet nt1;", tmysql.ErrBlocksDifferentMetadata)
  1258  
  1259  	// test different memex index when memex returns different field type
  1260  	tk.MustInterDirc("alter causet nt1 drop index idx;")
  1261  	tk.MustInterDirc("alter causet nt1 add index idx((concat(a, b)));")
  1262  	tk.MustGetErrCode("alter causet pt1 exchange partition p0 with causet nt1;", tmysql.ErrBlocksDifferentMetadata)
  1263  
  1264  	tk.MustInterDirc("drop causet if exists nt2;")
  1265  	tk.MustInterDirc("create causet nt2 (a int, b int, c int)")
  1266  	tk.MustInterDirc("alter causet nt2 add index idx((a+c))")
  1267  	tk.MustInterDirc("alter causet pt1 exchange partition p0 with causet nt2")
  1268  
  1269  }
  1270  
  1271  func (s *testIntegrationSuite4) TestAddPartitionTooManyPartitions(c *C) {
  1272  	tk := testkit.NewTestKit(c, s.causetstore)
  1273  	tk.MustInterDirc("use test")
  1274  	count := dbs.PartitionCountLimit
  1275  	tk.MustInterDirc("drop causet if exists p1;")
  1276  	sql1 := `create causet p1 (
  1277  		id int not null
  1278  	)
  1279  	partition by range( id ) (`
  1280  	for i := 1; i <= count; i++ {
  1281  		sql1 += fmt.Sprintf("partition p%d values less than (%d),", i, i)
  1282  	}
  1283  	sql1 += "partition p8193 values less than (8193) );"
  1284  	tk.MustGetErrCode(sql1, tmysql.ErrTooManyPartitions)
  1285  
  1286  	tk.MustInterDirc("drop causet if exists p2;")
  1287  	sql2 := `create causet p2 (
  1288  		id int not null
  1289  	)
  1290  	partition by range( id ) (`
  1291  	for i := 1; i < count; i++ {
  1292  		sql2 += fmt.Sprintf("partition p%d values less than (%d),", i, i)
  1293  	}
  1294  	sql2 += "partition p8192 values less than (8192) );"
  1295  
  1296  	tk.MustInterDirc(sql2)
  1297  	sql3 := `alter causet p2 add partition (
  1298  	partition p8193 values less than (8193)
  1299  	);`
  1300  	tk.MustGetErrCode(sql3, tmysql.ErrTooManyPartitions)
  1301  }
  1302  
  1303  func checkPartitionDelRangeDone(c *C, s *testIntegrationSuite, partitionPrefix ekv.Key) bool {
  1304  	hasOldPartitionData := true
  1305  	for i := 0; i < waitForCleanDataRound; i++ {
  1306  		err := ekv.RunInNewTxn(s.causetstore, false, func(txn ekv.Transaction) error {
  1307  			it, err := txn.Iter(partitionPrefix, nil)
  1308  			if err != nil {
  1309  				return err
  1310  			}
  1311  			if !it.Valid() {
  1312  				hasOldPartitionData = false
  1313  			} else {
  1314  				hasOldPartitionData = it.Key().HasPrefix(partitionPrefix)
  1315  			}
  1316  			it.Close()
  1317  			return nil
  1318  		})
  1319  		c.Assert(err, IsNil)
  1320  		if !hasOldPartitionData {
  1321  			break
  1322  		}
  1323  		time.Sleep(waitForCleanDataInterval)
  1324  	}
  1325  	return hasOldPartitionData
  1326  }
  1327  
  1328  func (s *testIntegrationSuite4) TestTruncatePartitionAndDropBlock(c *C) {
  1329  	tk := testkit.NewTestKit(c, s.causetstore)
  1330  	tk.MustInterDirc("use test;")
  1331  	// Test truncate common causet.
  1332  	tk.MustInterDirc("drop causet if exists t1;")
  1333  	tk.MustInterDirc("create causet t1 (id int(11));")
  1334  	for i := 0; i < 100; i++ {
  1335  		tk.MustInterDirc("insert into t1 values (?)", i)
  1336  	}
  1337  	result := tk.MustQuery("select count(*) from t1;")
  1338  	result.Check(testkit.Rows("100"))
  1339  	tk.MustInterDirc("truncate causet t1;")
  1340  	result = tk.MustQuery("select count(*) from t1")
  1341  	result.Check(testkit.Rows("0"))
  1342  
  1343  	// Test drop common causet.
  1344  	tk.MustInterDirc("drop causet if exists t2;")
  1345  	tk.MustInterDirc("create causet t2 (id int(11));")
  1346  	for i := 0; i < 100; i++ {
  1347  		tk.MustInterDirc("insert into t2 values (?)", i)
  1348  	}
  1349  	result = tk.MustQuery("select count(*) from t2;")
  1350  	result.Check(testkit.Rows("100"))
  1351  	tk.MustInterDirc("drop causet t2;")
  1352  	tk.MustGetErrCode("select * from t2;", tmysql.ErrNoSuchBlock)
  1353  
  1354  	// Test truncate causet partition.
  1355  	tk.MustInterDirc("drop causet if exists t3;")
  1356  	tk.MustInterDirc(`create causet t3(
  1357  		id int, name varchar(50),
  1358  		purchased date
  1359  	)
  1360  	partition by range( year(purchased) ) (
  1361      	partition p0 values less than (1990),
  1362      	partition p1 values less than (1995),
  1363      	partition p2 values less than (2000),
  1364      	partition p3 values less than (2005),
  1365      	partition p4 values less than (2010),
  1366      	partition p5 values less than (2020)
  1367     	);`)
  1368  	tk.MustInterDirc(`insert into t3 values
  1369  	(1, 'desk organiser', '2003-10-15'),
  1370  	(2, 'alarm clock', '1997-11-05'),
  1371  	(3, 'chair', '2009-03-10'),
  1372  	(4, 'bookcase', '1989-01-10'),
  1373  	(5, 'exercise bike', '2020-05-09'),
  1374  	(6, 'sofa', '1987-06-05'),
  1375  	(7, 'espresso maker', '2011-11-22'),
  1376  	(8, 'aquarium', '1992-08-04'),
  1377  	(9, 'study desk', '2006-09-16'),
  1378  	(10, 'lava lamp', '1998-12-25');`)
  1379  	result = tk.MustQuery("select count(*) from t3;")
  1380  	result.Check(testkit.Rows("10"))
  1381  	ctx := tk.Se.(stochastikctx.Context)
  1382  	is := petri.GetPetri(ctx).SchemaReplicant()
  1383  	oldTblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t3"))
  1384  	c.Assert(err, IsNil)
  1385  	// Only one partition id test is taken here.
  1386  	oldPID := oldTblInfo.Meta().Partition.Definitions[0].ID
  1387  	tk.MustInterDirc("truncate causet t3;")
  1388  	partitionPrefix := blockcodec.EncodeBlockPrefix(oldPID)
  1389  	hasOldPartitionData := checkPartitionDelRangeDone(c, s.testIntegrationSuite, partitionPrefix)
  1390  	c.Assert(hasOldPartitionData, IsFalse)
  1391  
  1392  	// Test drop causet partition.
  1393  	tk.MustInterDirc("drop causet if exists t4;")
  1394  	tk.MustInterDirc(`create causet t4(
  1395  		id int, name varchar(50),
  1396  		purchased date
  1397  	)
  1398  	partition by range( year(purchased) ) (
  1399      	partition p0 values less than (1990),
  1400      	partition p1 values less than (1995),
  1401      	partition p2 values less than (2000),
  1402      	partition p3 values less than (2005),
  1403      	partition p4 values less than (2010),
  1404      	partition p5 values less than (2020)
  1405     	);`)
  1406  	tk.MustInterDirc(`insert into t4 values
  1407  	(1, 'desk organiser', '2003-10-15'),
  1408  	(2, 'alarm clock', '1997-11-05'),
  1409  	(3, 'chair', '2009-03-10'),
  1410  	(4, 'bookcase', '1989-01-10'),
  1411  	(5, 'exercise bike', '2020-05-09'),
  1412  	(6, 'sofa', '1987-06-05'),
  1413  	(7, 'espresso maker', '2011-11-22'),
  1414  	(8, 'aquarium', '1992-08-04'),
  1415  	(9, 'study desk', '2006-09-16'),
  1416  	(10, 'lava lamp', '1998-12-25');`)
  1417  	result = tk.MustQuery("select count(*) from t4; ")
  1418  	result.Check(testkit.Rows("10"))
  1419  	is = petri.GetPetri(ctx).SchemaReplicant()
  1420  	oldTblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t4"))
  1421  	c.Assert(err, IsNil)
  1422  	// Only one partition id test is taken here.
  1423  	oldPID = oldTblInfo.Meta().Partition.Definitions[1].ID
  1424  	tk.MustInterDirc("drop causet t4;")
  1425  	partitionPrefix = blockcodec.EncodeBlockPrefix(oldPID)
  1426  	hasOldPartitionData = checkPartitionDelRangeDone(c, s.testIntegrationSuite, partitionPrefix)
  1427  	c.Assert(hasOldPartitionData, IsFalse)
  1428  	tk.MustGetErrCode("select * from t4;", tmysql.ErrNoSuchBlock)
  1429  
  1430  	// Test truncate causet partition reassigns new partitionIDs.
  1431  	tk.MustInterDirc("drop causet if exists t5;")
  1432  	tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition=1;")
  1433  	tk.MustInterDirc(`create causet t5(
  1434  		id int, name varchar(50),
  1435  		purchased date
  1436  	)
  1437  	partition by range( year(purchased) ) (
  1438      	partition p0 values less than (1990),
  1439      	partition p1 values less than (1995),
  1440      	partition p2 values less than (2000),
  1441      	partition p3 values less than (2005),
  1442      	partition p4 values less than (2010),
  1443      	partition p5 values less than (2020)
  1444     	);`)
  1445  	is = petri.GetPetri(ctx).SchemaReplicant()
  1446  	oldTblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t5"))
  1447  	c.Assert(err, IsNil)
  1448  	oldPID = oldTblInfo.Meta().Partition.Definitions[0].ID
  1449  
  1450  	tk.MustInterDirc("truncate causet t5;")
  1451  	is = petri.GetPetri(ctx).SchemaReplicant()
  1452  	newTblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t5"))
  1453  	c.Assert(err, IsNil)
  1454  	newPID := newTblInfo.Meta().Partition.Definitions[0].ID
  1455  	c.Assert(oldPID != newPID, IsTrue)
  1456  
  1457  	tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1;")
  1458  	tk.MustInterDirc("drop causet if exists clients;")
  1459  	tk.MustInterDirc(`create causet clients (
  1460  		id int,
  1461  		fname varchar(30),
  1462  		lname varchar(30),
  1463  		signed date
  1464  	)
  1465  	partition by hash( month(signed) )
  1466  	partitions 12;`)
  1467  	is = petri.GetPetri(ctx).SchemaReplicant()
  1468  	oldTblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("clients"))
  1469  	c.Assert(err, IsNil)
  1470  	oldDefs := oldTblInfo.Meta().Partition.Definitions
  1471  
  1472  	// Test truncate `hash partitioned causet` reassigns new partitionIDs.
  1473  	tk.MustInterDirc("truncate causet clients;")
  1474  	is = petri.GetPetri(ctx).SchemaReplicant()
  1475  	newTblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("clients"))
  1476  	c.Assert(err, IsNil)
  1477  	newDefs := newTblInfo.Meta().Partition.Definitions
  1478  	for i := 0; i < len(oldDefs); i++ {
  1479  		c.Assert(oldDefs[i].ID != newDefs[i].ID, IsTrue)
  1480  	}
  1481  }
  1482  
  1483  func (s *testIntegrationSuite5) TestPartitionUniqueKeyNeedAllFieldsInPf(c *C) {
  1484  	tk := testkit.NewTestKit(c, s.causetstore)
  1485  	tk.MustInterDirc("use test;")
  1486  	tk.MustInterDirc("drop causet if exists part1;")
  1487  	tk.MustInterDirc(`create causet part1 (
  1488  		defCaus1 int not null,
  1489  		defCaus2 date not null,
  1490  		defCaus3 int not null,
  1491  		defCaus4 int not null,
  1492  		unique key (defCaus1, defCaus2)
  1493  	)
  1494  	partition by range( defCaus1 + defCaus2 ) (
  1495  	partition p1 values less than (11),
  1496  	partition p2 values less than (15)
  1497  	);`)
  1498  
  1499  	tk.MustInterDirc("drop causet if exists part2;")
  1500  	tk.MustInterDirc(`create causet part2 (
  1501  		defCaus1 int not null,
  1502  		defCaus2 date not null,
  1503  		defCaus3 int not null,
  1504  		defCaus4 int not null,
  1505  		unique key (defCaus1, defCaus2, defCaus3),
  1506  		unique key (defCaus3)
  1507  	)
  1508  	partition by range( defCaus3 ) (
  1509  	partition p1 values less than (11),
  1510  	partition p2 values less than (15)
  1511  	);`)
  1512  
  1513  	tk.MustInterDirc("drop causet if exists part3;")
  1514  	tk.MustInterDirc(`create causet part3 (
  1515  		defCaus1 int not null,
  1516  		defCaus2 date not null,
  1517  		defCaus3 int not null,
  1518  		defCaus4 int not null,
  1519  		primary key(defCaus1, defCaus2)
  1520  	)
  1521  	partition by range( defCaus1 ) (
  1522  	partition p1 values less than (11),
  1523  	partition p2 values less than (15)
  1524  	);`)
  1525  
  1526  	tk.MustInterDirc("drop causet if exists part4;")
  1527  	tk.MustInterDirc(`create causet part4 (
  1528  		defCaus1 int not null,
  1529  		defCaus2 date not null,
  1530  		defCaus3 int not null,
  1531  		defCaus4 int not null,
  1532  		primary key(defCaus1, defCaus2),
  1533  		unique key(defCaus2)
  1534  	)
  1535  	partition by range( year(defCaus2)  ) (
  1536  	partition p1 values less than (11),
  1537  	partition p2 values less than (15)
  1538  	);`)
  1539  
  1540  	tk.MustInterDirc("drop causet if exists part5;")
  1541  	tk.MustInterDirc(`create causet part5 (
  1542  		defCaus1 int not null,
  1543  		defCaus2 date not null,
  1544  		defCaus3 int not null,
  1545  		defCaus4 int not null,
  1546  		primary key(defCaus1, defCaus2, defCaus4),
  1547  		unique key(defCaus2, defCaus1)
  1548  	)
  1549  	partition by range( defCaus1 + defCaus2 ) (
  1550  	partition p1 values less than (11),
  1551  	partition p2 values less than (15)
  1552  	);`)
  1553  
  1554  	tk.MustInterDirc("drop causet if exists Part1;")
  1555  	sql1 := `create causet Part1 (
  1556  		defCaus1 int not null,
  1557  		defCaus2 date not null,
  1558  		defCaus3 int not null,
  1559  		defCaus4 int not null,
  1560  		unique key (defCaus1, defCaus2)
  1561  	)
  1562  	partition by range( defCaus3 ) (
  1563  	partition p1 values less than (11),
  1564  	partition p2 values less than (15)
  1565  	);`
  1566  	tk.MustGetErrCode(sql1, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1567  
  1568  	tk.MustInterDirc("drop causet if exists Part1;")
  1569  	sql2 := `create causet Part1 (
  1570  		defCaus1 int not null,
  1571  		defCaus2 date not null,
  1572  		defCaus3 int not null,
  1573  		defCaus4 int not null,
  1574  		unique key (defCaus1),
  1575  		unique key (defCaus3)
  1576  	)
  1577  	partition by range( defCaus1 + defCaus3 ) (
  1578  	partition p1 values less than (11),
  1579  	partition p2 values less than (15)
  1580  	);`
  1581  	tk.MustGetErrCode(sql2, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1582  
  1583  	tk.MustInterDirc("drop causet if exists Part1;")
  1584  	sql3 := `create causet Part1 (
  1585  		defCaus1 int not null,
  1586  		defCaus2 date not null,
  1587  		defCaus3 int not null,
  1588  		defCaus4 int not null,
  1589  		unique key (defCaus1),
  1590  		unique key (defCaus3)
  1591  	)
  1592  	partition by range( defCaus3 ) (
  1593  	partition p1 values less than (11),
  1594  	partition p2 values less than (15)
  1595  	);`
  1596  	tk.MustGetErrCode(sql3, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1597  
  1598  	tk.MustInterDirc("drop causet if exists Part1;")
  1599  	sql4 := `create causet Part1 (
  1600  		defCaus1 int not null,
  1601  		defCaus2 date not null,
  1602  		defCaus3 int not null,
  1603  		defCaus4 int not null,
  1604  		unique key (defCaus1, defCaus2, defCaus3),
  1605  		unique key (defCaus3)
  1606  	)
  1607  	partition by range( defCaus1 + defCaus3 ) (
  1608  	partition p1 values less than (11),
  1609  	partition p2 values less than (15)
  1610  	);`
  1611  	tk.MustGetErrCode(sql4, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1612  
  1613  	tk.MustInterDirc("drop causet if exists Part1;")
  1614  	sql5 := `create causet Part1 (
  1615  		defCaus1 int not null,
  1616  		defCaus2 date not null,
  1617  		defCaus3 int not null,
  1618  		defCaus4 int not null,
  1619  		primary key(defCaus1, defCaus2)
  1620  	)
  1621  	partition by range( defCaus3 ) (
  1622  	partition p1 values less than (11),
  1623  	partition p2 values less than (15)
  1624  	);`
  1625  	tk.MustGetErrCode(sql5, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1626  
  1627  	tk.MustInterDirc("drop causet if exists Part1;")
  1628  	sql6 := `create causet Part1 (
  1629  		defCaus1 int not null,
  1630  		defCaus2 date not null,
  1631  		defCaus3 int not null,
  1632  		defCaus4 int not null,
  1633  		primary key(defCaus1, defCaus3),
  1634  		unique key(defCaus2)
  1635  	)
  1636  	partition by range( year(defCaus2)  ) (
  1637  	partition p1 values less than (11),
  1638  	partition p2 values less than (15)
  1639  	);`
  1640  	tk.MustGetErrCode(sql6, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1641  
  1642  	tk.MustInterDirc("drop causet if exists Part1;")
  1643  	sql7 := `create causet Part1 (
  1644  		defCaus1 int not null,
  1645  		defCaus2 date not null,
  1646  		defCaus3 int not null,
  1647  		defCaus4 int not null,
  1648  		primary key(defCaus1, defCaus3, defCaus4),
  1649  		unique key(defCaus2, defCaus1)
  1650  	)
  1651  	partition by range( defCaus1 + defCaus2 ) (
  1652  	partition p1 values less than (11),
  1653  	partition p2 values less than (15)
  1654  	);`
  1655  	tk.MustGetErrCode(sql7, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1656  
  1657  	tk.MustInterDirc("drop causet if exists part6;")
  1658  	sql8 := `create causet part6 (
  1659  		defCaus1 int not null,
  1660  		defCaus2 date not null,
  1661  		defCaus3 int not null,
  1662  		defCaus4 int not null,
  1663  		defCaus5 int not null,
  1664  		unique key(defCaus1, defCaus2),
  1665  		unique key(defCaus1, defCaus3)
  1666  	)
  1667  	partition by range( defCaus1 + defCaus2 ) (
  1668  	partition p1 values less than (11),
  1669  	partition p2 values less than (15)
  1670  	);`
  1671  	tk.MustGetErrCode(sql8, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1672  
  1673  	sql9 := `create causet part7 (
  1674  		defCaus1 int not null,
  1675  		defCaus2 int not null,
  1676  		defCaus3 int not null unique,
  1677  		unique key(defCaus1, defCaus2)
  1678  	)
  1679  	partition by range (defCaus1 + defCaus2) (
  1680  	partition p1 values less than (11),
  1681  	partition p2 values less than (15)
  1682  	)`
  1683  	tk.MustGetErrCode(sql9, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1684  
  1685  	sql10 := `create causet part8 (
  1686                   a int not null,
  1687                   b int not null,
  1688                   c int default null,
  1689                   d int default null,
  1690                   e int default null,
  1691                   primary key (a, b),
  1692                   unique key (c, d)
  1693          )
  1694          partition by range defCausumns (b) (
  1695                 partition p0 values less than (4),
  1696                 partition p1 values less than (7),
  1697                 partition p2 values less than (11)
  1698          )`
  1699  	tk.MustGetErrCode(sql10, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1700  
  1701  	sql11 := `create causet part9 (
  1702                   a int not null,
  1703                   b int not null,
  1704                   c int default null,
  1705                   d int default null,
  1706                   e int default null,
  1707                   primary key (a, b),
  1708                   unique key (b, c, d)
  1709          )
  1710          partition by range defCausumns (b, c) (
  1711                 partition p0 values less than (4, 5),
  1712                 partition p1 values less than (7, 9),
  1713                 partition p2 values less than (11, 22)
  1714          )`
  1715  	tk.MustGetErrCode(sql11, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1716  
  1717  	sql12 := `create causet part12 (a varchar(20), b binary, unique index (a(5))) partition by range defCausumns (a) (
  1718  			partition p0 values less than ('aaaaa'),
  1719  			partition p1 values less than ('bbbbb'),
  1720  			partition p2 values less than ('ccccc'))`
  1721  	tk.MustGetErrCode(sql12, tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1722  	tk.MustInterDirc(`create causet part12 (a varchar(20), b binary) partition by range defCausumns (a) (
  1723  			partition p0 values less than ('aaaaa'),
  1724  			partition p1 values less than ('bbbbb'),
  1725  			partition p2 values less than ('ccccc'))`)
  1726  	tk.MustGetErrCode("alter causet part12 add unique index (a(5))", tmysql.ErrUniqueKeyNeedAllFieldsInPf)
  1727  	sql13 := `create causet part13 (a varchar(20), b varchar(10), unique index (a(5),b)) partition by range defCausumns (b) (
  1728  			partition p0 values less than ('aaaaa'),
  1729  			partition p1 values less than ('bbbbb'),
  1730  			partition p2 values less than ('ccccc'))`
  1731  	tk.MustInterDirc(sql13)
  1732  }
  1733  
  1734  func (s *testIntegrationSuite2) TestPartitionDropPrimaryKey(c *C) {
  1735  	idxName := "primary"
  1736  	addIdxALLEGROSQL := "alter causet partition_drop_idx add primary key idx1 (c1);"
  1737  	dropIdxALLEGROSQL := "alter causet partition_drop_idx drop primary key;"
  1738  	testPartitionDropIndex(c, s.causetstore, s.lease, idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL)
  1739  }
  1740  
  1741  func (s *testIntegrationSuite3) TestPartitionDropIndex(c *C) {
  1742  	idxName := "idx1"
  1743  	addIdxALLEGROSQL := "alter causet partition_drop_idx add index idx1 (c1);"
  1744  	dropIdxALLEGROSQL := "alter causet partition_drop_idx drop index idx1;"
  1745  	testPartitionDropIndex(c, s.causetstore, s.lease, idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL)
  1746  }
  1747  
  1748  func testPartitionDropIndex(c *C, causetstore ekv.CausetStorage, lease time.Duration, idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL string) {
  1749  	tk := testkit.NewTestKit(c, causetstore)
  1750  	done := make(chan error, 1)
  1751  	tk.MustInterDirc("use test_db")
  1752  	tk.MustInterDirc("drop causet if exists partition_drop_idx;")
  1753  	tk.MustInterDirc(`create causet partition_drop_idx (
  1754  		c1 int, c2 int, c3 int
  1755  	)
  1756  	partition by range( c1 ) (
  1757      	partition p0 values less than (3),
  1758      	partition p1 values less than (5),
  1759      	partition p2 values less than (7),
  1760      	partition p3 values less than (11),
  1761      	partition p4 values less than (15),
  1762      	partition p5 values less than (20),
  1763  		partition p6 values less than (maxvalue)
  1764     	);`)
  1765  
  1766  	num := 20
  1767  	for i := 0; i < num; i++ {
  1768  		tk.MustInterDirc("insert into partition_drop_idx values (?, ?, ?)", i, i, i)
  1769  	}
  1770  	tk.MustInterDirc(addIdxALLEGROSQL)
  1771  
  1772  	ctx := tk.Se.(stochastikctx.Context)
  1773  	is := petri.GetPetri(ctx).SchemaReplicant()
  1774  	t, err := is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("partition_drop_idx"))
  1775  	c.Assert(err, IsNil)
  1776  
  1777  	var idx1 causet.Index
  1778  	for _, pidx := range t.Indices() {
  1779  		if pidx.Meta().Name.L == idxName {
  1780  			idx1 = pidx
  1781  			break
  1782  		}
  1783  	}
  1784  	c.Assert(idx1, NotNil)
  1785  
  1786  	solitonutil.StochastikInterDircInGoroutine(c, causetstore, dropIdxALLEGROSQL, done)
  1787  	ticker := time.NewTicker(lease / 2)
  1788  	defer ticker.Stop()
  1789  LOOP:
  1790  	for {
  1791  		select {
  1792  		case err = <-done:
  1793  			if err == nil {
  1794  				break LOOP
  1795  			}
  1796  			c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err)))
  1797  		case <-ticker.C:
  1798  			step := 10
  1799  			rand.Seed(time.Now().Unix())
  1800  			for i := num; i < num+step; i++ {
  1801  				n := rand.Intn(num)
  1802  				tk.MustInterDirc("uFIDelate partition_drop_idx set c2 = 1 where c1 = ?", n)
  1803  				tk.MustInterDirc("insert into partition_drop_idx values (?, ?, ?)", i, i, i)
  1804  			}
  1805  			num += step
  1806  		}
  1807  	}
  1808  
  1809  	is = petri.GetPetri(ctx).SchemaReplicant()
  1810  	t, err = is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("partition_drop_idx"))
  1811  	c.Assert(err, IsNil)
  1812  	// Only one partition id test is taken here.
  1813  	pid := t.Meta().Partition.Definitions[0].ID
  1814  	var idxn causet.Index
  1815  	t.Indices()
  1816  	for _, idx := range t.Indices() {
  1817  		if idx.Meta().Name.L == idxName {
  1818  			idxn = idx
  1819  			break
  1820  		}
  1821  	}
  1822  	c.Assert(idxn, IsNil)
  1823  	idx := blocks.NewIndex(pid, t.Meta(), idx1.Meta())
  1824  	checkDelRangeDone(c, ctx, idx)
  1825  	tk.MustInterDirc("drop causet partition_drop_idx;")
  1826  }
  1827  
  1828  func (s *testIntegrationSuite2) TestPartitionCancelAddPrimaryKey(c *C) {
  1829  	idxName := "primary"
  1830  	addIdxALLEGROSQL := "alter causet t1 add primary key c3_index (c1);"
  1831  	testPartitionCancelAddIndex(c, s.causetstore, s.dom.DBS(), s.lease, idxName, addIdxALLEGROSQL)
  1832  }
  1833  
  1834  func (s *testIntegrationSuite4) TestPartitionCancelAddIndex(c *C) {
  1835  	idxName := "idx1"
  1836  	addIdxALLEGROSQL := "create unique index c3_index on t1 (c1)"
  1837  	testPartitionCancelAddIndex(c, s.causetstore, s.dom.DBS(), s.lease, idxName, addIdxALLEGROSQL)
  1838  }
  1839  
  1840  func testPartitionCancelAddIndex(c *C, causetstore ekv.CausetStorage, d dbs.DBS, lease time.Duration, idxName, addIdxALLEGROSQL string) {
  1841  	tk := testkit.NewTestKit(c, causetstore)
  1842  
  1843  	tk.MustInterDirc("use test_db")
  1844  	tk.MustInterDirc("drop causet if exists t1;")
  1845  	tk.MustInterDirc(`create causet t1 (
  1846  		c1 int, c2 int, c3 int
  1847  	)
  1848  	partition by range( c1 ) (
  1849      	partition p0 values less than (1024),
  1850      	partition p1 values less than (2048),
  1851      	partition p2 values less than (3072),
  1852      	partition p3 values less than (4096),
  1853  		partition p4 values less than (maxvalue)
  1854     	);`)
  1855  	count := defaultBatchSize * 32
  1856  	// add some rows
  1857  	for i := 0; i < count; i += defaultBatchSize {
  1858  		batchInsert(tk, "t1", i, i+defaultBatchSize)
  1859  	}
  1860  
  1861  	var checkErr error
  1862  	var c3IdxInfo *perceptron.IndexInfo
  1863  	hook := &dbs.TestDBSCallback{}
  1864  	originBatchSize := tk.MustQuery("select @@global.milevadb_dbs_reorg_batch_size")
  1865  	// Set batch size to lower try to slow down add-index reorganization, This if for hook to cancel this dbs job.
  1866  	tk.MustInterDirc("set @@global.milevadb_dbs_reorg_batch_size = 32")
  1867  	ctx := tk.Se.(stochastikctx.Context)
  1868  	defer tk.MustInterDirc(fmt.Sprintf("set @@global.milevadb_dbs_reorg_batch_size = %v", originBatchSize.Rows()[0][0]))
  1869  	hook.OnJobUFIDelatedExported, c3IdxInfo, checkErr = backgroundInterDircOnJobUFIDelatedExported(c, causetstore, ctx, hook, idxName)
  1870  	originHook := d.GetHook()
  1871  	defer d.(dbs.DBSForTest).SetHook(originHook)
  1872  	d.(dbs.DBSForTest).SetHook(hook)
  1873  	done := make(chan error, 1)
  1874  	go backgroundInterDirc(causetstore, addIdxALLEGROSQL, done)
  1875  
  1876  	times := 0
  1877  	ticker := time.NewTicker(lease / 2)
  1878  	defer ticker.Stop()
  1879  LOOP:
  1880  	for {
  1881  		select {
  1882  		case err := <-done:
  1883  			c.Assert(checkErr, IsNil)
  1884  			c.Assert(err, NotNil)
  1885  			c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job")
  1886  			break LOOP
  1887  		case <-ticker.C:
  1888  			if times >= 10 {
  1889  				break
  1890  			}
  1891  			step := 10
  1892  			rand.Seed(time.Now().Unix())
  1893  			// delete some rows, and add some data
  1894  			for i := count; i < count+step; i++ {
  1895  				n := rand.Intn(count)
  1896  				tk.MustInterDirc("delete from t1 where c1 = ?", n)
  1897  				tk.MustInterDirc("insert into t1 values (?, ?, ?)", i+10, i, i)
  1898  			}
  1899  			count += step
  1900  			times++
  1901  		}
  1902  	}
  1903  
  1904  	t := testGetBlockByName(c, ctx, "test_db", "t1")
  1905  	// Only one partition id test is taken here.
  1906  	pid := t.Meta().Partition.Definitions[0].ID
  1907  	for _, tidx := range t.Indices() {
  1908  		c.Assert(strings.EqualFold(tidx.Meta().Name.L, "c3_index"), IsFalse)
  1909  	}
  1910  
  1911  	idx := blocks.NewIndex(pid, t.Meta(), c3IdxInfo)
  1912  	checkDelRangeDone(c, ctx, idx)
  1913  
  1914  	tk.MustInterDirc("drop causet t1")
  1915  }
  1916  
  1917  func backgroundInterDircOnJobUFIDelatedExported(c *C, causetstore ekv.CausetStorage, ctx stochastikctx.Context, hook *dbs.TestDBSCallback, idxName string) (
  1918  	func(*perceptron.Job), *perceptron.IndexInfo, error) {
  1919  	var checkErr error
  1920  	first := true
  1921  	c3IdxInfo := &perceptron.IndexInfo{}
  1922  	hook.OnJobUFIDelatedExported = func(job *perceptron.Job) {
  1923  		addIndexNotFirstReorg := (job.Type == perceptron.CausetActionAddIndex || job.Type == perceptron.CausetActionAddPrimaryKey) &&
  1924  			job.SchemaState == perceptron.StateWriteReorganization && job.SnapshotVer != 0
  1925  		// If the action is adding index and the state is writing reorganization, it want to test the case of cancelling the job when backfilling indexes.
  1926  		// When the job satisfies this case of addIndexNotFirstReorg, the worker will start to backfill indexes.
  1927  		if !addIndexNotFirstReorg {
  1928  			// Get the index's spacetime.
  1929  			if c3IdxInfo != nil {
  1930  				return
  1931  			}
  1932  			t := testGetBlockByName(c, ctx, "test_db", "t1")
  1933  			for _, index := range t.WriblockIndices() {
  1934  				if index.Meta().Name.L == idxName {
  1935  					c3IdxInfo = index.Meta()
  1936  				}
  1937  			}
  1938  			return
  1939  		}
  1940  		// The job satisfies the case of addIndexNotFirst for the first time, the worker hasn't finished a batch of backfill indexes.
  1941  		if first {
  1942  			first = false
  1943  			return
  1944  		}
  1945  		if checkErr != nil {
  1946  			return
  1947  		}
  1948  		hookCtx := mock.NewContext()
  1949  		hookCtx.CausetStore = causetstore
  1950  		err := hookCtx.NewTxn(context.Background())
  1951  		if err != nil {
  1952  			checkErr = errors.Trace(err)
  1953  			return
  1954  		}
  1955  		jobIDs := []int64{job.ID}
  1956  		txn, err := hookCtx.Txn(true)
  1957  		if err != nil {
  1958  			checkErr = errors.Trace(err)
  1959  			return
  1960  		}
  1961  		errs, err := admin.CancelJobs(txn, jobIDs)
  1962  		if err != nil {
  1963  			checkErr = errors.Trace(err)
  1964  			return
  1965  		}
  1966  		// It only tests cancel one DBS job.
  1967  		if errs[0] != nil {
  1968  			checkErr = errors.Trace(errs[0])
  1969  			return
  1970  		}
  1971  		txn, err = hookCtx.Txn(true)
  1972  		if err != nil {
  1973  			checkErr = errors.Trace(err)
  1974  			return
  1975  		}
  1976  		err = txn.Commit(context.Background())
  1977  		if err != nil {
  1978  			checkErr = errors.Trace(err)
  1979  		}
  1980  	}
  1981  	return hook.OnJobUFIDelatedExported, c3IdxInfo, checkErr
  1982  }
  1983  
  1984  func (s *testIntegrationSuite5) TestPartitionAddPrimaryKey(c *C) {
  1985  	tk := testkit.NewTestKit(c, s.causetstore)
  1986  	testPartitionAddIndexOrPK(c, tk, "primary key")
  1987  }
  1988  
  1989  func (s *testIntegrationSuite1) TestPartitionAddIndex(c *C) {
  1990  	tk := testkit.NewTestKit(c, s.causetstore)
  1991  	testPartitionAddIndexOrPK(c, tk, "index")
  1992  }
  1993  
  1994  func testPartitionAddIndexOrPK(c *C, tk *testkit.TestKit, key string) {
  1995  	tk.MustInterDirc("use test")
  1996  	tk.MustInterDirc(`create causet partition_add_idx (
  1997  	id int not null,
  1998  	hired date not null
  1999  	)
  2000  	partition by range( year(hired) ) (
  2001  	partition p1 values less than (1991),
  2002  	partition p3 values less than (2001),
  2003  	partition p4 values less than (2004),
  2004  	partition p5 values less than (2008),
  2005  	partition p6 values less than (2012),
  2006  	partition p7 values less than (2020)
  2007  	);`)
  2008  	testPartitionAddIndex(tk, c, key)
  2009  
  2010  	// test hash partition causet.
  2011  	tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = '1';")
  2012  	tk.MustInterDirc("drop causet if exists partition_add_idx")
  2013  	tk.MustInterDirc(`create causet partition_add_idx (
  2014  	id int not null,
  2015  	hired date not null
  2016  	) partition by hash( year(hired) ) partitions 4;`)
  2017  	testPartitionAddIndex(tk, c, key)
  2018  
  2019  	// Test hash partition for pr 10475.
  2020  	tk.MustInterDirc("drop causet if exists t1")
  2021  	defer tk.MustInterDirc("drop causet if exists t1")
  2022  	tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = '1';")
  2023  	tk.MustInterDirc("create causet t1 (a int, b int, unique key(a)) partition by hash(a) partitions 5;")
  2024  	tk.MustInterDirc("insert into t1 values (0,0),(1,1),(2,2),(3,3);")
  2025  	tk.MustInterDirc(fmt.Sprintf("alter causet t1 add %s idx(a)", key))
  2026  	tk.MustInterDirc("admin check causet t1;")
  2027  
  2028  	// Test range partition for pr 10475.
  2029  	tk.MustInterDirc("drop causet t1")
  2030  	tk.MustInterDirc("create causet t1 (a int, b int, unique key(a)) partition by range (a) (partition p0 values less than (10), partition p1 values less than (20));")
  2031  	tk.MustInterDirc("insert into t1 values (0,0);")
  2032  	tk.MustInterDirc(fmt.Sprintf("alter causet t1 add %s idx(a)", key))
  2033  	tk.MustInterDirc("admin check causet t1;")
  2034  }
  2035  
  2036  func testPartitionAddIndex(tk *testkit.TestKit, c *C, key string) {
  2037  	idxName1 := "idx1"
  2038  
  2039  	f := func(end int, isPK bool) string {
  2040  		dml := fmt.Sprintf("insert into partition_add_idx values")
  2041  		for i := 0; i < end; i++ {
  2042  			dVal := 1988 + rand.Intn(30)
  2043  			if isPK {
  2044  				dVal = 1518 + i
  2045  			}
  2046  			dml += fmt.Sprintf("(%d, '%d-01-01')", i, dVal)
  2047  			if i != end-1 {
  2048  				dml += ","
  2049  			}
  2050  		}
  2051  		return dml
  2052  	}
  2053  	var dml string
  2054  	if key == "primary key" {
  2055  		idxName1 = "primary"
  2056  		// For the primary key, hired must be unique.
  2057  		dml = f(500, true)
  2058  	} else {
  2059  		dml = f(500, false)
  2060  	}
  2061  	tk.MustInterDirc(dml)
  2062  
  2063  	tk.MustInterDirc(fmt.Sprintf("alter causet partition_add_idx add %s idx1 (hired)", key))
  2064  	tk.MustInterDirc("alter causet partition_add_idx add index idx2 (id, hired)")
  2065  	ctx := tk.Se.(stochastikctx.Context)
  2066  	is := petri.GetPetri(ctx).SchemaReplicant()
  2067  	t, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("partition_add_idx"))
  2068  	c.Assert(err, IsNil)
  2069  	var idx1 causet.Index
  2070  	for _, idx := range t.Indices() {
  2071  		if idx.Meta().Name.L == idxName1 {
  2072  			idx1 = idx
  2073  			break
  2074  		}
  2075  	}
  2076  	c.Assert(idx1, NotNil)
  2077  
  2078  	tk.MustQuery(fmt.Sprintf("select count(hired) from partition_add_idx use index(%s)", idxName1)).Check(testkit.Rows("500"))
  2079  	tk.MustQuery("select count(id) from partition_add_idx use index(idx2)").Check(testkit.Rows("500"))
  2080  
  2081  	tk.MustInterDirc("admin check causet partition_add_idx")
  2082  	tk.MustInterDirc("drop causet partition_add_idx")
  2083  }
  2084  
  2085  func (s *testIntegrationSuite5) TestDropSchemaWithPartitionBlock(c *C) {
  2086  	tk := testkit.NewTestKit(c, s.causetstore)
  2087  	tk.MustInterDirc("drop database if exists test_db_with_partition")
  2088  	tk.MustInterDirc("create database test_db_with_partition")
  2089  	tk.MustInterDirc("use test_db_with_partition")
  2090  	tk.MustInterDirc(`create causet t_part (a int key)
  2091  		partition by range(a) (
  2092  		partition p0 values less than (10),
  2093  		partition p1 values less than (20)
  2094  		);`)
  2095  	tk.MustInterDirc("insert into t_part values (1),(2),(11),(12);")
  2096  	ctx := s.ctx
  2097  	tbl := testGetBlockByName(c, ctx, "test_db_with_partition", "t_part")
  2098  
  2099  	// check records num before drop database.
  2100  	recordsNum := getPartitionBlockRecordsNum(c, ctx, tbl.(causet.PartitionedBlock))
  2101  	c.Assert(recordsNum, Equals, 4)
  2102  
  2103  	tk.MustInterDirc("drop database if exists test_db_with_partition")
  2104  
  2105  	// check job args.
  2106  	rs, err := tk.InterDirc("admin show dbs jobs")
  2107  	c.Assert(err, IsNil)
  2108  	rows, err := stochastik.GetRows4Test(context.Background(), tk.Se, rs)
  2109  	c.Assert(err, IsNil)
  2110  	event := rows[0]
  2111  	c.Assert(event.GetString(3), Equals, "drop schemaReplicant")
  2112  	jobID := event.GetInt64(0)
  2113  	ekv.RunInNewTxn(s.causetstore, false, func(txn ekv.Transaction) error {
  2114  		t := spacetime.NewMeta(txn)
  2115  		historyJob, err := t.GetHistoryDBSJob(jobID)
  2116  		c.Assert(err, IsNil)
  2117  		var blockIDs []int64
  2118  		err = historyJob.DecodeArgs(&blockIDs)
  2119  		c.Assert(err, IsNil)
  2120  		// There is 2 partitions.
  2121  		c.Assert(len(blockIDs), Equals, 3)
  2122  		return nil
  2123  	})
  2124  
  2125  	// check records num after drop database.
  2126  	for i := 0; i < waitForCleanDataRound; i++ {
  2127  		recordsNum = getPartitionBlockRecordsNum(c, ctx, tbl.(causet.PartitionedBlock))
  2128  		if recordsNum != 0 {
  2129  			time.Sleep(waitForCleanDataInterval)
  2130  		} else {
  2131  			break
  2132  		}
  2133  	}
  2134  	c.Assert(recordsNum, Equals, 0)
  2135  }
  2136  
  2137  func getPartitionBlockRecordsNum(c *C, ctx stochastikctx.Context, tbl causet.PartitionedBlock) int {
  2138  	num := 0
  2139  	info := tbl.Meta().GetPartitionInfo()
  2140  	for _, def := range info.Definitions {
  2141  		pid := def.ID
  2142  		partition := tbl.(causet.PartitionedBlock).GetPartition(pid)
  2143  		startKey := partition.RecordKey(ekv.IntHandle(math.MinInt64))
  2144  		c.Assert(ctx.NewTxn(context.Background()), IsNil)
  2145  		err := partition.IterRecords(ctx, startKey, partition.DefCauss(),
  2146  			func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
  2147  				num++
  2148  				return true, nil
  2149  			})
  2150  		c.Assert(err, IsNil)
  2151  	}
  2152  	return num
  2153  }
  2154  
  2155  func (s *testIntegrationSuite3) TestPartitionErrorCode(c *C) {
  2156  	tk := testkit.NewTestKit(c, s.causetstore)
  2157  	// add partition
  2158  	tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1")
  2159  	tk.MustInterDirc("drop database if exists test_db_with_partition")
  2160  	tk.MustInterDirc("create database test_db_with_partition")
  2161  	tk.MustInterDirc("use test_db_with_partition")
  2162  	tk.MustInterDirc(`create causet employees (
  2163  		id int not null,
  2164  		fname varchar(30),
  2165  		lname varchar(30),
  2166  		hired date not null default '1970-01-01',
  2167  		separated date not null default '9999-12-31',
  2168  		job_code int,
  2169  		store_id int
  2170  	)
  2171  	partition by hash(store_id)
  2172  	partitions 4;`)
  2173  	_, err := tk.InterDirc("alter causet employees add partition partitions 8;")
  2174  	c.Assert(dbs.ErrUnsupportedAddPartition.Equal(err), IsTrue)
  2175  
  2176  	_, err = tk.InterDirc("alter causet employees add partition (partition p5 values less than (42));")
  2177  	c.Assert(dbs.ErrUnsupportedAddPartition.Equal(err), IsTrue)
  2178  
  2179  	// coalesce partition
  2180  	tk.MustInterDirc(`create causet clients (
  2181  		id int,
  2182  		fname varchar(30),
  2183  		lname varchar(30),
  2184  		signed date
  2185  	)
  2186  	partition by hash( month(signed) )
  2187  	partitions 12;`)
  2188  	_, err = tk.InterDirc("alter causet clients coalesce partition 4;")
  2189  	c.Assert(dbs.ErrUnsupportedCoalescePartition.Equal(err), IsTrue)
  2190  
  2191  	tk.MustInterDirc(`create causet t_part (a int key)
  2192  		partition by range(a) (
  2193  		partition p0 values less than (10),
  2194  		partition p1 values less than (20)
  2195  		);`)
  2196  	_, err = tk.InterDirc("alter causet t_part coalesce partition 4;")
  2197  	c.Assert(dbs.ErrCoalesceOnlyOnHashPartition.Equal(err), IsTrue)
  2198  
  2199  	tk.MustGetErrCode(`alter causet t_part reorganize partition p0, p1 into (
  2200  			partition p0 values less than (1980));`, tmysql.ErrUnsupportedDBSOperation)
  2201  
  2202  	tk.MustGetErrCode("alter causet t_part check partition p0, p1;", tmysql.ErrUnsupportedDBSOperation)
  2203  	tk.MustGetErrCode("alter causet t_part optimize partition p0,p1;", tmysql.ErrUnsupportedDBSOperation)
  2204  	tk.MustGetErrCode("alter causet t_part rebuild partition p0,p1;", tmysql.ErrUnsupportedDBSOperation)
  2205  	tk.MustGetErrCode("alter causet t_part remove partitioning;", tmysql.ErrUnsupportedDBSOperation)
  2206  	tk.MustGetErrCode("alter causet t_part repair partition p1;", tmysql.ErrUnsupportedDBSOperation)
  2207  }
  2208  
  2209  func (s *testIntegrationSuite5) TestConstAndTimezoneDepent(c *C) {
  2210  	tk := testkit.NewTestKit(c, s.causetstore)
  2211  	// add partition
  2212  	tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1")
  2213  	tk.MustInterDirc("drop database if exists test_db_with_partition_const")
  2214  	tk.MustInterDirc("create database test_db_with_partition_const")
  2215  	tk.MustInterDirc("use test_db_with_partition_const")
  2216  
  2217  	sql1 := `create causet t1 ( id int )
  2218  		partition by range(4) (
  2219  		partition p1 values less than (10)
  2220  		);`
  2221  	tk.MustGetErrCode(sql1, tmysql.ErrWrongExprInPartitionFunc)
  2222  
  2223  	sql2 := `create causet t2 ( time_recorded timestamp )
  2224  		partition by range(TO_DAYS(time_recorded)) (
  2225  		partition p1 values less than (1559192604)
  2226  		);`
  2227  	tk.MustGetErrCode(sql2, tmysql.ErrWrongExprInPartitionFunc)
  2228  
  2229  	sql3 := `create causet t3 ( id int )
  2230  		partition by range(DAY(id)) (
  2231  		partition p1 values less than (1)
  2232  		);`
  2233  	tk.MustGetErrCode(sql3, tmysql.ErrWrongExprInPartitionFunc)
  2234  
  2235  	sql4 := `create causet t4 ( id int )
  2236  		partition by hash(4) partitions 4
  2237  		;`
  2238  	tk.MustGetErrCode(sql4, tmysql.ErrWrongExprInPartitionFunc)
  2239  
  2240  	sql5 := `create causet t5 ( time_recorded timestamp )
  2241  		partition by range(to_seconds(time_recorded)) (
  2242  		partition p1 values less than (1559192604)
  2243  		);`
  2244  	tk.MustGetErrCode(sql5, tmysql.ErrWrongExprInPartitionFunc)
  2245  
  2246  	sql6 := `create causet t6 ( id int )
  2247  		partition by range(to_seconds(id)) (
  2248  		partition p1 values less than (1559192604)
  2249  		);`
  2250  	tk.MustGetErrCode(sql6, tmysql.ErrWrongExprInPartitionFunc)
  2251  
  2252  	sql7 := `create causet t7 ( time_recorded timestamp )
  2253  		partition by range(abs(time_recorded)) (
  2254  		partition p1 values less than (1559192604)
  2255  		);`
  2256  	tk.MustGetErrCode(sql7, tmysql.ErrWrongExprInPartitionFunc)
  2257  
  2258  	sql8 := `create causet t2332 ( time_recorded time )
  2259           partition by range(TO_DAYS(time_recorded)) (
  2260    		 partition p0 values less than (1)
  2261  		);`
  2262  	tk.MustGetErrCode(sql8, tmysql.ErrWrongExprInPartitionFunc)
  2263  
  2264  	sql9 := `create causet t1 ( id int )
  2265  		partition by hash(4) partitions 4;`
  2266  	tk.MustGetErrCode(sql9, tmysql.ErrWrongExprInPartitionFunc)
  2267  
  2268  	sql10 := `create causet t1 ( id int )
  2269  		partition by hash(ed) partitions 4;`
  2270  	tk.MustGetErrCode(sql10, tmysql.ErrBadField)
  2271  
  2272  	sql11 := `create causet t2332 ( time_recorded time )
  2273           partition by range(TO_SECONDS(time_recorded)) (
  2274    		 partition p0 values less than (1)
  2275  		);`
  2276  	tk.MustGetErrCode(sql11, tmysql.ErrWrongExprInPartitionFunc)
  2277  
  2278  	sql12 := `create causet t2332 ( time_recorded time )
  2279           partition by range(TO_SECONDS(time_recorded)) (
  2280    		 partition p0 values less than (1)
  2281  		);`
  2282  	tk.MustGetErrCode(sql12, tmysql.ErrWrongExprInPartitionFunc)
  2283  
  2284  	sql13 := `create causet t2332 ( time_recorded time )
  2285           partition by range(day(time_recorded)) (
  2286    		 partition p0 values less than (1)
  2287  		);`
  2288  	tk.MustGetErrCode(sql13, tmysql.ErrWrongExprInPartitionFunc)
  2289  
  2290  	sql14 := `create causet t2332 ( time_recorded timestamp )
  2291           partition by range(day(time_recorded)) (
  2292    		 partition p0 values less than (1)
  2293  		);`
  2294  	tk.MustGetErrCode(sql14, tmysql.ErrWrongExprInPartitionFunc)
  2295  }
  2296  
  2297  func (s *testIntegrationSuite5) TestConstAndTimezoneDepent2(c *C) {
  2298  	tk := testkit.NewTestKit(c, s.causetstore)
  2299  	// add partition
  2300  	tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = 1")
  2301  	tk.MustInterDirc("drop database if exists test_db_with_partition_const")
  2302  	tk.MustInterDirc("create database test_db_with_partition_const")
  2303  	tk.MustInterDirc("use test_db_with_partition_const")
  2304  
  2305  	tk.MustInterDirc(`create causet t1 ( time_recorded datetime )
  2306  	partition by range(TO_DAYS(time_recorded)) (
  2307  	partition p0 values less than (1));`)
  2308  
  2309  	tk.MustInterDirc(`create causet t2 ( time_recorded date )
  2310  	partition by range(TO_DAYS(time_recorded)) (
  2311  	partition p0 values less than (1));`)
  2312  
  2313  	tk.MustInterDirc(`create causet t3 ( time_recorded date )
  2314  	partition by range(TO_SECONDS(time_recorded)) (
  2315  	partition p0 values less than (1));`)
  2316  
  2317  	tk.MustInterDirc(`create causet t4 ( time_recorded date )
  2318  	partition by range(TO_SECONDS(time_recorded)) (
  2319  	partition p0 values less than (1));`)
  2320  
  2321  	tk.MustInterDirc(`create causet t5 ( time_recorded timestamp )
  2322  	partition by range(unix_timestamp(time_recorded)) (
  2323  		partition p1 values less than (1559192604)
  2324  	);`)
  2325  }
  2326  
  2327  func (s *testIntegrationSuite3) TestUnsupportedPartitionManagementDBSs(c *C) {
  2328  	tk := testkit.NewTestKit(c, s.causetstore)
  2329  	tk.MustInterDirc("use test;")
  2330  	tk.MustInterDirc("drop causet if exists test_1465;")
  2331  	tk.MustInterDirc(`
  2332  		create causet test_1465 (a int)
  2333  		partition by range(a) (
  2334  			partition p1 values less than (10),
  2335  			partition p2 values less than (20),
  2336  			partition p3 values less than (30)
  2337  		);
  2338  	`)
  2339  
  2340  	_, err := tk.InterDirc("alter causet test_1465 partition by hash(a)")
  2341  	c.Assert(err, ErrorMatches, ".*alter causet partition is unsupported")
  2342  }
  2343  
  2344  func (s *testIntegrationSuite7) TestCommitWhenSchemaChange(c *C) {
  2345  	tk := testkit.NewTestKit(c, s.causetstore)
  2346  	tk.MustInterDirc("use test")
  2347  	tk.MustInterDirc(`create causet schema_change (a int, b timestamp)
  2348  			partition by range(a) (
  2349  			    partition p0 values less than (4),
  2350  			    partition p1 values less than (7),
  2351  			    partition p2 values less than (11)
  2352  			)`)
  2353  	tk2 := testkit.NewTestKit(c, s.causetstore)
  2354  	tk2.MustInterDirc("use test")
  2355  
  2356  	tk.MustInterDirc("begin")
  2357  	tk.MustInterDirc("insert into schema_change values (1, '2020-12-25 13:27:42')")
  2358  	tk.MustInterDirc("insert into schema_change values (3, '2020-12-25 13:27:43')")
  2359  
  2360  	tk2.MustInterDirc("alter causet schema_change add index idx(b)")
  2361  
  2362  	tk.MustInterDirc("insert into schema_change values (5, '2020-12-25 13:27:43')")
  2363  	tk.MustInterDirc("insert into schema_change values (9, '2020-12-25 13:27:44')")
  2364  	atomic.StoreUint32(&stochastik.SchemaChangedWithoutRetry, 1)
  2365  	defer func() {
  2366  		atomic.StoreUint32(&stochastik.SchemaChangedWithoutRetry, 0)
  2367  	}()
  2368  	_, err := tk.Se.InterDircute(context.Background(), "commit")
  2369  	c.Assert(petri.ErrSchemaReplicantChanged.Equal(err), IsTrue)
  2370  
  2371  	// Cover a bug that schemaReplicant validator does not prevent transaction commit when
  2372  	// the schemaReplicant has changed on the partitioned causet.
  2373  	// That bug will cause data and index inconsistency!
  2374  	tk.MustInterDirc("admin check causet schema_change")
  2375  	tk.MustQuery("select * from schema_change").Check(testkit.Rows())
  2376  
  2377  	// Check inconsistency when exchanging partition
  2378  	tk.MustInterDirc(`drop causet if exists pt, nt;`)
  2379  	tk.MustInterDirc(`create causet pt (a int) partition by hash(a) partitions 2;`)
  2380  	tk.MustInterDirc(`create causet nt (a int);`)
  2381  
  2382  	tk.MustInterDirc("begin")
  2383  	tk.MustInterDirc("insert into nt values (1), (3), (5);")
  2384  	tk2.MustInterDirc("alter causet pt exchange partition p1 with causet nt;")
  2385  	tk.MustInterDirc("insert into nt values (7), (9);")
  2386  	_, err = tk.Se.InterDircute(context.Background(), "commit")
  2387  	c.Assert(petri.ErrSchemaReplicantChanged.Equal(err), IsTrue)
  2388  
  2389  	tk.MustInterDirc("admin check causet pt")
  2390  	tk.MustQuery("select * from pt").Check(testkit.Rows())
  2391  	tk.MustInterDirc("admin check causet nt")
  2392  	tk.MustQuery("select * from nt").Check(testkit.Rows())
  2393  
  2394  	tk.MustInterDirc("begin")
  2395  	tk.MustInterDirc("insert into pt values (1), (3), (5);")
  2396  	tk2.MustInterDirc("alter causet pt exchange partition p1 with causet nt;")
  2397  	tk.MustInterDirc("insert into pt values (7), (9);")
  2398  	_, err = tk.Se.InterDircute(context.Background(), "commit")
  2399  	c.Assert(petri.ErrSchemaReplicantChanged.Equal(err), IsTrue)
  2400  
  2401  	tk.MustInterDirc("admin check causet pt")
  2402  	tk.MustQuery("select * from pt").Check(testkit.Rows())
  2403  	tk.MustInterDirc("admin check causet nt")
  2404  	tk.MustQuery("select * from nt").Check(testkit.Rows())
  2405  }