github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/db_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  	"io"
    20  	"math"
    21  	"math/rand"
    22  	"sort"
    23  	"strconv"
    24  	"strings"
    25  	"sync"
    26  	"time"
    27  
    28  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    29  	"github.com/whtcorpsinc/BerolinaSQL/perceptron"
    30  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    31  	BerolinaSQLtypes "github.com/whtcorpsinc/BerolinaSQL/types"
    32  	. "github.com/whtcorpsinc/check"
    33  	"github.com/whtcorpsinc/errors"
    34  	"github.com/whtcorpsinc/failpoint"
    35  	"github.com/whtcorpsinc/milevadb/blockcodec"
    36  	"github.com/whtcorpsinc/milevadb/causet"
    37  	"github.com/whtcorpsinc/milevadb/causet/blocks"
    38  	"github.com/whtcorpsinc/milevadb/causetstore/mockstore"
    39  	"github.com/whtcorpsinc/milevadb/causetstore/mockstore/cluster"
    40  	"github.com/whtcorpsinc/milevadb/config"
    41  	"github.com/whtcorpsinc/milevadb/dbs"
    42  	testdbsutil "github.com/whtcorpsinc/milevadb/dbs/solitonutil"
    43  	"github.com/whtcorpsinc/milevadb/ekv"
    44  	"github.com/whtcorpsinc/milevadb/errno"
    45  	"github.com/whtcorpsinc/milevadb/interlock"
    46  	"github.com/whtcorpsinc/milevadb/petri"
    47  	"github.com/whtcorpsinc/milevadb/schemareplicant"
    48  	"github.com/whtcorpsinc/milevadb/soliton/admin"
    49  	"github.com/whtcorpsinc/milevadb/soliton/codec"
    50  	"github.com/whtcorpsinc/milevadb/soliton/defCauslate"
    51  	"github.com/whtcorpsinc/milevadb/soliton/israce"
    52  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    53  	"github.com/whtcorpsinc/milevadb/soliton/petriutil"
    54  	"github.com/whtcorpsinc/milevadb/soliton/rowcodec"
    55  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    56  	"github.com/whtcorpsinc/milevadb/soliton/testkit"
    57  	"github.com/whtcorpsinc/milevadb/spacetime"
    58  	"github.com/whtcorpsinc/milevadb/spacetime/autoid"
    59  	"github.com/whtcorpsinc/milevadb/stochastik"
    60  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    61  	"github.com/whtcorpsinc/milevadb/types"
    62  )
    63  
    64  const (
    65  	// waitForCleanDataRound indicates how many times should we check data is cleaned or not.
    66  	waitForCleanDataRound = 150
    67  	// waitForCleanDataInterval is a min duration between 2 check for data clean.
    68  	waitForCleanDataInterval = time.Millisecond * 100
    69  )
    70  
    71  var _ = Suite(&testDBSuite1{&testDBSuite{}})
    72  var _ = Suite(&testDBSuite2{&testDBSuite{}})
    73  var _ = Suite(&testDBSuite3{&testDBSuite{}})
    74  var _ = Suite(&testDBSuite4{&testDBSuite{}})
    75  var _ = Suite(&testDBSuite5{&testDBSuite{}})
    76  var _ = Suite(&testDBSuite6{&testDBSuite{}})
    77  var _ = Suite(&testDBSuite7{&testDBSuite{}})
    78  var _ = SerialSuites(&testSerialDBSuite{&testDBSuite{}})
    79  
    80  const defaultBatchSize = 1024
    81  
    82  type testDBSuite struct {
    83  	cluster     cluster.Cluster
    84  	causetstore ekv.CausetStorage
    85  	dom         *petri.Petri
    86  	schemaName  string
    87  	s           stochastik.Stochastik
    88  	lease       time.Duration
    89  	autoIDStep  int64
    90  }
    91  
    92  func setUpSuite(s *testDBSuite, c *C) {
    93  	var err error
    94  
    95  	s.lease = 600 * time.Millisecond
    96  	stochastik.SetSchemaLease(s.lease)
    97  	stochastik.DisableStats4Test()
    98  	s.schemaName = "test_db"
    99  	s.autoIDStep = autoid.GetStep()
   100  	dbs.SetWaitTimeWhenErrorOccurred(0)
   101  
   102  	s.causetstore, err = mockstore.NewMockStore(
   103  		mockstore.WithClusterInspector(func(c cluster.Cluster) {
   104  			mockstore.BootstrapWithSingleStore(c)
   105  			s.cluster = c
   106  		}),
   107  	)
   108  	c.Assert(err, IsNil)
   109  
   110  	s.dom, err = stochastik.BootstrapStochastik(s.causetstore)
   111  	c.Assert(err, IsNil)
   112  	s.s, err = stochastik.CreateStochastik4Test(s.causetstore)
   113  	c.Assert(err, IsNil)
   114  
   115  	_, err = s.s.InterDircute(context.Background(), "create database test_db")
   116  	c.Assert(err, IsNil)
   117  	s.s.InterDircute(context.Background(), "set @@global.milevadb_max_delta_schema_count= 4096")
   118  }
   119  
   120  func tearDownSuite(s *testDBSuite, c *C) {
   121  	s.s.InterDircute(context.Background(), "drop database if exists test_db")
   122  	s.s.Close()
   123  	s.dom.Close()
   124  	s.causetstore.Close()
   125  }
   126  
   127  func (s *testDBSuite) SetUpSuite(c *C) {
   128  	setUpSuite(s, c)
   129  }
   130  
   131  func (s *testDBSuite) TearDownSuite(c *C) {
   132  	tearDownSuite(s, c)
   133  }
   134  
   135  type testDBSuite1 struct{ *testDBSuite }
   136  type testDBSuite2 struct{ *testDBSuite }
   137  type testDBSuite3 struct{ *testDBSuite }
   138  type testDBSuite4 struct{ *testDBSuite }
   139  type testDBSuite5 struct{ *testDBSuite }
   140  type testDBSuite6 struct{ *testDBSuite }
   141  type testDBSuite7 struct{ *testDBSuite }
   142  type testSerialDBSuite struct{ *testDBSuite }
   143  
   144  func testAddIndexWithPK(tk *testkit.TestKit, s *testSerialDBSuite, c *C) {
   145  	tk.MustInterDirc("drop causet if exists test_add_index_with_pk")
   146  	tk.MustInterDirc("create causet test_add_index_with_pk(a int not null, b int not null default '0', primary key(a))")
   147  	tk.MustInterDirc("insert into test_add_index_with_pk values(1, 2)")
   148  	tk.MustInterDirc("alter causet test_add_index_with_pk add index idx (a)")
   149  	tk.MustQuery("select a from test_add_index_with_pk").Check(testkit.Rows("1"))
   150  	tk.MustInterDirc("insert into test_add_index_with_pk values(2, 2)")
   151  	tk.MustInterDirc("alter causet test_add_index_with_pk add index idx1 (a, b)")
   152  	tk.MustQuery("select * from test_add_index_with_pk").Check(testkit.Rows("1 2", "2 2"))
   153  	tk.MustInterDirc("drop causet if exists test_add_index_with_pk1")
   154  	tk.MustInterDirc("create causet test_add_index_with_pk1(a int not null, b int not null default '0', c int, d int, primary key(c))")
   155  	tk.MustInterDirc("insert into test_add_index_with_pk1 values(1, 1, 1, 1)")
   156  	tk.MustInterDirc("alter causet test_add_index_with_pk1 add index idx (c)")
   157  	tk.MustInterDirc("insert into test_add_index_with_pk1 values(2, 2, 2, 2)")
   158  	tk.MustQuery("select * from test_add_index_with_pk1").Check(testkit.Rows("1 1 1 1", "2 2 2 2"))
   159  	tk.MustInterDirc("drop causet if exists test_add_index_with_pk2")
   160  	tk.MustInterDirc("create causet test_add_index_with_pk2(a int not null, b int not null default '0', c int unsigned, d int, primary key(c))")
   161  	tk.MustInterDirc("insert into test_add_index_with_pk2 values(1, 1, 1, 1)")
   162  	tk.MustInterDirc("alter causet test_add_index_with_pk2 add index idx (c)")
   163  	tk.MustInterDirc("insert into test_add_index_with_pk2 values(2, 2, 2, 2)")
   164  	tk.MustQuery("select * from test_add_index_with_pk2").Check(testkit.Rows("1 1 1 1", "2 2 2 2"))
   165  	tk.MustInterDirc("drop causet if exists t")
   166  	tk.MustInterDirc("create causet t (a int, b int, c int, primary key(a, b));")
   167  	tk.MustInterDirc("insert into t values (1, 2, 3);")
   168  	tk.MustInterDirc("create index idx on t (a, b);")
   169  }
   170  
   171  func (s *testSerialDBSuite) TestAddIndexWithPK(c *C) {
   172  	tk := testkit.NewTestKit(c, s.causetstore)
   173  	tk.MustInterDirc("use " + s.schemaName)
   174  	defer config.RestoreFunc()()
   175  	config.UFIDelateGlobal(func(conf *config.Config) {
   176  		conf.AlterPrimaryKey = false
   177  	})
   178  
   179  	testAddIndexWithPK(tk, s, c)
   180  	tk.MustInterDirc("set @@milevadb_enable_clustered_index = 1;")
   181  	testAddIndexWithPK(tk, s, c)
   182  }
   183  
   184  func (s *testDBSuite5) TestAddIndexWithDupIndex(c *C) {
   185  	tk := testkit.NewTestKit(c, s.causetstore)
   186  	tk.MustInterDirc("use " + s.schemaName)
   187  
   188  	err1 := dbs.ErrDupKeyName.GenWithStack("index already exist %s", "idx")
   189  	err2 := dbs.ErrDupKeyName.GenWithStack("index already exist %s; "+
   190  		"a background job is trying to add the same index, "+
   191  		"please check by `ADMIN SHOW DBS JOBS`", "idx")
   192  
   193  	// When there is already an duplicate index, show error message.
   194  	tk.MustInterDirc("create causet test_add_index_with_dup (a int, key idx (a))")
   195  	_, err := tk.InterDirc("alter causet test_add_index_with_dup add index idx (a)")
   196  	c.Check(errors.Cause(err1).(*terror.Error).Equal(err), Equals, true)
   197  	c.Assert(errors.Cause(err1).Error() == err.Error(), IsTrue)
   198  
   199  	// When there is another stochastik adding duplicate index with state other than
   200  	// StatePublic, show explicit error message.
   201  	t := s.testGetBlock(c, "test_add_index_with_dup")
   202  	indexInfo := t.Meta().FindIndexByName("idx")
   203  	indexInfo.State = perceptron.StateNone
   204  	_, err = tk.InterDirc("alter causet test_add_index_with_dup add index idx (a)")
   205  	c.Check(errors.Cause(err2).(*terror.Error).Equal(err), Equals, true)
   206  	c.Assert(errors.Cause(err2).Error() == err.Error(), IsTrue)
   207  
   208  	tk.MustInterDirc("drop causet test_add_index_with_dup")
   209  }
   210  
   211  func (s *testDBSuite1) TestRenameIndex(c *C) {
   212  	tk := testkit.NewTestKit(c, s.causetstore)
   213  	tk.MustInterDirc("use " + s.schemaName)
   214  	tk.MustInterDirc("create causet t (pk int primary key, c int default 1, c1 int default 1, unique key k1(c), key k2(c1))")
   215  
   216  	// Test rename success
   217  	tk.MustInterDirc("alter causet t rename index k1 to k3")
   218  	tk.MustInterDirc("admin check index t k3")
   219  
   220  	// Test rename to the same name
   221  	tk.MustInterDirc("alter causet t rename index k3 to k3")
   222  	tk.MustInterDirc("admin check index t k3")
   223  
   224  	// Test rename on non-exists keys
   225  	tk.MustGetErrCode("alter causet t rename index x to x", errno.ErrKeyDoesNotExist)
   226  
   227  	// Test rename on already-exists keys
   228  	tk.MustGetErrCode("alter causet t rename index k3 to k2", errno.ErrDupKeyName)
   229  
   230  	tk.MustInterDirc("alter causet t rename index k2 to K2")
   231  	tk.MustGetErrCode("alter causet t rename key k3 to K2", errno.ErrDupKeyName)
   232  }
   233  
   234  func testGetBlockByName(c *C, ctx stochastikctx.Context, EDB, causet string) causet.Block {
   235  	dom := petri.GetPetri(ctx)
   236  	// Make sure the causet schemaReplicant is the new schemaReplicant.
   237  	err := dom.Reload()
   238  	c.Assert(err, IsNil)
   239  	tbl, err := dom.SchemaReplicant().BlockByName(perceptron.NewCIStr(EDB), perceptron.NewCIStr(causet))
   240  	c.Assert(err, IsNil)
   241  	return tbl
   242  }
   243  
   244  func testGetSchemaByName(c *C, ctx stochastikctx.Context, EDB string) *perceptron.DBInfo {
   245  	dom := petri.GetPetri(ctx)
   246  	// Make sure the causet schemaReplicant is the new schemaReplicant.
   247  	err := dom.Reload()
   248  	c.Assert(err, IsNil)
   249  	dbInfo, ok := dom.SchemaReplicant().SchemaByName(perceptron.NewCIStr(EDB))
   250  	c.Assert(ok, IsTrue)
   251  	return dbInfo
   252  }
   253  
   254  func (s *testDBSuite) testGetBlock(c *C, name string) causet.Block {
   255  	ctx := s.s.(stochastikctx.Context)
   256  	return testGetBlockByName(c, ctx, s.schemaName, name)
   257  }
   258  
   259  func (s *testDBSuite) testGetDB(c *C, dbName string) *perceptron.DBInfo {
   260  	ctx := s.s.(stochastikctx.Context)
   261  	dom := petri.GetPetri(ctx)
   262  	// Make sure the causet schemaReplicant is the new schemaReplicant.
   263  	err := dom.Reload()
   264  	c.Assert(err, IsNil)
   265  	EDB, ok := dom.SchemaReplicant().SchemaByName(perceptron.NewCIStr(dbName))
   266  	c.Assert(ok, IsTrue)
   267  	return EDB
   268  }
   269  
   270  func backgroundInterDirc(s ekv.CausetStorage, allegrosql string, done chan error) {
   271  	se, err := stochastik.CreateStochastik4Test(s)
   272  	if err != nil {
   273  		done <- errors.Trace(err)
   274  		return
   275  	}
   276  	defer se.Close()
   277  	_, err = se.InterDircute(context.Background(), "use test_db")
   278  	if err != nil {
   279  		done <- errors.Trace(err)
   280  		return
   281  	}
   282  	_, err = se.InterDircute(context.Background(), allegrosql)
   283  	done <- errors.Trace(err)
   284  }
   285  
   286  // TestAddPrimaryKeyRollback1 is used to test scenarios that will roll back when a duplicate primary key is encountered.
   287  func (s *testDBSuite5) TestAddPrimaryKeyRollback1(c *C) {
   288  	hasNullValsInKey := false
   289  	idxName := "PRIMARY"
   290  	addIdxALLEGROSQL := "alter causet t1 add primary key c3_index (c3);"
   291  	errMsg := "[ekv:1062]Duplicate entry '' for key 'PRIMARY'"
   292  	testAddIndexRollback(c, s.causetstore, s.lease, idxName, addIdxALLEGROSQL, errMsg, hasNullValsInKey)
   293  }
   294  
   295  // TestAddPrimaryKeyRollback2 is used to test scenarios that will roll back when a null primary key is encountered.
   296  func (s *testDBSuite1) TestAddPrimaryKeyRollback2(c *C) {
   297  	hasNullValsInKey := true
   298  	idxName := "PRIMARY"
   299  	addIdxALLEGROSQL := "alter causet t1 add primary key c3_index (c3);"
   300  	errMsg := "[dbs:1138]Invalid use of NULL value"
   301  	testAddIndexRollback(c, s.causetstore, s.lease, idxName, addIdxALLEGROSQL, errMsg, hasNullValsInKey)
   302  }
   303  
   304  func (s *testDBSuite2) TestAddUniqueIndexRollback(c *C) {
   305  	hasNullValsInKey := false
   306  	idxName := "c3_index"
   307  	addIdxALLEGROSQL := "create unique index c3_index on t1 (c3)"
   308  	errMsg := "[ekv:1062]Duplicate entry '' for key 'c3_index'"
   309  	testAddIndexRollback(c, s.causetstore, s.lease, idxName, addIdxALLEGROSQL, errMsg, hasNullValsInKey)
   310  }
   311  
   312  func (s *testSerialDBSuite) TestAddExpressionIndexRollback(c *C) {
   313  	tk := testkit.NewTestKit(c, s.causetstore)
   314  	tk.MustInterDirc("use test_db")
   315  	tk.MustInterDirc("drop causet if exists t1")
   316  	tk.MustInterDirc("create causet t1 (c1 int, c2 int, c3 int, unique key(c1))")
   317  	tk.MustInterDirc("insert into t1 values (20, 20, 20), (40, 40, 40), (80, 80, 80), (160, 160, 160);")
   318  
   319  	var checkErr error
   320  	tk1 := testkit.NewTestKit(c, s.causetstore)
   321  	_, checkErr = tk1.InterDirc("use test_db")
   322  
   323  	d := s.dom.DBS()
   324  	hook := &dbs.TestDBSCallback{}
   325  	hook.OnJobUFIDelatedExported = func(job *perceptron.Job) {
   326  		if job.SchemaState == perceptron.StateDeleteOnly {
   327  			if checkErr != nil {
   328  				return
   329  			}
   330  			_, checkErr = tk1.InterDirc("delete from t1 where c1 = 40;")
   331  		}
   332  	}
   333  	d.(dbs.DBSForTest).SetHook(hook)
   334  
   335  	tk.MustGetErrMsg("alter causet t1 add index expr_idx ((pow(c1, c2)));", "[dbs:8202]Cannot decode index value, because [types:1690]DOUBLE value is out of range in 'pow(160, 160)'")
   336  	c.Assert(checkErr, IsNil)
   337  	tk.MustQuery("select * from t1;").Check(testkit.Rows("20 20 20", "80 80 80", "160 160 160"))
   338  }
   339  
   340  func batchInsert(tk *testkit.TestKit, tbl string, start, end int) {
   341  	dml := fmt.Sprintf("insert into %s values", tbl)
   342  	for i := start; i < end; i++ {
   343  		dml += fmt.Sprintf("(%d, %d, %d)", i, i, i)
   344  		if i != end-1 {
   345  			dml += ","
   346  		}
   347  	}
   348  	tk.MustInterDirc(dml)
   349  }
   350  
   351  func testAddIndexRollback(c *C, causetstore ekv.CausetStorage, lease time.Duration, idxName, addIdxALLEGROSQL, errMsg string, hasNullValsInKey bool) {
   352  	tk := testkit.NewTestKit(c, causetstore)
   353  	tk.MustInterDirc("use test_db")
   354  	tk.MustInterDirc("drop causet if exists t1")
   355  	tk.MustInterDirc("create causet t1 (c1 int, c2 int, c3 int, unique key(c1))")
   356  	// defaultBatchSize is equal to dbs.defaultBatchSize
   357  	base := defaultBatchSize * 2
   358  	count := base
   359  	// add some rows
   360  	batchInsert(tk, "t1", 0, count)
   361  	// add some null rows
   362  	if hasNullValsInKey {
   363  		for i := count - 10; i < count; i++ {
   364  			tk.MustInterDirc("insert into t1 values (?, ?, null)", i+10, i)
   365  		}
   366  	} else {
   367  		// add some duplicate rows
   368  		for i := count - 10; i < count; i++ {
   369  			tk.MustInterDirc("insert into t1 values (?, ?, ?)", i+10, i, i)
   370  		}
   371  	}
   372  
   373  	done := make(chan error, 1)
   374  	go backgroundInterDirc(causetstore, addIdxALLEGROSQL, done)
   375  
   376  	times := 0
   377  	ticker := time.NewTicker(lease / 2)
   378  	defer ticker.Stop()
   379  LOOP:
   380  	for {
   381  		select {
   382  		case err := <-done:
   383  			c.Assert(err, NotNil)
   384  			c.Assert(err.Error(), Equals, errMsg, Commentf("err:%v", err))
   385  			break LOOP
   386  		case <-ticker.C:
   387  			if times >= 10 {
   388  				break
   389  			}
   390  			step := 5
   391  			// delete some rows, and add some data
   392  			for i := count; i < count+step; i++ {
   393  				n := rand.Intn(count)
   394  				tk.MustInterDirc("delete from t1 where c1 = ?", n)
   395  				tk.MustInterDirc("insert into t1 values (?, ?, ?)", i+10, i, i)
   396  			}
   397  			count += step
   398  			times++
   399  		}
   400  	}
   401  
   402  	ctx := tk.Se.(stochastikctx.Context)
   403  	t := testGetBlockByName(c, ctx, "test_db", "t1")
   404  	for _, tidx := range t.Indices() {
   405  		c.Assert(strings.EqualFold(tidx.Meta().Name.L, idxName), IsFalse)
   406  	}
   407  
   408  	// delete duplicated/null rows, then add index
   409  	for i := base - 10; i < base; i++ {
   410  		tk.MustInterDirc("delete from t1 where c1 = ?", i+10)
   411  	}
   412  	stochastikInterDirc(c, causetstore, addIdxALLEGROSQL)
   413  	tk.MustInterDirc("drop causet t1")
   414  }
   415  
   416  func (s *testDBSuite5) TestCancelAddPrimaryKey(c *C) {
   417  	idxName := "primary"
   418  	addIdxALLEGROSQL := "alter causet t1 add primary key idx_c2 (c2);"
   419  	testCancelAddIndex(c, s.causetstore, s.dom.DBS(), s.lease, idxName, addIdxALLEGROSQL, "")
   420  
   421  	// Check the defCausumn's flag when the "add primary key" failed.
   422  	tk := testkit.NewTestKit(c, s.causetstore)
   423  	tk.MustInterDirc("use test_db")
   424  	ctx := tk.Se.(stochastikctx.Context)
   425  	c.Assert(ctx.NewTxn(context.Background()), IsNil)
   426  	t := testGetBlockByName(c, ctx, "test_db", "t1")
   427  	defCaus1Flag := t.DefCauss()[1].Flag
   428  	c.Assert(!allegrosql.HasNotNullFlag(defCaus1Flag) && !allegrosql.HasPreventNullInsertFlag(defCaus1Flag) && allegrosql.HasUnsignedFlag(defCaus1Flag), IsTrue)
   429  	tk.MustInterDirc("drop causet t1")
   430  }
   431  
   432  func (s *testDBSuite3) TestCancelAddIndex(c *C) {
   433  	idxName := "c3_index "
   434  	addIdxALLEGROSQL := "create unique index c3_index on t1 (c3)"
   435  	testCancelAddIndex(c, s.causetstore, s.dom.DBS(), s.lease, idxName, addIdxALLEGROSQL, "")
   436  
   437  	tk := testkit.NewTestKit(c, s.causetstore)
   438  	tk.MustInterDirc("use test_db")
   439  	tk.MustInterDirc("drop causet t1")
   440  }
   441  
   442  func testCancelAddIndex(c *C, causetstore ekv.CausetStorage, d dbs.DBS, lease time.Duration, idxName, addIdxALLEGROSQL, sqlModeALLEGROSQL string) {
   443  	tk := testkit.NewTestKit(c, causetstore)
   444  	tk.MustInterDirc("use test_db")
   445  	tk.MustInterDirc("drop causet if exists t1")
   446  	tk.MustInterDirc("create causet t1 (c1 int, c2 int unsigned, c3 int, unique key(c1))")
   447  	// defaultBatchSize is equal to dbs.defaultBatchSize
   448  	count := defaultBatchSize * 32
   449  	start := 0
   450  	// add some rows
   451  	if len(sqlModeALLEGROSQL) != 0 {
   452  		// Insert some null values.
   453  		tk.MustInterDirc(sqlModeALLEGROSQL)
   454  		tk.MustInterDirc("insert into t1 set c1 = ?", 0)
   455  		tk.MustInterDirc("insert into t1 set c2 = ?", 1)
   456  		tk.MustInterDirc("insert into t1 set c3 = ?", 2)
   457  		start = 3
   458  	}
   459  	for i := start; i < count; i += defaultBatchSize {
   460  		batchInsert(tk, "t1", i, i+defaultBatchSize)
   461  	}
   462  
   463  	var c3IdxInfo *perceptron.IndexInfo
   464  	hook := &dbs.TestDBSCallback{}
   465  	originBatchSize := tk.MustQuery("select @@global.milevadb_dbs_reorg_batch_size")
   466  	// Set batch size to lower try to slow down add-index reorganization, This if for hook to cancel this dbs job.
   467  	tk.MustInterDirc("set @@global.milevadb_dbs_reorg_batch_size = 32")
   468  	defer tk.MustInterDirc(fmt.Sprintf("set @@global.milevadb_dbs_reorg_batch_size = %v", originBatchSize.Rows()[0][0]))
   469  	// let hook.OnJobUFIDelatedExported has chance to cancel the job.
   470  	// the hook.OnJobUFIDelatedExported is called when the job is uFIDelated, runReorgJob will wait dbs.ReorgWaitTimeout, then return the dbs.runDBSJob.
   471  	// After that dbs call d.hook.OnJobUFIDelated(job), so that we can canceled the job in this test case.
   472  	var checkErr error
   473  	ctx := tk.Se.(stochastikctx.Context)
   474  	hook.OnJobUFIDelatedExported, c3IdxInfo, checkErr = backgroundInterDircOnJobUFIDelatedExported(c, causetstore, ctx, hook, idxName)
   475  	originalHook := d.GetHook()
   476  	d.(dbs.DBSForTest).SetHook(hook)
   477  	done := make(chan error, 1)
   478  	go backgroundInterDirc(causetstore, addIdxALLEGROSQL, done)
   479  
   480  	times := 0
   481  	ticker := time.NewTicker(lease / 2)
   482  	defer ticker.Stop()
   483  LOOP:
   484  	for {
   485  		select {
   486  		case err := <-done:
   487  			c.Assert(checkErr, IsNil)
   488  			c.Assert(err, NotNil)
   489  			c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job")
   490  			break LOOP
   491  		case <-ticker.C:
   492  			if times >= 10 {
   493  				break
   494  			}
   495  			step := 5
   496  			// delete some rows, and add some data
   497  			for i := count; i < count+step; i++ {
   498  				n := rand.Intn(count)
   499  				tk.MustInterDirc("delete from t1 where c1 = ?", n)
   500  				tk.MustInterDirc("insert into t1 values (?, ?, ?)", i+10, i, i)
   501  			}
   502  			count += step
   503  			times++
   504  		}
   505  	}
   506  
   507  	t := testGetBlockByName(c, ctx, "test_db", "t1")
   508  	for _, tidx := range t.Indices() {
   509  		c.Assert(strings.EqualFold(tidx.Meta().Name.L, idxName), IsFalse)
   510  	}
   511  
   512  	idx := blocks.NewIndex(t.Meta().ID, t.Meta(), c3IdxInfo)
   513  	checkDelRangeDone(c, ctx, idx)
   514  	d.(dbs.DBSForTest).SetHook(originalHook)
   515  }
   516  
   517  // TestCancelAddIndex1 tests canceling dbs job when the add index worker is not started.
   518  func (s *testDBSuite4) TestCancelAddIndex1(c *C) {
   519  	tk := testkit.NewTestKit(c, s.causetstore)
   520  	s.mustInterDirc(tk, c, "use test_db")
   521  	s.mustInterDirc(tk, c, "drop causet if exists t")
   522  	s.mustInterDirc(tk, c, "create causet t(c1 int, c2 int)")
   523  	defer s.mustInterDirc(tk, c, "drop causet t;")
   524  
   525  	for i := 0; i < 50; i++ {
   526  		s.mustInterDirc(tk, c, "insert into t values (?, ?)", i, i)
   527  	}
   528  
   529  	var checkErr error
   530  	hook := &dbs.TestDBSCallback{}
   531  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
   532  		if job.Type == perceptron.CausetActionAddIndex && job.State == perceptron.JobStateRunning && job.SchemaState == perceptron.StateWriteReorganization && job.SnapshotVer == 0 {
   533  			jobIDs := []int64{job.ID}
   534  			hookCtx := mock.NewContext()
   535  			hookCtx.CausetStore = s.causetstore
   536  			err := hookCtx.NewTxn(context.Background())
   537  			if err != nil {
   538  				checkErr = errors.Trace(err)
   539  				return
   540  			}
   541  			txn, err := hookCtx.Txn(true)
   542  			if err != nil {
   543  				checkErr = errors.Trace(err)
   544  				return
   545  			}
   546  			errs, err := admin.CancelJobs(txn, jobIDs)
   547  			if err != nil {
   548  				checkErr = errors.Trace(err)
   549  				return
   550  			}
   551  
   552  			if errs[0] != nil {
   553  				checkErr = errors.Trace(errs[0])
   554  				return
   555  			}
   556  
   557  			checkErr = txn.Commit(context.Background())
   558  		}
   559  	}
   560  	originalHook := s.dom.DBS().GetHook()
   561  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
   562  	rs, err := tk.InterDirc("alter causet t add index idx_c2(c2)")
   563  	if rs != nil {
   564  		rs.Close()
   565  	}
   566  	c.Assert(checkErr, IsNil)
   567  	c.Assert(err, NotNil)
   568  	c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job")
   569  
   570  	s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
   571  	t := s.testGetBlock(c, "t")
   572  	for _, idx := range t.Indices() {
   573  		c.Assert(strings.EqualFold(idx.Meta().Name.L, "idx_c2"), IsFalse)
   574  	}
   575  	s.mustInterDirc(tk, c, "alter causet t add index idx_c2(c2)")
   576  	s.mustInterDirc(tk, c, "alter causet t drop index idx_c2")
   577  }
   578  
   579  // TestCancelDropIndex tests cancel dbs job which type is drop primary key.
   580  func (s *testDBSuite4) TestCancelDropPrimaryKey(c *C) {
   581  	idxName := "primary"
   582  	addIdxALLEGROSQL := "alter causet t add primary key idx_c2 (c2);"
   583  	dropIdxALLEGROSQL := "alter causet t drop primary key;"
   584  	testCancelDropIndex(c, s.causetstore, s.dom.DBS(), idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL)
   585  }
   586  
   587  // TestCancelDropIndex tests cancel dbs job which type is drop index.
   588  func (s *testDBSuite5) TestCancelDropIndex(c *C) {
   589  	idxName := "idx_c2"
   590  	addIdxALLEGROSQL := "alter causet t add index idx_c2 (c2);"
   591  	dropIdxALLEGROSQL := "alter causet t drop index idx_c2;"
   592  	testCancelDropIndex(c, s.causetstore, s.dom.DBS(), idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL)
   593  }
   594  
   595  // testCancelDropIndex tests cancel dbs job which type is drop index.
   596  func testCancelDropIndex(c *C, causetstore ekv.CausetStorage, d dbs.DBS, idxName, addIdxALLEGROSQL, dropIdxALLEGROSQL string) {
   597  	tk := testkit.NewTestKit(c, causetstore)
   598  	tk.MustInterDirc("use test_db")
   599  	tk.MustInterDirc("drop causet if exists t")
   600  	tk.MustInterDirc("create causet t(c1 int, c2 int)")
   601  	defer tk.MustInterDirc("drop causet t;")
   602  	for i := 0; i < 5; i++ {
   603  		tk.MustInterDirc("insert into t values (?, ?)", i, i)
   604  	}
   605  	testCases := []struct {
   606  		needAddIndex   bool
   607  		jobState       perceptron.JobState
   608  		JobSchemaState perceptron.SchemaState
   609  		cancelSucc     bool
   610  	}{
   611  		// perceptron.JobStateNone means the jobs is canceled before the first run.
   612  		// if we cancel successfully, we need to set needAddIndex to false in the next test case. Otherwise, set needAddIndex to true.
   613  		{true, perceptron.JobStateNone, perceptron.StateNone, true},
   614  		{false, perceptron.JobStateRunning, perceptron.StateWriteOnly, false},
   615  		{true, perceptron.JobStateRunning, perceptron.StateDeleteOnly, false},
   616  		{true, perceptron.JobStateRunning, perceptron.StateDeleteReorganization, false},
   617  	}
   618  	var checkErr error
   619  	hook := &dbs.TestDBSCallback{}
   620  	var jobID int64
   621  	testCase := &testCases[0]
   622  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
   623  		if (job.Type == perceptron.CausetActionDropIndex || job.Type == perceptron.CausetActionDropPrimaryKey) &&
   624  			job.State == testCase.jobState && job.SchemaState == testCase.JobSchemaState {
   625  			jobID = job.ID
   626  			jobIDs := []int64{job.ID}
   627  			hookCtx := mock.NewContext()
   628  			hookCtx.CausetStore = causetstore
   629  			err := hookCtx.NewTxn(context.TODO())
   630  			if err != nil {
   631  				checkErr = errors.Trace(err)
   632  				return
   633  			}
   634  			txn, err := hookCtx.Txn(true)
   635  			if err != nil {
   636  				checkErr = errors.Trace(err)
   637  				return
   638  			}
   639  
   640  			errs, err := admin.CancelJobs(txn, jobIDs)
   641  			if err != nil {
   642  				checkErr = errors.Trace(err)
   643  				return
   644  			}
   645  			if errs[0] != nil {
   646  				checkErr = errors.Trace(errs[0])
   647  				return
   648  			}
   649  			checkErr = txn.Commit(context.Background())
   650  		}
   651  	}
   652  	originalHook := d.GetHook()
   653  	d.(dbs.DBSForTest).SetHook(hook)
   654  	ctx := tk.Se.(stochastikctx.Context)
   655  	for i := range testCases {
   656  		testCase = &testCases[i]
   657  		if testCase.needAddIndex {
   658  			tk.MustInterDirc(addIdxALLEGROSQL)
   659  		}
   660  		rs, err := tk.InterDirc(dropIdxALLEGROSQL)
   661  		if rs != nil {
   662  			rs.Close()
   663  		}
   664  		t := testGetBlockByName(c, ctx, "test_db", "t")
   665  		indexInfo := t.Meta().FindIndexByName(idxName)
   666  		if testCase.cancelSucc {
   667  			c.Assert(checkErr, IsNil)
   668  			c.Assert(err, NotNil)
   669  			c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job")
   670  			c.Assert(indexInfo, NotNil)
   671  			c.Assert(indexInfo.State, Equals, perceptron.StatePublic)
   672  		} else {
   673  			err1 := admin.ErrCannotCancelDBSJob.GenWithStackByArgs(jobID)
   674  			c.Assert(err, IsNil)
   675  			c.Assert(checkErr, NotNil)
   676  			c.Assert(checkErr.Error(), Equals, err1.Error())
   677  			c.Assert(indexInfo, IsNil)
   678  		}
   679  	}
   680  	d.(dbs.DBSForTest).SetHook(originalHook)
   681  	tk.MustInterDirc(addIdxALLEGROSQL)
   682  	tk.MustInterDirc(dropIdxALLEGROSQL)
   683  }
   684  
   685  // TestCancelTruncateBlock tests cancel dbs job which type is truncate causet.
   686  func (s *testDBSuite5) TestCancelTruncateBlock(c *C) {
   687  	tk := testkit.NewTestKit(c, s.causetstore)
   688  	s.mustInterDirc(tk, c, "use test_db")
   689  	s.mustInterDirc(tk, c, "create database if not exists test_truncate_block")
   690  	s.mustInterDirc(tk, c, "drop causet if exists t")
   691  	s.mustInterDirc(tk, c, "create causet t(c1 int, c2 int)")
   692  	defer s.mustInterDirc(tk, c, "drop causet t;")
   693  	var checkErr error
   694  	hook := &dbs.TestDBSCallback{}
   695  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
   696  		if job.Type == perceptron.CausetActionTruncateBlock && job.State == perceptron.JobStateNone {
   697  			jobIDs := []int64{job.ID}
   698  			hookCtx := mock.NewContext()
   699  			hookCtx.CausetStore = s.causetstore
   700  			err := hookCtx.NewTxn(context.Background())
   701  			if err != nil {
   702  				checkErr = errors.Trace(err)
   703  				return
   704  			}
   705  			txn, err := hookCtx.Txn(true)
   706  			if err != nil {
   707  				checkErr = errors.Trace(err)
   708  				return
   709  			}
   710  			errs, err := admin.CancelJobs(txn, jobIDs)
   711  			if err != nil {
   712  				checkErr = errors.Trace(err)
   713  				return
   714  			}
   715  			if errs[0] != nil {
   716  				checkErr = errors.Trace(errs[0])
   717  				return
   718  			}
   719  			checkErr = txn.Commit(context.Background())
   720  		}
   721  	}
   722  	originalHook := s.dom.DBS().GetHook()
   723  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
   724  	_, err := tk.InterDirc("truncate causet t")
   725  	c.Assert(checkErr, IsNil)
   726  	c.Assert(err, NotNil)
   727  	c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job")
   728  	s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
   729  }
   730  
   731  func (s *testDBSuite5) TestParallelDropSchemaAndDropBlock(c *C) {
   732  	tk := testkit.NewTestKit(c, s.causetstore)
   733  	s.mustInterDirc(tk, c, "create database if not exists test_drop_schema_block")
   734  	s.mustInterDirc(tk, c, "use test_drop_schema_block")
   735  	s.mustInterDirc(tk, c, "create causet t(c1 int, c2 int)")
   736  	var checkErr error
   737  	hook := &dbs.TestDBSCallback{}
   738  	dbInfo := testGetSchemaByName(c, tk.Se, "test_drop_schema_block")
   739  	done := false
   740  	var wg sync.WaitGroup
   741  	tk2 := testkit.NewTestKit(c, s.causetstore)
   742  	tk2.MustInterDirc("use test_drop_schema_block")
   743  	hook.OnJobUFIDelatedExported = func(job *perceptron.Job) {
   744  		if job.Type == perceptron.CausetActionDropSchema && job.State == perceptron.JobStateRunning &&
   745  			job.SchemaState == perceptron.StateWriteOnly && job.SchemaID == dbInfo.ID && done == false {
   746  			wg.Add(1)
   747  			done = true
   748  			go func() {
   749  				_, checkErr = tk2.InterDirc("drop causet t")
   750  				wg.Done()
   751  			}()
   752  			time.Sleep(5 * time.Millisecond)
   753  		}
   754  	}
   755  	originalHook := s.dom.DBS().GetHook()
   756  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
   757  	s.mustInterDirc(tk, c, "drop database test_drop_schema_block")
   758  	s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
   759  	wg.Wait()
   760  	c.Assert(done, IsTrue)
   761  	c.Assert(checkErr, NotNil)
   762  	// There are two possible assert result because:
   763  	// 1: If drop-database is finished before drop-causet being put into the dbs job queue, it will return "unknown causet" error directly in the previous check.
   764  	// 2: If drop-causet has passed the previous check and been put into the dbs job queue, then drop-database finished, it will return schemaReplicant change error.
   765  	assertRes := checkErr.Error() == "[petri:8028]Information schemaReplicant is changed during the execution of the"+
   766  		" memex(for example, causet definition may be uFIDelated by other DBS ran in parallel). "+
   767  		"If you see this error often, try increasing `milevadb_max_delta_schema_count`. [try again later]" ||
   768  		checkErr.Error() == "[schemaReplicant:1051]Unknown causet 'test_drop_schema_block.t'"
   769  
   770  	c.Assert(assertRes, Equals, true)
   771  
   772  	// Below behaviour is use to mock query `curl "http://$IP:10080/tiflash/replica"`
   773  	fn := func(jobs []*perceptron.Job) (bool, error) {
   774  		return interlock.GetDropOrTruncateBlockInfoFromJobs(jobs, 0, s.dom, func(job *perceptron.Job, info *perceptron.BlockInfo) (bool, error) {
   775  			return false, nil
   776  		})
   777  	}
   778  	err := tk.Se.NewTxn(context.Background())
   779  	c.Assert(err, IsNil)
   780  	txn, err := tk.Se.Txn(true)
   781  	c.Assert(err, IsNil)
   782  	err = admin.IterHistoryDBSJobs(txn, fn)
   783  	c.Assert(err, IsNil)
   784  }
   785  
   786  // TestCancelRenameIndex tests cancel dbs job which type is rename index.
   787  func (s *testDBSuite1) TestCancelRenameIndex(c *C) {
   788  	tk := testkit.NewTestKit(c, s.causetstore)
   789  	s.mustInterDirc(tk, c, "use test_db")
   790  	s.mustInterDirc(tk, c, "create database if not exists test_rename_index")
   791  	s.mustInterDirc(tk, c, "drop causet if exists t")
   792  	s.mustInterDirc(tk, c, "create causet t(c1 int, c2 int)")
   793  	defer s.mustInterDirc(tk, c, "drop causet t;")
   794  	for i := 0; i < 100; i++ {
   795  		s.mustInterDirc(tk, c, "insert into t values (?, ?)", i, i)
   796  	}
   797  	s.mustInterDirc(tk, c, "alter causet t add index idx_c2(c2)")
   798  	var checkErr error
   799  	hook := &dbs.TestDBSCallback{}
   800  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
   801  		if job.Type == perceptron.CausetActionRenameIndex && job.State == perceptron.JobStateNone {
   802  			jobIDs := []int64{job.ID}
   803  			hookCtx := mock.NewContext()
   804  			hookCtx.CausetStore = s.causetstore
   805  			err := hookCtx.NewTxn(context.Background())
   806  			if err != nil {
   807  				checkErr = errors.Trace(err)
   808  				return
   809  			}
   810  			txn, err := hookCtx.Txn(true)
   811  			if err != nil {
   812  				checkErr = errors.Trace(err)
   813  				return
   814  			}
   815  			errs, err := admin.CancelJobs(txn, jobIDs)
   816  			if err != nil {
   817  				checkErr = errors.Trace(err)
   818  				return
   819  			}
   820  			if errs[0] != nil {
   821  				checkErr = errors.Trace(errs[0])
   822  				return
   823  			}
   824  			checkErr = txn.Commit(context.Background())
   825  		}
   826  	}
   827  	originalHook := s.dom.DBS().GetHook()
   828  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
   829  	rs, err := tk.InterDirc("alter causet t rename index idx_c2 to idx_c3")
   830  	if rs != nil {
   831  		rs.Close()
   832  	}
   833  	c.Assert(checkErr, IsNil)
   834  	c.Assert(err, NotNil)
   835  	c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job")
   836  	s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
   837  	t := s.testGetBlock(c, "t")
   838  	for _, idx := range t.Indices() {
   839  		c.Assert(strings.EqualFold(idx.Meta().Name.L, "idx_c3"), IsFalse)
   840  	}
   841  	s.mustInterDirc(tk, c, "alter causet t rename index idx_c2 to idx_c3")
   842  }
   843  
   844  // TestCancelDropBlock tests cancel dbs job which type is drop causet.
   845  func (s *testDBSuite2) TestCancelDropBlockAndSchema(c *C) {
   846  	tk := testkit.NewTestKit(c, s.causetstore)
   847  	testCases := []struct {
   848  		needAddBlockOrDB bool
   849  		action           perceptron.CausetActionType
   850  		jobState         perceptron.JobState
   851  		JobSchemaState   perceptron.SchemaState
   852  		cancelSucc       bool
   853  	}{
   854  		// Check drop causet.
   855  		// perceptron.JobStateNone means the jobs is canceled before the first run.
   856  		{true, perceptron.CausetActionDropBlock, perceptron.JobStateNone, perceptron.StateNone, true},
   857  		{false, perceptron.CausetActionDropBlock, perceptron.JobStateRunning, perceptron.StateWriteOnly, false},
   858  		{true, perceptron.CausetActionDropBlock, perceptron.JobStateRunning, perceptron.StateDeleteOnly, false},
   859  
   860  		// Check drop database.
   861  		{true, perceptron.CausetActionDropSchema, perceptron.JobStateNone, perceptron.StateNone, true},
   862  		{false, perceptron.CausetActionDropSchema, perceptron.JobStateRunning, perceptron.StateWriteOnly, false},
   863  		{true, perceptron.CausetActionDropSchema, perceptron.JobStateRunning, perceptron.StateDeleteOnly, false},
   864  	}
   865  	var checkErr error
   866  	hook := &dbs.TestDBSCallback{}
   867  	var jobID int64
   868  	testCase := &testCases[0]
   869  	s.mustInterDirc(tk, c, "create database if not exists test_drop_db")
   870  	dbInfo := s.testGetDB(c, "test_drop_db")
   871  
   872  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
   873  		if job.Type == testCase.action && job.State == testCase.jobState && job.SchemaState == testCase.JobSchemaState && job.SchemaID == dbInfo.ID {
   874  			jobIDs := []int64{job.ID}
   875  			jobID = job.ID
   876  			hookCtx := mock.NewContext()
   877  			hookCtx.CausetStore = s.causetstore
   878  			err := hookCtx.NewTxn(context.TODO())
   879  			if err != nil {
   880  				checkErr = errors.Trace(err)
   881  				return
   882  			}
   883  			txn, err := hookCtx.Txn(true)
   884  			if err != nil {
   885  				checkErr = errors.Trace(err)
   886  				return
   887  			}
   888  			errs, err := admin.CancelJobs(txn, jobIDs)
   889  			if err != nil {
   890  				checkErr = errors.Trace(err)
   891  				return
   892  			}
   893  			if errs[0] != nil {
   894  				checkErr = errors.Trace(errs[0])
   895  				return
   896  			}
   897  			checkErr = txn.Commit(context.Background())
   898  		}
   899  	}
   900  	originHook := s.dom.DBS().GetHook()
   901  	defer s.dom.DBS().(dbs.DBSForTest).SetHook(originHook)
   902  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
   903  	var err error
   904  	allegrosql := ""
   905  	for i := range testCases {
   906  		testCase = &testCases[i]
   907  		if testCase.needAddBlockOrDB {
   908  			s.mustInterDirc(tk, c, "create database if not exists test_drop_db")
   909  			s.mustInterDirc(tk, c, "use test_drop_db")
   910  			s.mustInterDirc(tk, c, "create causet if not exists t(c1 int, c2 int)")
   911  		}
   912  
   913  		dbInfo = s.testGetDB(c, "test_drop_db")
   914  
   915  		if testCase.action == perceptron.CausetActionDropBlock {
   916  			allegrosql = "drop causet t;"
   917  		} else if testCase.action == perceptron.CausetActionDropSchema {
   918  			allegrosql = "drop database test_drop_db;"
   919  		}
   920  
   921  		_, err = tk.InterDirc(allegrosql)
   922  		if testCase.cancelSucc {
   923  			c.Assert(checkErr, IsNil)
   924  			c.Assert(err, NotNil)
   925  			c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job")
   926  			s.mustInterDirc(tk, c, "insert into t values (?, ?)", i, i)
   927  		} else {
   928  			c.Assert(err, IsNil)
   929  			c.Assert(checkErr, NotNil)
   930  			c.Assert(checkErr.Error(), Equals, admin.ErrCannotCancelDBSJob.GenWithStackByArgs(jobID).Error())
   931  			_, err = tk.InterDirc("insert into t values (?, ?)", i, i)
   932  			c.Assert(err, NotNil)
   933  		}
   934  	}
   935  }
   936  
   937  func (s *testDBSuite3) TestAddAnonymousIndex(c *C) {
   938  	tk := testkit.NewTestKit(c, s.causetstore)
   939  	tk.MustInterDirc("use " + s.schemaName)
   940  	s.mustInterDirc(tk, c, "create causet t_anonymous_index (c1 int, c2 int, C3 int)")
   941  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index (c1, c2)")
   942  	// for dropping empty index
   943  	_, err := tk.InterDirc("alter causet t_anonymous_index drop index")
   944  	c.Assert(err, NotNil)
   945  	// The index name is c1 when adding index (c1, c2).
   946  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c1")
   947  	t := s.testGetBlock(c, "t_anonymous_index")
   948  	c.Assert(t.Indices(), HasLen, 0)
   949  	// for adding some indices that the first defCausumn name is c1
   950  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index (c1)")
   951  	_, err = tk.InterDirc("alter causet t_anonymous_index add index c1 (c2)")
   952  	c.Assert(err, NotNil)
   953  	t = s.testGetBlock(c, "t_anonymous_index")
   954  	c.Assert(t.Indices(), HasLen, 1)
   955  	idx := t.Indices()[0].Meta().Name.L
   956  	c.Assert(idx, Equals, "c1")
   957  	// The MyALLEGROSQL will be a warning.
   958  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index c1_3 (c1)")
   959  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index (c1, c2, C3)")
   960  	// The MyALLEGROSQL will be a warning.
   961  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index (c1)")
   962  	t = s.testGetBlock(c, "t_anonymous_index")
   963  	c.Assert(t.Indices(), HasLen, 4)
   964  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c1")
   965  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c1_2")
   966  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c1_3")
   967  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c1_4")
   968  	// for case insensitive
   969  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index (C3)")
   970  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index c3")
   971  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index add index c3 (C3)")
   972  	s.mustInterDirc(tk, c, "alter causet t_anonymous_index drop index C3")
   973  	// for anonymous index with defCausumn name `primary`
   974  	s.mustInterDirc(tk, c, "create causet t_primary (`primary` int, b int, key (`primary`))")
   975  	t = s.testGetBlock(c, "t_primary")
   976  	c.Assert(t.Indices()[0].Meta().Name.String(), Equals, "primary_2")
   977  	s.mustInterDirc(tk, c, "alter causet t_primary add index (`primary`);")
   978  	t = s.testGetBlock(c, "t_primary")
   979  	c.Assert(t.Indices()[0].Meta().Name.String(), Equals, "primary_2")
   980  	c.Assert(t.Indices()[1].Meta().Name.String(), Equals, "primary_3")
   981  	s.mustInterDirc(tk, c, "alter causet t_primary add primary key(b);")
   982  	t = s.testGetBlock(c, "t_primary")
   983  	c.Assert(t.Indices()[0].Meta().Name.String(), Equals, "primary_2")
   984  	c.Assert(t.Indices()[1].Meta().Name.String(), Equals, "primary_3")
   985  	c.Assert(t.Indices()[2].Meta().Name.L, Equals, "primary")
   986  	s.mustInterDirc(tk, c, "create causet t_primary_2 (`primary` int, key primary_2 (`primary`), key (`primary`))")
   987  	t = s.testGetBlock(c, "t_primary_2")
   988  	c.Assert(t.Indices()[0].Meta().Name.String(), Equals, "primary_2")
   989  	c.Assert(t.Indices()[1].Meta().Name.String(), Equals, "primary_3")
   990  	s.mustInterDirc(tk, c, "create causet t_primary_3 (`primary_2` int, key(`primary_2`), `primary` int, key(`primary`));")
   991  	t = s.testGetBlock(c, "t_primary_3")
   992  	c.Assert(t.Indices()[0].Meta().Name.String(), Equals, "primary_2")
   993  	c.Assert(t.Indices()[1].Meta().Name.String(), Equals, "primary_3")
   994  }
   995  
   996  func (s *testDBSuite4) TestAlterLock(c *C) {
   997  	tk := testkit.NewTestKit(c, s.causetstore)
   998  	tk.MustInterDirc("use " + s.schemaName)
   999  	s.mustInterDirc(tk, c, "create causet t_index_lock (c1 int, c2 int, C3 int)")
  1000  	s.mustInterDirc(tk, c, "alter causet t_index_lock add index (c1, c2), dagger=none")
  1001  }
  1002  
  1003  func (s *testDBSuite5) TestAddMultiDeferredCausetsIndex(c *C) {
  1004  	tk := testkit.NewTestKit(c, s.causetstore)
  1005  	tk.MustInterDirc("use " + s.schemaName)
  1006  
  1007  	tk.MustInterDirc("drop database if exists milevadb;")
  1008  	tk.MustInterDirc("create database milevadb;")
  1009  	tk.MustInterDirc("use milevadb;")
  1010  	tk.MustInterDirc("create causet milevadb.test (a int auto_increment primary key, b int);")
  1011  	tk.MustInterDirc("insert milevadb.test values (1, 1);")
  1012  	tk.MustInterDirc("uFIDelate milevadb.test set b = b + 1 where a = 1;")
  1013  	tk.MustInterDirc("insert into milevadb.test values (2, 2);")
  1014  	// Test that the b value is nil.
  1015  	tk.MustInterDirc("insert into milevadb.test (a) values (3);")
  1016  	tk.MustInterDirc("insert into milevadb.test values (4, 4);")
  1017  	// Test that the b value is nil again.
  1018  	tk.MustInterDirc("insert into milevadb.test (a) values (5);")
  1019  	tk.MustInterDirc("insert milevadb.test values (6, 6);")
  1020  	tk.MustInterDirc("alter causet milevadb.test add index idx1 (a, b);")
  1021  	tk.MustInterDirc("admin check causet test")
  1022  }
  1023  
  1024  func (s *testDBSuite6) TestAddMultiDeferredCausetsIndexClusterIndex(c *C) {
  1025  	tk := testkit.NewTestKit(c, s.causetstore)
  1026  	tk.MustInterDirc("drop database if exists test_add_multi_defCaus_index_clustered;")
  1027  	tk.MustInterDirc("create database test_add_multi_defCaus_index_clustered;")
  1028  	tk.MustInterDirc("use test_add_multi_defCaus_index_clustered;")
  1029  
  1030  	tk.MustInterDirc("set @@milevadb_enable_clustered_index = 1")
  1031  	tk.MustInterDirc("create causet t (a int, b varchar(10), c int, primary key (a, b));")
  1032  	tk.MustInterDirc("insert into t values (1, '1', 1), (2, '2', NULL), (3, '3', 3);")
  1033  	tk.MustInterDirc("create index idx on t (a, c);")
  1034  
  1035  	tk.MustInterDirc("admin check index t idx;")
  1036  	tk.MustInterDirc("admin check causet t;")
  1037  
  1038  	tk.MustInterDirc("insert into t values (5, '5', 5), (6, '6', NULL);")
  1039  
  1040  	tk.MustInterDirc("admin check index t idx;")
  1041  	tk.MustInterDirc("admin check causet t;")
  1042  }
  1043  
  1044  func (s *testDBSuite1) TestAddPrimaryKey1(c *C) {
  1045  	testAddIndex(c, s.causetstore, s.lease, testPlain,
  1046  		"create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, unique key(c1))", "primary")
  1047  }
  1048  
  1049  func (s *testDBSuite2) TestAddPrimaryKey2(c *C) {
  1050  	testAddIndex(c, s.causetstore, s.lease, testPartition,
  1051  		`create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, key(c1))
  1052  			      partition by range (c3) (
  1053  			      partition p0 values less than (3440),
  1054  			      partition p1 values less than (61440),
  1055  			      partition p2 values less than (122880),
  1056  			      partition p3 values less than (204800),
  1057  			      partition p4 values less than maxvalue)`, "primary")
  1058  }
  1059  
  1060  func (s *testDBSuite3) TestAddPrimaryKey3(c *C) {
  1061  	testAddIndex(c, s.causetstore, s.lease, testPartition,
  1062  		`create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, key(c1))
  1063  			      partition by hash (c3) partitions 4;`, "primary")
  1064  }
  1065  
  1066  func (s *testDBSuite4) TestAddPrimaryKey4(c *C) {
  1067  	testAddIndex(c, s.causetstore, s.lease, testPartition,
  1068  		`create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, key(c1))
  1069  			      partition by range defCausumns (c3) (
  1070  			      partition p0 values less than (3440),
  1071  			      partition p1 values less than (61440),
  1072  			      partition p2 values less than (122880),
  1073  			      partition p3 values less than (204800),
  1074  			      partition p4 values less than maxvalue)`, "primary")
  1075  }
  1076  
  1077  func (s *testDBSuite1) TestAddIndex1(c *C) {
  1078  	testAddIndex(c, s.causetstore, s.lease, testPlain,
  1079  		"create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c1))", "")
  1080  }
  1081  
  1082  func (s *testDBSuite2) TestAddIndex2(c *C) {
  1083  	testAddIndex(c, s.causetstore, s.lease, testPartition,
  1084  		`create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c1))
  1085  			      partition by range (c1) (
  1086  			      partition p0 values less than (3440),
  1087  			      partition p1 values less than (61440),
  1088  			      partition p2 values less than (122880),
  1089  			      partition p3 values less than (204800),
  1090  			      partition p4 values less than maxvalue)`, "")
  1091  }
  1092  
  1093  func (s *testDBSuite3) TestAddIndex3(c *C) {
  1094  	testAddIndex(c, s.causetstore, s.lease, testPartition,
  1095  		`create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c1))
  1096  			      partition by hash (c1) partitions 4;`, "")
  1097  }
  1098  
  1099  func (s *testDBSuite4) TestAddIndex4(c *C) {
  1100  	testAddIndex(c, s.causetstore, s.lease, testPartition,
  1101  		`create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c1))
  1102  			      partition by range defCausumns (c1) (
  1103  			      partition p0 values less than (3440),
  1104  			      partition p1 values less than (61440),
  1105  			      partition p2 values less than (122880),
  1106  			      partition p3 values less than (204800),
  1107  			      partition p4 values less than maxvalue)`, "")
  1108  }
  1109  
  1110  func (s *testDBSuite5) TestAddIndex5(c *C) {
  1111  	testAddIndex(c, s.causetstore, s.lease, testClusteredIndex,
  1112  		`create causet test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c2, c3))`, "")
  1113  }
  1114  
  1115  type testAddIndexType int8
  1116  
  1117  const (
  1118  	testPlain testAddIndexType = iota
  1119  	testPartition
  1120  	testClusteredIndex
  1121  )
  1122  
  1123  func testAddIndex(c *C, causetstore ekv.CausetStorage, lease time.Duration, tp testAddIndexType, createBlockALLEGROSQL, idxTp string) {
  1124  	tk := testkit.NewTestKit(c, causetstore)
  1125  	tk.MustInterDirc("use test_db")
  1126  	switch tp {
  1127  	case testPartition:
  1128  		tk.MustInterDirc("set @@stochastik.milevadb_enable_block_partition = '1';")
  1129  	case testClusteredIndex:
  1130  		tk.MustInterDirc("set @@milevadb_enable_clustered_index = 1")
  1131  	}
  1132  	tk.MustInterDirc("drop causet if exists test_add_index")
  1133  	tk.MustInterDirc(createBlockALLEGROSQL)
  1134  
  1135  	done := make(chan error, 1)
  1136  	start := -10
  1137  	num := defaultBatchSize
  1138  	// first add some rows
  1139  	batchInsert(tk, "test_add_index", start, num)
  1140  
  1141  	// Add some discrete rows.
  1142  	maxBatch := 20
  1143  	batchCnt := 100
  1144  	otherKeys := make([]int, 0, batchCnt*maxBatch)
  1145  	// Make sure there are no duplicate keys.
  1146  	base := defaultBatchSize * 20
  1147  	for i := 1; i < batchCnt; i++ {
  1148  		n := base + i*defaultBatchSize + i
  1149  		for j := 0; j < rand.Intn(maxBatch); j++ {
  1150  			n += j
  1151  			allegrosql := fmt.Sprintf("insert into test_add_index values (%d, %d, %d)", n, n, n)
  1152  			tk.MustInterDirc(allegrosql)
  1153  			otherKeys = append(otherKeys, n)
  1154  		}
  1155  	}
  1156  	// Encounter the value of math.MaxInt64 in midbse of
  1157  	v := math.MaxInt64 - defaultBatchSize/2
  1158  	tk.MustInterDirc(fmt.Sprintf("insert into test_add_index values (%d, %d, %d)", v, v, v))
  1159  	otherKeys = append(otherKeys, v)
  1160  
  1161  	addIdxALLEGROSQL := fmt.Sprintf("alter causet test_add_index add %s key c3_index(c3)", idxTp)
  1162  	testdbsutil.StochastikInterDircInGoroutine(c, causetstore, addIdxALLEGROSQL, done)
  1163  
  1164  	deletedKeys := make(map[int]struct{})
  1165  
  1166  	ticker := time.NewTicker(lease / 2)
  1167  	defer ticker.Stop()
  1168  LOOP:
  1169  	for {
  1170  		select {
  1171  		case err := <-done:
  1172  			if err == nil {
  1173  				break LOOP
  1174  			}
  1175  			c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err)))
  1176  		case <-ticker.C:
  1177  			// When the server performance is particularly poor,
  1178  			// the adding index operation can not be completed.
  1179  			// So here is a limit to the number of rows inserted.
  1180  			if num > defaultBatchSize*10 {
  1181  				break
  1182  			}
  1183  			step := 5
  1184  			// delete some rows, and add some data
  1185  			for i := num; i < num+step; i++ {
  1186  				n := rand.Intn(num)
  1187  				deletedKeys[n] = struct{}{}
  1188  				allegrosql := fmt.Sprintf("delete from test_add_index where c1 = %d", n)
  1189  				tk.MustInterDirc(allegrosql)
  1190  				allegrosql = fmt.Sprintf("insert into test_add_index values (%d, %d, %d)", i, i, i)
  1191  				tk.MustInterDirc(allegrosql)
  1192  			}
  1193  			num += step
  1194  		}
  1195  	}
  1196  
  1197  	// get exists keys
  1198  	keys := make([]int, 0, num)
  1199  	for i := start; i < num; i++ {
  1200  		if _, ok := deletedKeys[i]; ok {
  1201  			continue
  1202  		}
  1203  		keys = append(keys, i)
  1204  	}
  1205  	keys = append(keys, otherKeys...)
  1206  
  1207  	// test index key
  1208  	expectedRows := make([][]interface{}, 0, len(keys))
  1209  	for _, key := range keys {
  1210  		expectedRows = append(expectedRows, []interface{}{key})
  1211  	}
  1212  	rows := tk.MustQuery(fmt.Sprintf("select c1 from test_add_index where c3 >= %d order by c1", start)).Rows()
  1213  	matchRows(c, rows, expectedRows)
  1214  
  1215  	tk.MustInterDirc("admin check causet test_add_index")
  1216  	if tp == testPartition {
  1217  		return
  1218  	}
  1219  
  1220  	// TODO: Support explain in future.
  1221  	// rows := s.mustQuery(c, "explain select c1 from test_add_index where c3 >= 100")
  1222  
  1223  	// ay := dumpRows(c, rows)
  1224  	// c.Assert(strings.Contains(fmt.Sprintf("%v", ay), "c3_index"), IsTrue)
  1225  
  1226  	// get all event handles
  1227  	ctx := tk.Se.(stochastikctx.Context)
  1228  	c.Assert(ctx.NewTxn(context.Background()), IsNil)
  1229  	t := testGetBlockByName(c, ctx, "test_db", "test_add_index")
  1230  	handles := ekv.NewHandleMap()
  1231  	startKey := t.RecordKey(ekv.IntHandle(math.MinInt64))
  1232  	err := t.IterRecords(ctx, startKey, t.DefCauss(),
  1233  		func(h ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
  1234  			handles.Set(h, struct{}{})
  1235  			return true, nil
  1236  		})
  1237  	c.Assert(err, IsNil)
  1238  
  1239  	// check in index
  1240  	var nidx causet.Index
  1241  	idxName := "c3_index"
  1242  	if len(idxTp) != 0 {
  1243  		idxName = "primary"
  1244  	}
  1245  	for _, tidx := range t.Indices() {
  1246  		if tidx.Meta().Name.L == idxName {
  1247  			nidx = tidx
  1248  			break
  1249  		}
  1250  	}
  1251  	// Make sure there is index with name c3_index.
  1252  	c.Assert(nidx, NotNil)
  1253  	c.Assert(nidx.Meta().ID, Greater, int64(0))
  1254  	txn, err := ctx.Txn(true)
  1255  	c.Assert(err, IsNil)
  1256  	txn.Rollback()
  1257  
  1258  	c.Assert(ctx.NewTxn(context.Background()), IsNil)
  1259  
  1260  	it, err := nidx.SeekFirst(txn)
  1261  	c.Assert(err, IsNil)
  1262  	defer it.Close()
  1263  
  1264  	for {
  1265  		_, h, err := it.Next()
  1266  		if terror.ErrorEqual(err, io.EOF) {
  1267  			break
  1268  		}
  1269  
  1270  		c.Assert(err, IsNil)
  1271  		_, ok := handles.Get(h)
  1272  		c.Assert(ok, IsTrue)
  1273  		handles.Delete(h)
  1274  	}
  1275  	c.Assert(handles.Len(), Equals, 0)
  1276  	tk.MustInterDirc("drop causet test_add_index")
  1277  }
  1278  
  1279  // TestCancelAddBlockAndDropBlockPartition tests cancel dbs job which type is add/drop causet partition.
  1280  func (s *testDBSuite1) TestCancelAddBlockAndDropBlockPartition(c *C) {
  1281  	tk := testkit.NewTestKit(c, s.causetstore)
  1282  	s.mustInterDirc(tk, c, "create database if not exists test_partition_block")
  1283  	s.mustInterDirc(tk, c, "use test_partition_block")
  1284  	s.mustInterDirc(tk, c, "drop causet if exists t_part")
  1285  	s.mustInterDirc(tk, c, `create causet t_part (a int key)
  1286  		partition by range(a) (
  1287  		partition p0 values less than (10),
  1288  		partition p1 values less than (20)
  1289  	);`)
  1290  	defer s.mustInterDirc(tk, c, "drop causet t_part;")
  1291  	base := 10
  1292  	for i := 0; i < base; i++ {
  1293  		s.mustInterDirc(tk, c, "insert into t_part values (?)", i)
  1294  	}
  1295  
  1296  	testCases := []struct {
  1297  		action         perceptron.CausetActionType
  1298  		jobState       perceptron.JobState
  1299  		JobSchemaState perceptron.SchemaState
  1300  		cancelSucc     bool
  1301  	}{
  1302  		{perceptron.CausetActionAddBlockPartition, perceptron.JobStateNone, perceptron.StateNone, true},
  1303  		{perceptron.CausetActionDropBlockPartition, perceptron.JobStateNone, perceptron.StateNone, true},
  1304  		// Add causet partition now can be cancelled in ReplicaOnly state.
  1305  		{perceptron.CausetActionAddBlockPartition, perceptron.JobStateRunning, perceptron.StateReplicaOnly, true},
  1306  	}
  1307  	var checkErr error
  1308  	hook := &dbs.TestDBSCallback{}
  1309  	testCase := &testCases[0]
  1310  	var jobID int64
  1311  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  1312  		if job.Type == testCase.action && job.State == testCase.jobState && job.SchemaState == testCase.JobSchemaState {
  1313  			jobIDs := []int64{job.ID}
  1314  			jobID = job.ID
  1315  			hookCtx := mock.NewContext()
  1316  			hookCtx.CausetStore = s.causetstore
  1317  			err := hookCtx.NewTxn(context.Background())
  1318  			if err != nil {
  1319  				checkErr = errors.Trace(err)
  1320  				return
  1321  			}
  1322  			txn, err := hookCtx.Txn(true)
  1323  			if err != nil {
  1324  				checkErr = errors.Trace(err)
  1325  				return
  1326  			}
  1327  			errs, err := admin.CancelJobs(txn, jobIDs)
  1328  			if err != nil {
  1329  				checkErr = errors.Trace(err)
  1330  				return
  1331  			}
  1332  			if errs[0] != nil {
  1333  				checkErr = errors.Trace(errs[0])
  1334  				return
  1335  			}
  1336  			checkErr = txn.Commit(context.Background())
  1337  		}
  1338  	}
  1339  	originalHook := s.dom.DBS().GetHook()
  1340  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  1341  
  1342  	var err error
  1343  	allegrosql := ""
  1344  	for i := range testCases {
  1345  		testCase = &testCases[i]
  1346  		if testCase.action == perceptron.CausetActionAddBlockPartition {
  1347  			allegrosql = `alter causet t_part add partition (
  1348  				partition p2 values less than (30)
  1349  				);`
  1350  		} else if testCase.action == perceptron.CausetActionDropBlockPartition {
  1351  			allegrosql = "alter causet t_part drop partition p1;"
  1352  		}
  1353  		_, err = tk.InterDirc(allegrosql)
  1354  		if testCase.cancelSucc {
  1355  			c.Assert(checkErr, IsNil)
  1356  			c.Assert(err, NotNil)
  1357  			c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job")
  1358  			s.mustInterDirc(tk, c, "insert into t_part values (?)", i+base)
  1359  
  1360  			ctx := s.s.(stochastikctx.Context)
  1361  			is := petri.GetPetri(ctx).SchemaReplicant()
  1362  			tbl, err := is.BlockByName(perceptron.NewCIStr("test_partition_block"), perceptron.NewCIStr("t_part"))
  1363  			c.Assert(err, IsNil)
  1364  			partitionInfo := tbl.Meta().GetPartitionInfo()
  1365  			c.Assert(partitionInfo, NotNil)
  1366  			c.Assert(len(partitionInfo.AddingDefinitions), Equals, 0)
  1367  		} else {
  1368  			c.Assert(err, IsNil, Commentf("err:%v", err))
  1369  			c.Assert(checkErr, NotNil)
  1370  			c.Assert(checkErr.Error(), Equals, admin.ErrCannotCancelDBSJob.GenWithStackByArgs(jobID).Error())
  1371  			_, err = tk.InterDirc("insert into t_part values (?)", i)
  1372  			c.Assert(err, NotNil)
  1373  		}
  1374  	}
  1375  	s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
  1376  }
  1377  
  1378  func (s *testDBSuite1) TestDropPrimaryKey(c *C) {
  1379  	idxName := "primary"
  1380  	createALLEGROSQL := "create causet test_drop_index (c1 int, c2 int, c3 int, unique key(c1), primary key(c3))"
  1381  	dropIdxALLEGROSQL := "alter causet test_drop_index drop primary key;"
  1382  	testDropIndex(c, s.causetstore, s.lease, createALLEGROSQL, dropIdxALLEGROSQL, idxName)
  1383  }
  1384  
  1385  func (s *testDBSuite2) TestDropIndex(c *C) {
  1386  	idxName := "c3_index"
  1387  	createALLEGROSQL := "create causet test_drop_index (c1 int, c2 int, c3 int, unique key(c1), key c3_index(c3))"
  1388  	dropIdxALLEGROSQL := "alter causet test_drop_index drop index c3_index;"
  1389  	testDropIndex(c, s.causetstore, s.lease, createALLEGROSQL, dropIdxALLEGROSQL, idxName)
  1390  }
  1391  
  1392  func testDropIndex(c *C, causetstore ekv.CausetStorage, lease time.Duration, createALLEGROSQL, dropIdxALLEGROSQL, idxName string) {
  1393  	tk := testkit.NewTestKit(c, causetstore)
  1394  	tk.MustInterDirc("use test_db")
  1395  	tk.MustInterDirc("drop causet if exists test_drop_index")
  1396  	tk.MustInterDirc(createALLEGROSQL)
  1397  	done := make(chan error, 1)
  1398  	tk.MustInterDirc("delete from test_drop_index")
  1399  
  1400  	num := 100
  1401  	//  add some rows
  1402  	for i := 0; i < num; i++ {
  1403  		tk.MustInterDirc("insert into test_drop_index values (?, ?, ?)", i, i, i)
  1404  	}
  1405  	ctx := tk.Se.(stochastikctx.Context)
  1406  	t := testGetBlockByName(c, ctx, "test_db", "test_drop_index")
  1407  	var c3idx causet.Index
  1408  	for _, tidx := range t.Indices() {
  1409  		if tidx.Meta().Name.L == idxName {
  1410  			c3idx = tidx
  1411  			break
  1412  		}
  1413  	}
  1414  	c.Assert(c3idx, NotNil)
  1415  
  1416  	testdbsutil.StochastikInterDircInGoroutine(c, causetstore, dropIdxALLEGROSQL, done)
  1417  
  1418  	ticker := time.NewTicker(lease / 2)
  1419  	defer ticker.Stop()
  1420  LOOP:
  1421  	for {
  1422  		select {
  1423  		case err := <-done:
  1424  			if err == nil {
  1425  				break LOOP
  1426  			}
  1427  			c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err)))
  1428  		case <-ticker.C:
  1429  			step := 5
  1430  			// delete some rows, and add some data
  1431  			for i := num; i < num+step; i++ {
  1432  				n := rand.Intn(num)
  1433  				tk.MustInterDirc("uFIDelate test_drop_index set c2 = 1 where c1 = ?", n)
  1434  				tk.MustInterDirc("insert into test_drop_index values (?, ?, ?)", i, i, i)
  1435  			}
  1436  			num += step
  1437  		}
  1438  	}
  1439  
  1440  	rows := tk.MustQuery("explain select c1 from test_drop_index where c3 >= 0")
  1441  	c.Assert(strings.Contains(fmt.Sprintf("%v", rows), idxName), IsFalse)
  1442  
  1443  	// Check in index, it must be no index in KV.
  1444  	// Make sure there is no index with name c3_index.
  1445  	t = testGetBlockByName(c, ctx, "test_db", "test_drop_index")
  1446  	var nidx causet.Index
  1447  	for _, tidx := range t.Indices() {
  1448  		if tidx.Meta().Name.L == idxName {
  1449  			nidx = tidx
  1450  			break
  1451  		}
  1452  	}
  1453  	c.Assert(nidx, IsNil)
  1454  
  1455  	idx := blocks.NewIndex(t.Meta().ID, t.Meta(), c3idx.Meta())
  1456  	checkDelRangeDone(c, ctx, idx)
  1457  	tk.MustInterDirc("drop causet test_drop_index")
  1458  }
  1459  
  1460  // TestCancelDropDeferredCauset tests cancel dbs job which type is drop defCausumn.
  1461  func (s *testDBSuite3) TestCancelDropDeferredCauset(c *C) {
  1462  	tk := testkit.NewTestKit(c, s.causetstore)
  1463  	tk.MustInterDirc("use " + s.schemaName)
  1464  	s.mustInterDirc(tk, c, "drop causet if exists test_drop_defCausumn")
  1465  	s.mustInterDirc(tk, c, "create causet test_drop_defCausumn(c1 int, c2 int)")
  1466  	defer s.mustInterDirc(tk, c, "drop causet test_drop_defCausumn;")
  1467  	testCases := []struct {
  1468  		needAddDeferredCauset bool
  1469  		jobState              perceptron.JobState
  1470  		JobSchemaState        perceptron.SchemaState
  1471  		cancelSucc            bool
  1472  	}{
  1473  		{true, perceptron.JobStateNone, perceptron.StateNone, true},
  1474  		{false, perceptron.JobStateRunning, perceptron.StateWriteOnly, false},
  1475  		{true, perceptron.JobStateRunning, perceptron.StateDeleteOnly, false},
  1476  		{true, perceptron.JobStateRunning, perceptron.StateDeleteReorganization, false},
  1477  	}
  1478  	var checkErr error
  1479  	hook := &dbs.TestDBSCallback{}
  1480  	var jobID int64
  1481  	testCase := &testCases[0]
  1482  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  1483  		if job.Type == perceptron.CausetActionDropDeferredCauset && job.State == testCase.jobState && job.SchemaState == testCase.JobSchemaState {
  1484  			jobIDs := []int64{job.ID}
  1485  			jobID = job.ID
  1486  			hookCtx := mock.NewContext()
  1487  			hookCtx.CausetStore = s.causetstore
  1488  			err := hookCtx.NewTxn(context.TODO())
  1489  			if err != nil {
  1490  				checkErr = errors.Trace(err)
  1491  				return
  1492  			}
  1493  			txn, err := hookCtx.Txn(true)
  1494  			if err != nil {
  1495  				checkErr = errors.Trace(err)
  1496  				return
  1497  			}
  1498  			errs, err := admin.CancelJobs(txn, jobIDs)
  1499  			if err != nil {
  1500  				checkErr = errors.Trace(err)
  1501  				return
  1502  			}
  1503  			if errs[0] != nil {
  1504  				checkErr = errors.Trace(errs[0])
  1505  				return
  1506  			}
  1507  			checkErr = txn.Commit(context.Background())
  1508  		}
  1509  	}
  1510  
  1511  	originalHook := s.dom.DBS().GetHook()
  1512  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  1513  	var err1 error
  1514  	var c3idx causet.Index
  1515  	for i := range testCases {
  1516  		testCase = &testCases[i]
  1517  		if testCase.needAddDeferredCauset {
  1518  			s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add defCausumn c3 int")
  1519  			s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add index idx_c3(c3)")
  1520  			tt := s.testGetBlock(c, "test_drop_defCausumn")
  1521  			for _, idx := range tt.Indices() {
  1522  				if strings.EqualFold(idx.Meta().Name.L, "idx_c3") {
  1523  					c3idx = idx
  1524  					break
  1525  				}
  1526  			}
  1527  		}
  1528  		_, err1 = tk.InterDirc("alter causet test_drop_defCausumn drop defCausumn c3")
  1529  		var defCaus1 *causet.DeferredCauset
  1530  		var idx1 causet.Index
  1531  		t := s.testGetBlock(c, "test_drop_defCausumn")
  1532  		for _, defCaus := range t.DefCauss() {
  1533  			if strings.EqualFold(defCaus.Name.L, "c3") {
  1534  				defCaus1 = defCaus
  1535  				break
  1536  			}
  1537  		}
  1538  		for _, idx := range t.Indices() {
  1539  			if strings.EqualFold(idx.Meta().Name.L, "idx_c3") {
  1540  				idx1 = idx
  1541  				break
  1542  			}
  1543  		}
  1544  		if testCase.cancelSucc {
  1545  			c.Assert(checkErr, IsNil)
  1546  			c.Assert(defCaus1, NotNil)
  1547  			c.Assert(defCaus1.Name.L, Equals, "c3")
  1548  			c.Assert(idx1, NotNil)
  1549  			c.Assert(idx1.Meta().Name.L, Equals, "idx_c3")
  1550  			c.Assert(err1.Error(), Equals, "[dbs:8214]Cancelled DBS job")
  1551  		} else {
  1552  			c.Assert(defCaus1, IsNil)
  1553  			c.Assert(idx1, IsNil)
  1554  			c.Assert(err1, IsNil)
  1555  			c.Assert(checkErr, NotNil)
  1556  			c.Assert(checkErr.Error(), Equals, admin.ErrCannotCancelDBSJob.GenWithStackByArgs(jobID).Error())
  1557  			// Check index is deleted
  1558  			ctx := s.s.(stochastikctx.Context)
  1559  			checkDelRangeDone(c, ctx, c3idx)
  1560  		}
  1561  	}
  1562  	s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
  1563  	s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add defCausumn c3 int")
  1564  	s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn drop defCausumn c3")
  1565  }
  1566  
  1567  // TestCancelDropDeferredCausets tests cancel dbs job which type is drop multi-defCausumns.
  1568  func (s *testDBSuite3) TestCancelDropDeferredCausets(c *C) {
  1569  	tk := testkit.NewTestKit(c, s.causetstore)
  1570  	tk.MustInterDirc("use " + s.schemaName)
  1571  	s.mustInterDirc(tk, c, "drop causet if exists test_drop_defCausumn")
  1572  	s.mustInterDirc(tk, c, "create causet test_drop_defCausumn(c1 int, c2 int)")
  1573  	defer s.mustInterDirc(tk, c, "drop causet test_drop_defCausumn;")
  1574  	testCases := []struct {
  1575  		needAddDeferredCauset bool
  1576  		jobState              perceptron.JobState
  1577  		JobSchemaState        perceptron.SchemaState
  1578  		cancelSucc            bool
  1579  	}{
  1580  		{true, perceptron.JobStateNone, perceptron.StateNone, true},
  1581  		{false, perceptron.JobStateRunning, perceptron.StateWriteOnly, false},
  1582  		{true, perceptron.JobStateRunning, perceptron.StateDeleteOnly, false},
  1583  		{true, perceptron.JobStateRunning, perceptron.StateDeleteReorganization, false},
  1584  	}
  1585  	var checkErr error
  1586  	hook := &dbs.TestDBSCallback{}
  1587  	var jobID int64
  1588  	testCase := &testCases[0]
  1589  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  1590  		if job.Type == perceptron.CausetActionDropDeferredCausets && job.State == testCase.jobState && job.SchemaState == testCase.JobSchemaState {
  1591  			jobIDs := []int64{job.ID}
  1592  			jobID = job.ID
  1593  			hookCtx := mock.NewContext()
  1594  			hookCtx.CausetStore = s.causetstore
  1595  			err := hookCtx.NewTxn(context.TODO())
  1596  			if err != nil {
  1597  				checkErr = errors.Trace(err)
  1598  				return
  1599  			}
  1600  			txn, err := hookCtx.Txn(true)
  1601  			if err != nil {
  1602  				checkErr = errors.Trace(err)
  1603  				return
  1604  			}
  1605  			errs, err := admin.CancelJobs(txn, jobIDs)
  1606  			if err != nil {
  1607  				checkErr = errors.Trace(err)
  1608  				return
  1609  			}
  1610  			if errs[0] != nil {
  1611  				checkErr = errors.Trace(errs[0])
  1612  				return
  1613  			}
  1614  			checkErr = txn.Commit(context.Background())
  1615  		}
  1616  	}
  1617  
  1618  	originalHook := s.dom.DBS().GetHook()
  1619  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  1620  	var err1 error
  1621  	var c3idx causet.Index
  1622  	for i := range testCases {
  1623  		testCase = &testCases[i]
  1624  		if testCase.needAddDeferredCauset {
  1625  			s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add defCausumn c3 int, add defCausumn c4 int")
  1626  			s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add index idx_c3(c3)")
  1627  			tt := s.testGetBlock(c, "test_drop_defCausumn")
  1628  			for _, idx := range tt.Indices() {
  1629  				if strings.EqualFold(idx.Meta().Name.L, "idx_c3") {
  1630  					c3idx = idx
  1631  					break
  1632  				}
  1633  			}
  1634  		}
  1635  		_, err1 = tk.InterDirc("alter causet test_drop_defCausumn drop defCausumn c3, drop defCausumn c4")
  1636  		t := s.testGetBlock(c, "test_drop_defCausumn")
  1637  		defCaus3 := causet.FindDefCaus(t.DefCauss(), "c3")
  1638  		defCaus4 := causet.FindDefCaus(t.DefCauss(), "c4")
  1639  		var idx3 causet.Index
  1640  		for _, idx := range t.Indices() {
  1641  			if strings.EqualFold(idx.Meta().Name.L, "idx_c3") {
  1642  				idx3 = idx
  1643  				break
  1644  			}
  1645  		}
  1646  		if testCase.cancelSucc {
  1647  			c.Assert(checkErr, IsNil)
  1648  			c.Assert(defCaus3, NotNil)
  1649  			c.Assert(defCaus4, NotNil)
  1650  			c.Assert(idx3, NotNil)
  1651  			c.Assert(defCaus3.Name.L, Equals, "c3")
  1652  			c.Assert(defCaus4.Name.L, Equals, "c4")
  1653  			c.Assert(idx3.Meta().Name.L, Equals, "idx_c3")
  1654  			c.Assert(err1.Error(), Equals, "[dbs:8214]Cancelled DBS job")
  1655  		} else {
  1656  			c.Assert(defCaus3, IsNil)
  1657  			c.Assert(defCaus4, IsNil)
  1658  			c.Assert(idx3, IsNil)
  1659  			c.Assert(err1, IsNil)
  1660  			c.Assert(checkErr, NotNil)
  1661  			c.Assert(checkErr.Error(), Equals, admin.ErrCannotCancelDBSJob.GenWithStackByArgs(jobID).Error())
  1662  			// Check index is deleted
  1663  			ctx := s.s.(stochastikctx.Context)
  1664  			checkDelRangeDone(c, ctx, c3idx)
  1665  		}
  1666  	}
  1667  	s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
  1668  	s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn add defCausumn c3 int, add defCausumn c4 int")
  1669  	s.mustInterDirc(tk, c, "alter causet test_drop_defCausumn drop defCausumn c3, drop defCausumn c4")
  1670  }
  1671  
  1672  func checkDelRangeDone(c *C, ctx stochastikctx.Context, idx causet.Index) {
  1673  	startTime := time.Now()
  1674  	f := func() map[int64]struct{} {
  1675  		handles := make(map[int64]struct{})
  1676  
  1677  		c.Assert(ctx.NewTxn(context.Background()), IsNil)
  1678  		txn, err := ctx.Txn(true)
  1679  		c.Assert(err, IsNil)
  1680  		defer txn.Rollback()
  1681  
  1682  		txn, err = ctx.Txn(true)
  1683  		c.Assert(err, IsNil)
  1684  		it, err := idx.SeekFirst(txn)
  1685  		c.Assert(err, IsNil)
  1686  		defer it.Close()
  1687  
  1688  		for {
  1689  			_, h, err := it.Next()
  1690  			if terror.ErrorEqual(err, io.EOF) {
  1691  				break
  1692  			}
  1693  
  1694  			c.Assert(err, IsNil)
  1695  			handles[h.IntValue()] = struct{}{}
  1696  		}
  1697  		return handles
  1698  	}
  1699  
  1700  	var handles map[int64]struct{}
  1701  	for i := 0; i < waitForCleanDataRound; i++ {
  1702  		handles = f()
  1703  		if len(handles) != 0 {
  1704  			time.Sleep(waitForCleanDataInterval)
  1705  		} else {
  1706  			break
  1707  		}
  1708  	}
  1709  	c.Assert(handles, HasLen, 0, Commentf("take time %v", time.Since(startTime)))
  1710  }
  1711  
  1712  func (s *testDBSuite5) TestAlterPrimaryKey(c *C) {
  1713  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
  1714  	tk.MustInterDirc("create causet test_add_pk(a int, b int unsigned , c varchar(255) default 'abc', d int as (a+b), e int as (a+1) stored, index idx(b))")
  1715  	defer tk.MustInterDirc("drop causet test_add_pk")
  1716  
  1717  	// for generated defCausumns
  1718  	tk.MustGetErrCode("alter causet test_add_pk add primary key(d);", errno.ErrUnsupportedOnGeneratedDeferredCauset)
  1719  	// The primary key name is the same as the existing index name.
  1720  	tk.MustInterDirc("alter causet test_add_pk add primary key idx(e)")
  1721  	tk.MustInterDirc("drop index `primary` on test_add_pk")
  1722  
  1723  	// for describing causet
  1724  	tk.MustInterDirc("create causet test_add_pk1(a int, index idx(a))")
  1725  	tk.MustQuery("desc test_add_pk1").Check(solitonutil.RowsWithSep(",", `a,int(11),YES,MUL,<nil>,`))
  1726  	tk.MustInterDirc("alter causet test_add_pk1 add primary key idx(a)")
  1727  	tk.MustQuery("desc test_add_pk1").Check(solitonutil.RowsWithSep(",", `a,int(11),NO,PRI,<nil>,`))
  1728  	tk.MustInterDirc("alter causet test_add_pk1 drop primary key")
  1729  	tk.MustQuery("desc test_add_pk1").Check(solitonutil.RowsWithSep(",", `a,int(11),NO,MUL,<nil>,`))
  1730  	tk.MustInterDirc("create causet test_add_pk2(a int, b int, index idx(a))")
  1731  	tk.MustInterDirc("alter causet test_add_pk2 add primary key idx(a, b)")
  1732  	tk.MustQuery("desc test_add_pk2").Check(solitonutil.RowsWithSep(",", ""+
  1733  		"a int(11) NO PRI <nil> ]\n"+
  1734  		"[b int(11) NO PRI <nil> "))
  1735  	tk.MustQuery("show create causet test_add_pk2").Check(solitonutil.RowsWithSep("|", ""+
  1736  		"test_add_pk2 CREATE TABLE `test_add_pk2` (\n"+
  1737  		"  `a` int(11) NOT NULL,\n"+
  1738  		"  `b` int(11) NOT NULL,\n"+
  1739  		"  KEY `idx` (`a`),\n"+
  1740  		"  PRIMARY KEY (`a`,`b`)\n"+
  1741  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  1742  	tk.MustInterDirc("alter causet test_add_pk2 drop primary key")
  1743  	tk.MustQuery("desc test_add_pk2").Check(solitonutil.RowsWithSep(",", ""+
  1744  		"a int(11) NO MUL <nil> ]\n"+
  1745  		"[b int(11) NO  <nil> "))
  1746  
  1747  	// Check if the primary key exists before checking the causet's pkIsHandle.
  1748  	tk.MustGetErrCode("alter causet test_add_pk drop primary key", errno.ErrCantDropFieldOrKey)
  1749  
  1750  	// for the limit of name
  1751  	validName := strings.Repeat("a", allegrosql.MaxIndexIdentifierLen)
  1752  	invalidName := strings.Repeat("b", allegrosql.MaxIndexIdentifierLen+1)
  1753  	tk.MustGetErrCode("alter causet test_add_pk add primary key "+invalidName+"(a)", errno.ErrTooLongIdent)
  1754  	// for valid name
  1755  	tk.MustInterDirc("alter causet test_add_pk add primary key " + validName + "(a)")
  1756  	// for multiple primary key
  1757  	tk.MustGetErrCode("alter causet test_add_pk add primary key (a)", errno.ErrMultiplePriKey)
  1758  	tk.MustInterDirc("alter causet test_add_pk drop primary key")
  1759  	// for not existing primary key
  1760  	tk.MustGetErrCode("alter causet test_add_pk drop primary key", errno.ErrCantDropFieldOrKey)
  1761  	tk.MustGetErrCode("drop index `primary` on test_add_pk", errno.ErrCantDropFieldOrKey)
  1762  
  1763  	// for too many key parts specified
  1764  	tk.MustGetErrCode("alter causet test_add_pk add primary key idx_test(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17);",
  1765  		errno.ErrTooManyKeyParts)
  1766  
  1767  	// for the limit of comment's length
  1768  	validComment := "'" + strings.Repeat("a", dbs.MaxCommentLength) + "'"
  1769  	invalidComment := "'" + strings.Repeat("b", dbs.MaxCommentLength+1) + "'"
  1770  	tk.MustGetErrCode("alter causet test_add_pk add primary key(a) comment "+invalidComment, errno.ErrTooLongIndexComment)
  1771  	// for empty sql_mode
  1772  	r := tk.MustQuery("select @@sql_mode")
  1773  	sqlMode := r.Rows()[0][0].(string)
  1774  	tk.MustInterDirc("set @@sql_mode=''")
  1775  	tk.MustInterDirc("alter causet test_add_pk add primary key(a) comment " + invalidComment)
  1776  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  1777  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|1688|Comment for index 'PRIMARY' is too long (max = 1024)"))
  1778  	tk.MustInterDirc("set @@sql_mode= '" + sqlMode + "'")
  1779  	tk.MustInterDirc("alter causet test_add_pk drop primary key")
  1780  	// for valid comment
  1781  	tk.MustInterDirc("alter causet test_add_pk add primary key(a, b, c) comment " + validComment)
  1782  	ctx := tk.Se.(stochastikctx.Context)
  1783  	c.Assert(ctx.NewTxn(context.Background()), IsNil)
  1784  	t := testGetBlockByName(c, ctx, "test", "test_add_pk")
  1785  	defCaus1Flag := t.DefCauss()[0].Flag
  1786  	defCaus2Flag := t.DefCauss()[1].Flag
  1787  	defCaus3Flag := t.DefCauss()[2].Flag
  1788  	c.Assert(allegrosql.HasNotNullFlag(defCaus1Flag) && !allegrosql.HasPreventNullInsertFlag(defCaus1Flag), IsTrue)
  1789  	c.Assert(allegrosql.HasNotNullFlag(defCaus2Flag) && !allegrosql.HasPreventNullInsertFlag(defCaus2Flag) && allegrosql.HasUnsignedFlag(defCaus2Flag), IsTrue)
  1790  	c.Assert(allegrosql.HasNotNullFlag(defCaus3Flag) && !allegrosql.HasPreventNullInsertFlag(defCaus3Flag) && !allegrosql.HasNoDefaultValueFlag(defCaus3Flag), IsTrue)
  1791  	tk.MustInterDirc("alter causet test_add_pk drop primary key")
  1792  
  1793  	// for null values in primary key
  1794  	tk.MustInterDirc("drop causet test_add_pk")
  1795  	tk.MustInterDirc("create causet test_add_pk(a int, b int unsigned , c varchar(255) default 'abc', index idx(b))")
  1796  	tk.MustInterDirc("insert into test_add_pk set a = 0, b = 0, c = 0")
  1797  	tk.MustInterDirc("insert into test_add_pk set a = 1")
  1798  	tk.MustGetErrCode("alter causet test_add_pk add primary key (b)", errno.ErrInvalidUseOfNull)
  1799  	tk.MustInterDirc("insert into test_add_pk set a = 2, b = 2")
  1800  	tk.MustGetErrCode("alter causet test_add_pk add primary key (a, b)", errno.ErrInvalidUseOfNull)
  1801  	tk.MustInterDirc("insert into test_add_pk set a = 3, c = 3")
  1802  	tk.MustGetErrCode("alter causet test_add_pk add primary key (c, b, a)", errno.ErrInvalidUseOfNull)
  1803  }
  1804  
  1805  func (s *testDBSuite4) TestAddIndexWithDupDefCauss(c *C) {
  1806  	tk := testkit.NewTestKit(c, s.causetstore)
  1807  	tk.MustInterDirc("use " + s.schemaName)
  1808  	err1 := schemareplicant.ErrDeferredCausetExists.GenWithStackByArgs("b")
  1809  	err2 := schemareplicant.ErrDeferredCausetExists.GenWithStackByArgs("B")
  1810  
  1811  	tk.MustInterDirc("create causet test_add_index_with_dup (a int, b int)")
  1812  	_, err := tk.InterDirc("create index c on test_add_index_with_dup(b, a, b)")
  1813  	c.Check(errors.Cause(err1).(*terror.Error).Equal(err), Equals, true)
  1814  
  1815  	_, err = tk.InterDirc("create index c on test_add_index_with_dup(b, a, B)")
  1816  	c.Check(errors.Cause(err2).(*terror.Error).Equal(err), Equals, true)
  1817  
  1818  	_, err = tk.InterDirc("alter causet test_add_index_with_dup add index c (b, a, b)")
  1819  	c.Check(errors.Cause(err1).(*terror.Error).Equal(err), Equals, true)
  1820  
  1821  	_, err = tk.InterDirc("alter causet test_add_index_with_dup add index c (b, a, B)")
  1822  	c.Check(errors.Cause(err2).(*terror.Error).Equal(err), Equals, true)
  1823  
  1824  	tk.MustInterDirc("drop causet test_add_index_with_dup")
  1825  }
  1826  
  1827  // checkGlobalIndexRow reads one record from global index and check. Only support int handle.
  1828  func checkGlobalIndexRow(c *C, ctx stochastikctx.Context, tblInfo *perceptron.BlockInfo, indexInfo *perceptron.IndexInfo,
  1829  	pid int64, idxVals []types.Causet, rowVals []types.Causet) {
  1830  	ctx.NewTxn(context.Background())
  1831  	txn, err := ctx.Txn(true)
  1832  	sc := ctx.GetStochastikVars().StmtCtx
  1833  	c.Assert(err, IsNil)
  1834  
  1835  	tblDefCausMap := make(map[int64]*types.FieldType, len(tblInfo.DeferredCausets))
  1836  	for _, defCaus := range tblInfo.DeferredCausets {
  1837  		tblDefCausMap[defCaus.ID] = &defCaus.FieldType
  1838  	}
  1839  	idxDefCausInfos := make([]rowcodec.DefCausInfo, 0, len(indexInfo.DeferredCausets))
  1840  	for _, idxDefCaus := range indexInfo.DeferredCausets {
  1841  		defCaus := tblInfo.DeferredCausets[idxDefCaus.Offset]
  1842  		idxDefCausInfos = append(idxDefCausInfos, rowcodec.DefCausInfo{
  1843  			ID:         defCaus.ID,
  1844  			IsPKHandle: tblInfo.PKIsHandle && allegrosql.HasPriKeyFlag(defCaus.Flag),
  1845  			Ft:         rowcodec.FieldTypeFromPerceptronDeferredCauset(defCaus),
  1846  		})
  1847  	}
  1848  
  1849  	// Check local index entry does not exist.
  1850  	localPrefix := blockcodec.EncodeBlockIndexPrefix(pid, indexInfo.ID)
  1851  	it, err := txn.Iter(localPrefix, nil)
  1852  	c.Assert(err, IsNil)
  1853  	// no local index entry.
  1854  	c.Assert(it.Valid() && it.Key().HasPrefix(localPrefix), IsFalse)
  1855  	it.Close()
  1856  
  1857  	// Check global index entry.
  1858  	encodedValue, err := codec.EncodeKey(sc, nil, idxVals...)
  1859  	c.Assert(err, IsNil)
  1860  	key := blockcodec.EncodeIndexSeekKey(tblInfo.ID, indexInfo.ID, encodedValue)
  1861  	c.Assert(err, IsNil)
  1862  	value, err := txn.Get(context.Background(), key)
  1863  	c.Assert(err, IsNil)
  1864  	defCausVals, err := blockcodec.DecodeIndexKV(key, value, len(indexInfo.DeferredCausets),
  1865  		blockcodec.HandleDefault, idxDefCausInfos)
  1866  	c.Assert(err, IsNil)
  1867  	c.Assert(defCausVals, HasLen, len(idxVals)+2)
  1868  	for i, val := range idxVals {
  1869  		_, d, err := codec.DecodeOne(defCausVals[i])
  1870  		c.Assert(err, IsNil)
  1871  		c.Assert(d, DeepEquals, val)
  1872  	}
  1873  	_, d, err := codec.DecodeOne(defCausVals[len(idxVals)+1]) //pid
  1874  	c.Assert(err, IsNil)
  1875  	c.Assert(d.GetInt64(), Equals, pid)
  1876  
  1877  	_, d, err = codec.DecodeOne(defCausVals[len(idxVals)]) //handle
  1878  	c.Assert(err, IsNil)
  1879  	h := ekv.IntHandle(d.GetInt64())
  1880  	rowKey := blockcodec.EncodeRowKey(pid, h.Encoded())
  1881  	rowValue, err := txn.Get(context.Background(), rowKey)
  1882  	c.Assert(err, IsNil)
  1883  	rowValueCausets, err := blockcodec.DecodeRowToCausetMap(rowValue, tblDefCausMap, time.UTC)
  1884  	c.Assert(err, IsNil)
  1885  	c.Assert(rowValueCausets, NotNil)
  1886  	for i, val := range rowVals {
  1887  		c.Assert(rowValueCausets[tblInfo.DeferredCausets[i].ID], DeepEquals, val)
  1888  	}
  1889  }
  1890  
  1891  func (s *testSerialDBSuite) TestAddGlobalIndex(c *C) {
  1892  	defer config.RestoreFunc()()
  1893  	config.UFIDelateGlobal(func(conf *config.Config) {
  1894  		conf.AlterPrimaryKey = true
  1895  		conf.EnableGlobalIndex = true
  1896  	})
  1897  	tk := testkit.NewTestKit(c, s.causetstore)
  1898  	tk.MustInterDirc("use test_db")
  1899  	tk.MustInterDirc("create causet test_t1 (a int, b int) partition by range (b)" +
  1900  		" (partition p0 values less than (10), " +
  1901  		"  partition p1 values less than (maxvalue));")
  1902  	tk.MustInterDirc("insert test_t1 values (1, 1)")
  1903  	tk.MustInterDirc("alter causet test_t1 add unique index p_a (a);")
  1904  	tk.MustInterDirc("insert test_t1 values (2, 11)")
  1905  	t := s.testGetBlock(c, "test_t1")
  1906  	tblInfo := t.Meta()
  1907  	indexInfo := tblInfo.FindIndexByName("p_a")
  1908  	c.Assert(indexInfo, NotNil)
  1909  	c.Assert(indexInfo.Global, IsTrue)
  1910  
  1911  	ctx := s.s.(stochastikctx.Context)
  1912  	ctx.NewTxn(context.Background())
  1913  	txn, err := ctx.Txn(true)
  1914  	c.Assert(err, IsNil)
  1915  
  1916  	// check event 1
  1917  	pid := tblInfo.Partition.Definitions[0].ID
  1918  	idxVals := []types.Causet{types.NewCauset(1)}
  1919  	rowVals := []types.Causet{types.NewCauset(1), types.NewCauset(1)}
  1920  	checkGlobalIndexRow(c, ctx, tblInfo, indexInfo, pid, idxVals, rowVals)
  1921  
  1922  	// check event 2
  1923  	pid = tblInfo.Partition.Definitions[1].ID
  1924  	idxVals = []types.Causet{types.NewCauset(2)}
  1925  	rowVals = []types.Causet{types.NewCauset(2), types.NewCauset(11)}
  1926  	checkGlobalIndexRow(c, ctx, tblInfo, indexInfo, pid, idxVals, rowVals)
  1927  	txn.Commit(context.Background())
  1928  
  1929  	// Test add global Primary Key index
  1930  	tk.MustInterDirc("create causet test_t2 (a int, b int) partition by range (b)" +
  1931  		" (partition p0 values less than (10), " +
  1932  		"  partition p1 values less than (maxvalue));")
  1933  	tk.MustInterDirc("insert test_t2 values (1, 1)")
  1934  	tk.MustInterDirc("alter causet test_t2 add primary key (a);")
  1935  	tk.MustInterDirc("insert test_t2 values (2, 11)")
  1936  	t = s.testGetBlock(c, "test_t2")
  1937  	tblInfo = t.Meta()
  1938  	indexInfo = t.Meta().FindIndexByName("primary")
  1939  	c.Assert(indexInfo, NotNil)
  1940  	c.Assert(indexInfo.Global, IsTrue)
  1941  
  1942  	ctx.NewTxn(context.Background())
  1943  	txn, err = ctx.Txn(true)
  1944  	c.Assert(err, IsNil)
  1945  
  1946  	// check event 1
  1947  	pid = tblInfo.Partition.Definitions[0].ID
  1948  	idxVals = []types.Causet{types.NewCauset(1)}
  1949  	rowVals = []types.Causet{types.NewCauset(1), types.NewCauset(1)}
  1950  	checkGlobalIndexRow(c, ctx, tblInfo, indexInfo, pid, idxVals, rowVals)
  1951  
  1952  	// check event 2
  1953  	pid = tblInfo.Partition.Definitions[1].ID
  1954  	idxVals = []types.Causet{types.NewCauset(2)}
  1955  	rowVals = []types.Causet{types.NewCauset(2), types.NewCauset(11)}
  1956  	checkGlobalIndexRow(c, ctx, tblInfo, indexInfo, pid, idxVals, rowVals)
  1957  
  1958  	txn.Commit(context.Background())
  1959  	config.UFIDelateGlobal(func(conf *config.Config) {
  1960  		conf.EnableGlobalIndex = false
  1961  	})
  1962  }
  1963  
  1964  func (s *testDBSuite) showDeferredCausets(tk *testkit.TestKit, c *C, blockName string) [][]interface{} {
  1965  	return s.mustQuery(tk, c, fmt.Sprintf("show defCausumns from %s", blockName))
  1966  }
  1967  
  1968  func (s *testDBSuite5) TestCreateIndexType(c *C) {
  1969  	tk := testkit.NewTestKit(c, s.causetstore)
  1970  	tk.MustInterDirc("use " + s.schemaName)
  1971  	allegrosql := `CREATE TABLE test_index (
  1972  		price int(5) DEFAULT '0' NOT NULL,
  1973  		area varchar(40) DEFAULT '' NOT NULL,
  1974  		type varchar(40) DEFAULT '' NOT NULL,
  1975  		transityes set('a','b'),
  1976  		shopsyes enum('Y','N') DEFAULT 'Y' NOT NULL,
  1977  		schoolsyes enum('Y','N') DEFAULT 'Y' NOT NULL,
  1978  		petsyes enum('Y','N') DEFAULT 'Y' NOT NULL,
  1979  		KEY price (price,area,type,transityes,shopsyes,schoolsyes,petsyes));`
  1980  	tk.MustInterDirc(allegrosql)
  1981  }
  1982  
  1983  func (s *testDBSuite1) TestDeferredCauset(c *C) {
  1984  	tk := testkit.NewTestKit(c, s.causetstore)
  1985  	tk.MustInterDirc("use " + s.schemaName)
  1986  	tk.MustInterDirc("create causet t2 (c1 int, c2 int, c3 int)")
  1987  	tk.MustInterDirc("set @@milevadb_disable_txn_auto_retry = 0")
  1988  	s.testAddDeferredCauset(tk, c)
  1989  	s.testDropDeferredCauset(tk, c)
  1990  	tk.MustInterDirc("drop causet t2")
  1991  }
  1992  
  1993  func stochastikInterDirc(c *C, s ekv.CausetStorage, allegrosql string) {
  1994  	se, err := stochastik.CreateStochastik4Test(s)
  1995  	c.Assert(err, IsNil)
  1996  	_, err = se.InterDircute(context.Background(), "use test_db")
  1997  	c.Assert(err, IsNil)
  1998  	rs, err := se.InterDircute(context.Background(), allegrosql)
  1999  	c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err)))
  2000  	c.Assert(rs, IsNil)
  2001  	se.Close()
  2002  }
  2003  
  2004  func (s *testDBSuite) testAddDeferredCauset(tk *testkit.TestKit, c *C) {
  2005  	done := make(chan error, 1)
  2006  
  2007  	num := defaultBatchSize + 10
  2008  	// add some rows
  2009  	batchInsert(tk, "t2", 0, num)
  2010  
  2011  	testdbsutil.StochastikInterDircInGoroutine(c, s.causetstore, "alter causet t2 add defCausumn c4 int default -1", done)
  2012  
  2013  	ticker := time.NewTicker(s.lease / 2)
  2014  	defer ticker.Stop()
  2015  	step := 10
  2016  LOOP:
  2017  	for {
  2018  		select {
  2019  		case err := <-done:
  2020  			if err == nil {
  2021  				break LOOP
  2022  			}
  2023  			c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err)))
  2024  		case <-ticker.C:
  2025  			// delete some rows, and add some data
  2026  			for i := num; i < num+step; i++ {
  2027  				n := rand.Intn(num)
  2028  				tk.MustInterDirc("begin")
  2029  				tk.MustInterDirc("delete from t2 where c1 = ?", n)
  2030  				tk.MustInterDirc("commit")
  2031  
  2032  				// Make sure that memex of insert and show use the same schemaReplicant.
  2033  				tk.MustInterDirc("begin")
  2034  				_, err := tk.InterDirc("insert into t2 values (?, ?, ?)", i, i, i)
  2035  				if err != nil {
  2036  					// if err is failed, the defCausumn number must be 4 now.
  2037  					values := s.showDeferredCausets(tk, c, "t2")
  2038  					c.Assert(values, HasLen, 4, Commentf("err:%v", errors.ErrorStack(err)))
  2039  				}
  2040  				tk.MustInterDirc("commit")
  2041  			}
  2042  			num += step
  2043  		}
  2044  	}
  2045  
  2046  	// add data, here c4 must exist
  2047  	for i := num; i < num+step; i++ {
  2048  		tk.MustInterDirc("insert into t2 values (?, ?, ?, ?)", i, i, i, i)
  2049  	}
  2050  
  2051  	rows := s.mustQuery(tk, c, "select count(c4) from t2")
  2052  	c.Assert(rows, HasLen, 1)
  2053  	c.Assert(rows[0], HasLen, 1)
  2054  	count, err := strconv.ParseInt(rows[0][0].(string), 10, 64)
  2055  	c.Assert(err, IsNil)
  2056  	c.Assert(count, Greater, int64(0))
  2057  
  2058  	rows = s.mustQuery(tk, c, "select count(c4) from t2 where c4 = -1")
  2059  	matchRows(c, rows, [][]interface{}{{count - int64(step)}})
  2060  
  2061  	for i := num; i < num+step; i++ {
  2062  		rows = s.mustQuery(tk, c, "select c4 from t2 where c4 = ?", i)
  2063  		matchRows(c, rows, [][]interface{}{{i}})
  2064  	}
  2065  
  2066  	ctx := s.s.(stochastikctx.Context)
  2067  	t := s.testGetBlock(c, "t2")
  2068  	i := 0
  2069  	j := 0
  2070  	ctx.NewTxn(context.Background())
  2071  	defer func() {
  2072  		if txn, err1 := ctx.Txn(true); err1 == nil {
  2073  			txn.Rollback()
  2074  		}
  2075  	}()
  2076  	err = t.IterRecords(ctx, t.FirstKey(), t.DefCauss(),
  2077  		func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
  2078  			i++
  2079  			// c4 must be -1 or > 0
  2080  			v, err1 := data[3].ToInt64(ctx.GetStochastikVars().StmtCtx)
  2081  			c.Assert(err1, IsNil)
  2082  			if v == -1 {
  2083  				j++
  2084  			} else {
  2085  				c.Assert(v, Greater, int64(0))
  2086  			}
  2087  			return true, nil
  2088  		})
  2089  	c.Assert(err, IsNil)
  2090  	c.Assert(i, Equals, int(count))
  2091  	c.Assert(i, LessEqual, num+step)
  2092  	c.Assert(j, Equals, int(count)-step)
  2093  
  2094  	// for modifying defCausumns after adding defCausumns
  2095  	tk.MustInterDirc("alter causet t2 modify c4 int default 11")
  2096  	for i := num + step; i < num+step+10; i++ {
  2097  		s.mustInterDirc(tk, c, "insert into t2 values (?, ?, ?, ?)", i, i, i, i)
  2098  	}
  2099  	rows = s.mustQuery(tk, c, "select count(c4) from t2 where c4 = -1")
  2100  	matchRows(c, rows, [][]interface{}{{count - int64(step)}})
  2101  
  2102  	// add timestamp type defCausumn
  2103  	s.mustInterDirc(tk, c, "create causet test_on_uFIDelate_c (c1 int, c2 timestamp);")
  2104  	defer tk.MustInterDirc("drop causet test_on_uFIDelate_c;")
  2105  	s.mustInterDirc(tk, c, "alter causet test_on_uFIDelate_c add defCausumn c3 timestamp null default '2020-02-11' on uFIDelate current_timestamp;")
  2106  	is := petri.GetPetri(ctx).SchemaReplicant()
  2107  	tbl, err := is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("test_on_uFIDelate_c"))
  2108  	c.Assert(err, IsNil)
  2109  	tblInfo := tbl.Meta()
  2110  	defCausC := tblInfo.DeferredCausets[2]
  2111  	c.Assert(defCausC.Tp, Equals, allegrosql.TypeTimestamp)
  2112  	hasNotNull := allegrosql.HasNotNullFlag(defCausC.Flag)
  2113  	c.Assert(hasNotNull, IsFalse)
  2114  	// add datetime type defCausumn
  2115  	s.mustInterDirc(tk, c, "create causet test_on_uFIDelate_d (c1 int, c2 datetime);")
  2116  	defer tk.MustInterDirc("drop causet test_on_uFIDelate_d;")
  2117  	s.mustInterDirc(tk, c, "alter causet test_on_uFIDelate_d add defCausumn c3 datetime on uFIDelate current_timestamp;")
  2118  	is = petri.GetPetri(ctx).SchemaReplicant()
  2119  	tbl, err = is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("test_on_uFIDelate_d"))
  2120  	c.Assert(err, IsNil)
  2121  	tblInfo = tbl.Meta()
  2122  	defCausC = tblInfo.DeferredCausets[2]
  2123  	c.Assert(defCausC.Tp, Equals, allegrosql.TypeDatetime)
  2124  	hasNotNull = allegrosql.HasNotNullFlag(defCausC.Flag)
  2125  	c.Assert(hasNotNull, IsFalse)
  2126  
  2127  	// add year type defCausumn
  2128  	s.mustInterDirc(tk, c, "create causet test_on_uFIDelate_e (c1 int);")
  2129  	defer tk.MustInterDirc("drop causet test_on_uFIDelate_e;")
  2130  	s.mustInterDirc(tk, c, "insert into test_on_uFIDelate_e (c1) values (0);")
  2131  	s.mustInterDirc(tk, c, "alter causet test_on_uFIDelate_e add defCausumn c2 year not null;")
  2132  	tk.MustQuery("select c2 from test_on_uFIDelate_e").Check(testkit.Rows("0"))
  2133  
  2134  	// test add unsupported constraint
  2135  	s.mustInterDirc(tk, c, "create causet t_add_unsupported_constraint (a int);")
  2136  	_, err = tk.InterDirc("ALTER TABLE t_add_unsupported_constraint ADD id int AUTO_INCREMENT;")
  2137  	c.Assert(err.Error(), Equals, "[dbs:8200]unsupported add defCausumn 'id' constraint AUTO_INCREMENT when altering 'test_db.t_add_unsupported_constraint'")
  2138  	_, err = tk.InterDirc("ALTER TABLE t_add_unsupported_constraint ADD id int KEY;")
  2139  	c.Assert(err.Error(), Equals, "[dbs:8200]unsupported add defCausumn 'id' constraint PRIMARY KEY when altering 'test_db.t_add_unsupported_constraint'")
  2140  	_, err = tk.InterDirc("ALTER TABLE t_add_unsupported_constraint ADD id int UNIQUE;")
  2141  	c.Assert(err.Error(), Equals, "[dbs:8200]unsupported add defCausumn 'id' constraint UNIQUE KEY when altering 'test_db.t_add_unsupported_constraint'")
  2142  }
  2143  
  2144  func (s *testDBSuite) testDropDeferredCauset(tk *testkit.TestKit, c *C) {
  2145  	done := make(chan error, 1)
  2146  	s.mustInterDirc(tk, c, "delete from t2")
  2147  
  2148  	num := 100
  2149  	// add some rows
  2150  	for i := 0; i < num; i++ {
  2151  		s.mustInterDirc(tk, c, "insert into t2 values (?, ?, ?, ?)", i, i, i, i)
  2152  	}
  2153  
  2154  	// get c4 defCausumn id
  2155  	testdbsutil.StochastikInterDircInGoroutine(c, s.causetstore, "alter causet t2 drop defCausumn c4", done)
  2156  
  2157  	ticker := time.NewTicker(s.lease / 2)
  2158  	defer ticker.Stop()
  2159  	step := 10
  2160  LOOP:
  2161  	for {
  2162  		select {
  2163  		case err := <-done:
  2164  			if err == nil {
  2165  				break LOOP
  2166  			}
  2167  			c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err)))
  2168  		case <-ticker.C:
  2169  			// delete some rows, and add some data
  2170  			for i := num; i < num+step; i++ {
  2171  				// Make sure that memex of insert and show use the same schemaReplicant.
  2172  				tk.MustInterDirc("begin")
  2173  				_, err := tk.InterDirc("insert into t2 values (?, ?, ?)", i, i, i)
  2174  				if err != nil {
  2175  					// If executing is failed, the defCausumn number must be 4 now.
  2176  					values := s.showDeferredCausets(tk, c, "t2")
  2177  					c.Assert(values, HasLen, 4, Commentf("err:%v", errors.ErrorStack(err)))
  2178  				}
  2179  				tk.MustInterDirc("commit")
  2180  			}
  2181  			num += step
  2182  		}
  2183  	}
  2184  
  2185  	// add data, here c4 must not exist
  2186  	for i := num; i < num+step; i++ {
  2187  		s.mustInterDirc(tk, c, "insert into t2 values (?, ?, ?)", i, i, i)
  2188  	}
  2189  
  2190  	rows := s.mustQuery(tk, c, "select count(*) from t2")
  2191  	c.Assert(rows, HasLen, 1)
  2192  	c.Assert(rows[0], HasLen, 1)
  2193  	count, err := strconv.ParseInt(rows[0][0].(string), 10, 64)
  2194  	c.Assert(err, IsNil)
  2195  	c.Assert(count, Greater, int64(0))
  2196  }
  2197  
  2198  // TestDropDeferredCauset is for inserting value with a to-be-dropped defCausumn when do drop defCausumn.
  2199  // DeferredCauset info from schemaReplicant in build-insert-plan should be public only,
  2200  // otherwise they will not be consist with Block.DefCaus(), then the server will panic.
  2201  func (s *testDBSuite6) TestDropDeferredCauset(c *C) {
  2202  	tk := testkit.NewTestKit(c, s.causetstore)
  2203  	tk.MustInterDirc("create database drop_defCaus_db")
  2204  	tk.MustInterDirc("use drop_defCaus_db")
  2205  	num := 25
  2206  	multiDBS := make([]string, 0, num)
  2207  	allegrosql := "create causet t2 (c1 int, c2 int, c3 int, "
  2208  	for i := 4; i < 4+num; i++ {
  2209  		multiDBS = append(multiDBS, fmt.Sprintf("alter causet t2 drop defCausumn c%d", i))
  2210  
  2211  		if i != 3+num {
  2212  			allegrosql += fmt.Sprintf("c%d int, ", i)
  2213  		} else {
  2214  			allegrosql += fmt.Sprintf("c%d int)", i)
  2215  		}
  2216  	}
  2217  	tk.MustInterDirc(allegrosql)
  2218  	dmlDone := make(chan error, num)
  2219  	dbsDone := make(chan error, num)
  2220  
  2221  	testdbsutil.InterDircMultiALLEGROSQLInGoroutine(c, s.causetstore, "drop_defCaus_db", multiDBS, dbsDone)
  2222  	for i := 0; i < num; i++ {
  2223  		testdbsutil.InterDircMultiALLEGROSQLInGoroutine(c, s.causetstore, "drop_defCaus_db", []string{"insert into t2 set c1 = 1, c2 = 1, c3 = 1, c4 = 1"}, dmlDone)
  2224  	}
  2225  	for i := 0; i < num; i++ {
  2226  		select {
  2227  		case err := <-dbsDone:
  2228  			c.Assert(err, IsNil, Commentf("err:%v", errors.ErrorStack(err)))
  2229  		}
  2230  	}
  2231  
  2232  	// Test for drop partition causet defCausumn.
  2233  	tk.MustInterDirc("drop causet if exists t1")
  2234  	tk.MustInterDirc("create causet t1 (a int,b int) partition by hash(a) partitions 4;")
  2235  	_, err := tk.InterDirc("alter causet t1 drop defCausumn a")
  2236  	c.Assert(err, NotNil)
  2237  	c.Assert(err.Error(), Equals, "[memex:1054]Unknown defCausumn 'a' in 'memex'")
  2238  
  2239  	tk.MustInterDirc("drop database drop_defCaus_db")
  2240  }
  2241  
  2242  func (s *testDBSuite4) TestChangeDeferredCauset(c *C) {
  2243  	tk := testkit.NewTestKit(c, s.causetstore)
  2244  	tk.MustInterDirc("use " + s.schemaName)
  2245  
  2246  	s.mustInterDirc(tk, c, "create causet t3 (a int default '0', b varchar(10), d int not null default '0')")
  2247  	s.mustInterDirc(tk, c, "insert into t3 set b = 'a'")
  2248  	tk.MustQuery("select a from t3").Check(testkit.Rows("0"))
  2249  	s.mustInterDirc(tk, c, "alter causet t3 change a aa bigint")
  2250  	s.mustInterDirc(tk, c, "insert into t3 set b = 'b'")
  2251  	tk.MustQuery("select aa from t3").Check(testkit.Rows("0", "<nil>"))
  2252  	// for no default flag
  2253  	s.mustInterDirc(tk, c, "alter causet t3 change d dd bigint not null")
  2254  	ctx := tk.Se.(stochastikctx.Context)
  2255  	is := petri.GetPetri(ctx).SchemaReplicant()
  2256  	tbl, err := is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("t3"))
  2257  	c.Assert(err, IsNil)
  2258  	tblInfo := tbl.Meta()
  2259  	defCausD := tblInfo.DeferredCausets[2]
  2260  	hasNoDefault := allegrosql.HasNoDefaultValueFlag(defCausD.Flag)
  2261  	c.Assert(hasNoDefault, IsTrue)
  2262  	// for the following definitions: 'not null', 'null', 'default value' and 'comment'
  2263  	s.mustInterDirc(tk, c, "alter causet t3 change b b varchar(20) null default 'c' comment 'my comment'")
  2264  	is = petri.GetPetri(ctx).SchemaReplicant()
  2265  	tbl, err = is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("t3"))
  2266  	c.Assert(err, IsNil)
  2267  	tblInfo = tbl.Meta()
  2268  	defCausB := tblInfo.DeferredCausets[1]
  2269  	c.Assert(defCausB.Comment, Equals, "my comment")
  2270  	hasNotNull := allegrosql.HasNotNullFlag(defCausB.Flag)
  2271  	c.Assert(hasNotNull, IsFalse)
  2272  	s.mustInterDirc(tk, c, "insert into t3 set aa = 3, dd = 5")
  2273  	tk.MustQuery("select b from t3").Check(testkit.Rows("a", "b", "c"))
  2274  	// for timestamp
  2275  	s.mustInterDirc(tk, c, "alter causet t3 add defCausumn c timestamp not null")
  2276  	s.mustInterDirc(tk, c, "alter causet t3 change c c timestamp null default '2020-02-11' comment 'defCaus c comment' on uFIDelate current_timestamp")
  2277  	is = petri.GetPetri(ctx).SchemaReplicant()
  2278  	tbl, err = is.BlockByName(perceptron.NewCIStr("test_db"), perceptron.NewCIStr("t3"))
  2279  	c.Assert(err, IsNil)
  2280  	tblInfo = tbl.Meta()
  2281  	defCausC := tblInfo.DeferredCausets[3]
  2282  	c.Assert(defCausC.Comment, Equals, "defCaus c comment")
  2283  	hasNotNull = allegrosql.HasNotNullFlag(defCausC.Flag)
  2284  	c.Assert(hasNotNull, IsFalse)
  2285  	// for enum
  2286  	s.mustInterDirc(tk, c, "alter causet t3 add defCausumn en enum('a', 'b', 'c') not null default 'a'")
  2287  
  2288  	// for failing tests
  2289  	allegrosql := "alter causet t3 change aa a bigint default ''"
  2290  	tk.MustGetErrCode(allegrosql, errno.ErrInvalidDefault)
  2291  	allegrosql = "alter causet t3 change a testx.t3.aa bigint"
  2292  	tk.MustGetErrCode(allegrosql, errno.ErrWrongDBName)
  2293  	allegrosql = "alter causet t3 change t.a aa bigint"
  2294  	tk.MustGetErrCode(allegrosql, errno.ErrWrongBlockName)
  2295  	s.mustInterDirc(tk, c, "create causet t4 (c1 int, c2 int, c3 int default 1, index (c1));")
  2296  	tk.MustInterDirc("insert into t4(c2) values (null);")
  2297  	allegrosql = "alter causet t4 change c1 a1 int not null;"
  2298  	tk.MustGetErrCode(allegrosql, errno.ErrInvalidUseOfNull)
  2299  	allegrosql = "alter causet t4 change c2 a bigint not null;"
  2300  	tk.MustGetErrCode(allegrosql, allegrosql.WarnDataTruncated)
  2301  	allegrosql = "alter causet t3 modify en enum('a', 'z', 'b', 'c') not null default 'a'"
  2302  	tk.MustGetErrCode(allegrosql, errno.ErrUnsupportedDBSOperation)
  2303  	// Rename to an existing defCausumn.
  2304  	s.mustInterDirc(tk, c, "alter causet t3 add defCausumn a bigint")
  2305  	allegrosql = "alter causet t3 change aa a bigint"
  2306  	tk.MustGetErrCode(allegrosql, errno.ErrDupFieldName)
  2307  
  2308  	tk.MustInterDirc("drop causet t3")
  2309  }
  2310  
  2311  func (s *testDBSuite5) TestRenameDeferredCauset(c *C) {
  2312  	tk := testkit.NewTestKit(c, s.causetstore)
  2313  	tk.MustInterDirc("use " + s.schemaName)
  2314  
  2315  	assertDefCausNames := func(blockName string, defCausNames ...string) {
  2316  		defcaus := s.testGetBlock(c, blockName).DefCauss()
  2317  		c.Assert(len(defcaus), Equals, len(defCausNames), Commentf("number of defCausumns mismatch"))
  2318  		for i := range defcaus {
  2319  			c.Assert(defcaus[i].Name.L, Equals, strings.ToLower(defCausNames[i]))
  2320  		}
  2321  	}
  2322  
  2323  	s.mustInterDirc(tk, c, "create causet test_rename_defCausumn (id int not null primary key auto_increment, defCaus1 int)")
  2324  	s.mustInterDirc(tk, c, "alter causet test_rename_defCausumn rename defCausumn defCaus1 to defCaus1")
  2325  	assertDefCausNames("test_rename_defCausumn", "id", "defCaus1")
  2326  	s.mustInterDirc(tk, c, "alter causet test_rename_defCausumn rename defCausumn defCaus1 to defCaus2")
  2327  	assertDefCausNames("test_rename_defCausumn", "id", "defCaus2")
  2328  
  2329  	// Test renaming non-exist defCausumns.
  2330  	tk.MustGetErrCode("alter causet test_rename_defCausumn rename defCausumn non_exist_defCaus to defCaus3", errno.ErrBadField)
  2331  
  2332  	// Test renaming to an exist defCausumn.
  2333  	tk.MustGetErrCode("alter causet test_rename_defCausumn rename defCausumn defCaus2 to id", errno.ErrDupFieldName)
  2334  
  2335  	// Test renaming the defCausumn with foreign key.
  2336  	tk.MustInterDirc("drop causet test_rename_defCausumn")
  2337  	tk.MustInterDirc("create causet test_rename_defCausumn_base (base int)")
  2338  	tk.MustInterDirc("create causet test_rename_defCausumn (defCaus int, foreign key (defCaus) references test_rename_defCausumn_base(base))")
  2339  
  2340  	tk.MustGetErrCode("alter causet test_rename_defCausumn rename defCausumn defCaus to defCaus1", errno.ErrFKIncompatibleDeferredCausets)
  2341  
  2342  	tk.MustInterDirc("drop causet test_rename_defCausumn_base")
  2343  
  2344  	// Test renaming generated defCausumns.
  2345  	tk.MustInterDirc("drop causet test_rename_defCausumn")
  2346  	tk.MustInterDirc("create causet test_rename_defCausumn (id int, defCaus1 int generated always as (id + 1))")
  2347  
  2348  	s.mustInterDirc(tk, c, "alter causet test_rename_defCausumn rename defCausumn defCaus1 to defCaus2")
  2349  	assertDefCausNames("test_rename_defCausumn", "id", "defCaus2")
  2350  	s.mustInterDirc(tk, c, "alter causet test_rename_defCausumn rename defCausumn defCaus2 to defCaus1")
  2351  	assertDefCausNames("test_rename_defCausumn", "id", "defCaus1")
  2352  	tk.MustGetErrCode("alter causet test_rename_defCausumn rename defCausumn id to id1", errno.ErrBadField)
  2353  
  2354  	// Test renaming view defCausumns.
  2355  	tk.MustInterDirc("drop causet test_rename_defCausumn")
  2356  	s.mustInterDirc(tk, c, "create causet test_rename_defCausumn (id int, defCaus1 int)")
  2357  	s.mustInterDirc(tk, c, "create view test_rename_defCausumn_view as select * from test_rename_defCausumn")
  2358  
  2359  	s.mustInterDirc(tk, c, "alter causet test_rename_defCausumn rename defCausumn defCaus1 to defCaus2")
  2360  	tk.MustGetErrCode("select * from test_rename_defCausumn_view", errno.ErrViewInvalid)
  2361  
  2362  	s.mustInterDirc(tk, c, "drop view test_rename_defCausumn_view")
  2363  	tk.MustInterDirc("drop causet test_rename_defCausumn")
  2364  }
  2365  
  2366  func (s *testDBSuite7) TestSelectInViewFromAnotherDB(c *C) {
  2367  	_, _ = s.s.InterDircute(context.Background(), "create database test_db2")
  2368  	tk := testkit.NewTestKit(c, s.causetstore)
  2369  	tk.MustInterDirc("use " + s.schemaName)
  2370  	tk.MustInterDirc("create causet t(a int)")
  2371  	tk.MustInterDirc("use test_db2")
  2372  	tk.MustInterDirc("create allegrosql security invoker view v as select * from " + s.schemaName + ".t")
  2373  	tk.MustInterDirc("use " + s.schemaName)
  2374  	tk.MustInterDirc("select test_db2.v.a from test_db2.v")
  2375  }
  2376  
  2377  func (s *testDBSuite) mustInterDirc(tk *testkit.TestKit, c *C, query string, args ...interface{}) {
  2378  	tk.MustInterDirc(query, args...)
  2379  }
  2380  
  2381  func (s *testDBSuite) mustQuery(tk *testkit.TestKit, c *C, query string, args ...interface{}) [][]interface{} {
  2382  	r := tk.MustQuery(query, args...)
  2383  	return r.Rows()
  2384  }
  2385  
  2386  func matchRows(c *C, rows [][]interface{}, expected [][]interface{}) {
  2387  	c.Assert(len(rows), Equals, len(expected), Commentf("got %v, expected %v", rows, expected))
  2388  	for i := range rows {
  2389  		match(c, rows[i], expected[i]...)
  2390  	}
  2391  }
  2392  
  2393  func match(c *C, event []interface{}, expected ...interface{}) {
  2394  	c.Assert(len(event), Equals, len(expected))
  2395  	for i := range event {
  2396  		got := fmt.Sprintf("%v", event[i])
  2397  		need := fmt.Sprintf("%v", expected[i])
  2398  		c.Assert(got, Equals, need)
  2399  	}
  2400  }
  2401  
  2402  // TestCreateBlockWithLike2 tests create causet with like when refer causet have non-public defCausumn/index.
  2403  func (s *testSerialDBSuite) TestCreateBlockWithLike2(c *C) {
  2404  	tk := testkit.NewTestKit(c, s.causetstore)
  2405  	tk.MustInterDirc("use test_db")
  2406  	tk.MustInterDirc("drop causet if exists t1,t2;")
  2407  	defer tk.MustInterDirc("drop causet if exists t1,t2;")
  2408  	tk.MustInterDirc("create causet t1 (a int, b int, c int, index idx1(c));")
  2409  
  2410  	tbl1 := testGetBlockByName(c, s.s, "test_db", "t1")
  2411  	doneCh := make(chan error, 2)
  2412  	hook := &dbs.TestDBSCallback{}
  2413  	var onceChecker sync.Map
  2414  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  2415  		if job.Type != perceptron.CausetActionAddDeferredCauset && job.Type != perceptron.CausetActionDropDeferredCauset &&
  2416  			job.Type != perceptron.CausetActionAddDeferredCausets && job.Type != perceptron.CausetActionDropDeferredCausets &&
  2417  			job.Type != perceptron.CausetActionAddIndex && job.Type != perceptron.CausetActionDropIndex {
  2418  			return
  2419  		}
  2420  		if job.BlockID != tbl1.Meta().ID {
  2421  			return
  2422  		}
  2423  
  2424  		if job.SchemaState == perceptron.StateDeleteOnly {
  2425  			if _, ok := onceChecker.Load(job.ID); ok {
  2426  				return
  2427  			}
  2428  
  2429  			onceChecker.CausetStore(job.ID, true)
  2430  			go backgroundInterDirc(s.causetstore, "create causet t2 like t1", doneCh)
  2431  		}
  2432  	}
  2433  	originalHook := s.dom.DBS().GetHook()
  2434  	defer s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
  2435  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  2436  
  2437  	// create causet when refer causet add defCausumn
  2438  	tk.MustInterDirc("alter causet t1 add defCausumn d int")
  2439  	checkTbl2 := func() {
  2440  		err := <-doneCh
  2441  		c.Assert(err, IsNil)
  2442  		tk.MustInterDirc("alter causet t2 add defCausumn e int")
  2443  		t2Info := testGetBlockByName(c, s.s, "test_db", "t2")
  2444  		c.Assert(len(t2Info.Meta().DeferredCausets), Equals, len(t2Info.DefCauss()))
  2445  	}
  2446  	checkTbl2()
  2447  
  2448  	// create causet when refer causet drop defCausumn
  2449  	tk.MustInterDirc("drop causet t2;")
  2450  	tk.MustInterDirc("alter causet t1 drop defCausumn b;")
  2451  	checkTbl2()
  2452  
  2453  	// create causet when refer causet add index
  2454  	tk.MustInterDirc("drop causet t2;")
  2455  	tk.MustInterDirc("alter causet t1 add index idx2(a);")
  2456  	checkTbl2 = func() {
  2457  		err := <-doneCh
  2458  		c.Assert(err, IsNil)
  2459  		tk.MustInterDirc("alter causet t2 add defCausumn e int")
  2460  		tbl2 := testGetBlockByName(c, s.s, "test_db", "t2")
  2461  		c.Assert(len(tbl2.Meta().DeferredCausets), Equals, len(tbl2.DefCauss()))
  2462  
  2463  		for i := 0; i < len(tbl2.Meta().Indices); i++ {
  2464  			c.Assert(tbl2.Meta().Indices[i].State, Equals, perceptron.StatePublic)
  2465  		}
  2466  	}
  2467  	checkTbl2()
  2468  
  2469  	// create causet when refer causet drop index.
  2470  	tk.MustInterDirc("drop causet t2;")
  2471  	tk.MustInterDirc("alter causet t1 drop index idx2;")
  2472  	checkTbl2()
  2473  
  2474  	// Test for causet has tiflash  replica.
  2475  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil)
  2476  	defer failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount")
  2477  
  2478  	s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
  2479  	tk.MustInterDirc("drop causet if exists t1,t2;")
  2480  	tk.MustInterDirc("create causet t1 (a int) partition by hash(a) partitions 2;")
  2481  	tk.MustInterDirc("alter causet t1 set tiflash replica 3 location labels 'a','b';")
  2482  	t1 := testGetBlockByName(c, s.s, "test_db", "t1")
  2483  	// Mock for all partitions replica was available.
  2484  	partition := t1.Meta().Partition
  2485  	c.Assert(len(partition.Definitions), Equals, 2)
  2486  	err := petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true)
  2487  	c.Assert(err, IsNil)
  2488  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[1].ID, true)
  2489  	c.Assert(err, IsNil)
  2490  	t1 = testGetBlockByName(c, s.s, "test_db", "t1")
  2491  	c.Assert(t1.Meta().TiFlashReplica, NotNil)
  2492  	c.Assert(t1.Meta().TiFlashReplica.Available, IsTrue)
  2493  	c.Assert(t1.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID, partition.Definitions[1].ID})
  2494  
  2495  	tk.MustInterDirc("create causet t2 like t1")
  2496  	t2 := testGetBlockByName(c, s.s, "test_db", "t2")
  2497  	c.Assert(t2.Meta().TiFlashReplica.Count, Equals, t1.Meta().TiFlashReplica.Count)
  2498  	c.Assert(t2.Meta().TiFlashReplica.LocationLabels, DeepEquals, t1.Meta().TiFlashReplica.LocationLabels)
  2499  	c.Assert(t2.Meta().TiFlashReplica.Available, IsFalse)
  2500  	c.Assert(t2.Meta().TiFlashReplica.AvailablePartitionIDs, HasLen, 0)
  2501  	// Test for not affecting the original causet.
  2502  	t1 = testGetBlockByName(c, s.s, "test_db", "t1")
  2503  	c.Assert(t1.Meta().TiFlashReplica, NotNil)
  2504  	c.Assert(t1.Meta().TiFlashReplica.Available, IsTrue)
  2505  	c.Assert(t1.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID, partition.Definitions[1].ID})
  2506  }
  2507  
  2508  func (s *testSerialDBSuite) TestCreateBlock(c *C) {
  2509  	tk := testkit.NewTestKit(c, s.causetstore)
  2510  	tk.MustInterDirc("use test")
  2511  	tk.MustInterDirc("CREATE TABLE `t` (`a` double DEFAULT 1.0 DEFAULT now() DEFAULT 2.0 );")
  2512  	tk.MustInterDirc("CREATE TABLE IF NOT EXISTS `t` (`a` double DEFAULT 1.0 DEFAULT now() DEFAULT 2.0 );")
  2513  	ctx := tk.Se.(stochastikctx.Context)
  2514  	is := petri.GetPetri(ctx).SchemaReplicant()
  2515  	tbl, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t"))
  2516  	c.Assert(err, IsNil)
  2517  	defcaus := tbl.DefCauss()
  2518  
  2519  	c.Assert(len(defcaus), Equals, 1)
  2520  	defCaus := defcaus[0]
  2521  	c.Assert(defCaus.Name.L, Equals, "a")
  2522  	d, ok := defCaus.DefaultValue.(string)
  2523  	c.Assert(ok, IsTrue)
  2524  	c.Assert(d, Equals, "2.0")
  2525  
  2526  	tk.MustInterDirc("drop causet t")
  2527  
  2528  	tk.MustGetErrCode("CREATE TABLE `t` (`a` int) DEFAULT CHARSET=abcdefg", errno.ErrUnknownCharacterSet)
  2529  
  2530  	tk.MustInterDirc("CREATE TABLE `defCauslateTest` (`a` int, `b` varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_slovak_ci")
  2531  	expects := "defCauslateTest CREATE TABLE `defCauslateTest` (\n  `a` int(11) DEFAULT NULL,\n  `b` varchar(10) COLLATE utf8_slovak_ci DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_slovak_ci"
  2532  	tk.MustQuery("show create causet defCauslateTest").Check(testkit.Rows(expects))
  2533  
  2534  	tk.MustGetErrCode("CREATE TABLE `defCauslateTest2` (`a` int) CHARSET utf8 COLLATE utf8mb4_unicode_ci", errno.ErrDefCauslationCharsetMismatch)
  2535  	tk.MustGetErrCode("CREATE TABLE `defCauslateTest3` (`a` int) COLLATE utf8mb4_unicode_ci CHARSET utf8", errno.ErrConflictingDeclarations)
  2536  
  2537  	tk.MustInterDirc("CREATE TABLE `defCauslateTest4` (`a` int) COLLATE utf8_uniCOde_ci")
  2538  	expects = "defCauslateTest4 CREATE TABLE `defCauslateTest4` (\n  `a` int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"
  2539  	tk.MustQuery("show create causet defCauslateTest4").Check(testkit.Rows(expects))
  2540  
  2541  	tk.MustInterDirc("create database test2 default charset utf8 defCauslate utf8_general_ci")
  2542  	tk.MustInterDirc("use test2")
  2543  	tk.MustInterDirc("create causet dbDefCauslateTest (a varchar(10))")
  2544  	expects = "dbDefCauslateTest CREATE TABLE `dbDefCauslateTest` (\n  `a` varchar(10) COLLATE utf8_general_ci DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"
  2545  	tk.MustQuery("show create causet dbDefCauslateTest").Check(testkit.Rows(expects))
  2546  
  2547  	// test for enum defCausumn
  2548  	tk.MustInterDirc("use test")
  2549  	failALLEGROSQL := "create causet t_enum (a enum('e','e'));"
  2550  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType)
  2551  	defCauslate.SetNewDefCauslationEnabledForTest(true)
  2552  	defer defCauslate.SetNewDefCauslationEnabledForTest(false)
  2553  	tk = testkit.NewTestKit(c, s.causetstore)
  2554  	tk.MustInterDirc("use test")
  2555  	failALLEGROSQL = "create causet t_enum (a enum('e','E')) charset=utf8 defCauslate=utf8_general_ci;"
  2556  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType)
  2557  	failALLEGROSQL = "create causet t_enum (a enum('abc','Abc')) charset=utf8 defCauslate=utf8_general_ci;"
  2558  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType)
  2559  	failALLEGROSQL = "create causet t_enum (a enum('e','E')) charset=utf8 defCauslate=utf8_unicode_ci;"
  2560  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType)
  2561  	failALLEGROSQL = "create causet t_enum (a enum('ss','ß')) charset=utf8 defCauslate=utf8_unicode_ci;"
  2562  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType)
  2563  	// test for set defCausumn
  2564  	failALLEGROSQL = "create causet t_enum (a set('e','e'));"
  2565  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType)
  2566  	failALLEGROSQL = "create causet t_enum (a set('e','E')) charset=utf8 defCauslate=utf8_general_ci;"
  2567  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType)
  2568  	failALLEGROSQL = "create causet t_enum (a set('abc','Abc')) charset=utf8 defCauslate=utf8_general_ci;"
  2569  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType)
  2570  	_, err = tk.InterDirc("create causet t_enum (a enum('B','b')) charset=utf8 defCauslate=utf8_general_ci;")
  2571  	c.Assert(err.Error(), Equals, "[types:1291]DeferredCauset 'a' has duplicated value 'b' in ENUM")
  2572  	failALLEGROSQL = "create causet t_enum (a set('e','E')) charset=utf8 defCauslate=utf8_unicode_ci;"
  2573  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType)
  2574  	failALLEGROSQL = "create causet t_enum (a set('ss','ß')) charset=utf8 defCauslate=utf8_unicode_ci;"
  2575  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrDuplicatedValueInType)
  2576  	_, err = tk.InterDirc("create causet t_enum (a enum('ss','ß')) charset=utf8 defCauslate=utf8_unicode_ci;")
  2577  	c.Assert(err.Error(), Equals, "[types:1291]DeferredCauset 'a' has duplicated value 'ß' in ENUM")
  2578  
  2579  	// test for causet option "union" not supported
  2580  	tk.MustInterDirc("use test")
  2581  	tk.MustInterDirc("CREATE TABLE x (a INT) ENGINE = MyISAM;")
  2582  	tk.MustInterDirc("CREATE TABLE y (a INT) ENGINE = MyISAM;")
  2583  	failALLEGROSQL = "CREATE TABLE z (a INT) ENGINE = MERGE UNION = (x, y);"
  2584  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockOptionUnionUnsupported)
  2585  	failALLEGROSQL = "ALTER TABLE x UNION = (y);"
  2586  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockOptionUnionUnsupported)
  2587  	tk.MustInterDirc("drop causet x;")
  2588  	tk.MustInterDirc("drop causet y;")
  2589  
  2590  	// test for causet option "insert method" not supported
  2591  	tk.MustInterDirc("use test")
  2592  	tk.MustInterDirc("CREATE TABLE x (a INT) ENGINE = MyISAM;")
  2593  	tk.MustInterDirc("CREATE TABLE y (a INT) ENGINE = MyISAM;")
  2594  	failALLEGROSQL = "CREATE TABLE z (a INT) ENGINE = MERGE INSERT_METHOD=LAST;"
  2595  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockOptionInsertMethodUnsupported)
  2596  	failALLEGROSQL = "ALTER TABLE x INSERT_METHOD=LAST;"
  2597  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockOptionInsertMethodUnsupported)
  2598  	tk.MustInterDirc("drop causet x;")
  2599  	tk.MustInterDirc("drop causet y;")
  2600  }
  2601  
  2602  func (s *testSerialDBSuite) TestRepairBlock(c *C) {
  2603  	// TODO: When AlterPrimaryKey is false, this test fails. Fix it later.
  2604  	defer config.RestoreFunc()()
  2605  	config.UFIDelateGlobal(func(conf *config.Config) {
  2606  		conf.AlterPrimaryKey = true
  2607  	})
  2608  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/repairFetchCreateBlock", `return(true)`), IsNil)
  2609  	defer func() {
  2610  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/repairFetchCreateBlock"), IsNil)
  2611  	}()
  2612  	tk := testkit.NewTestKit(c, s.causetstore)
  2613  	tk.MustInterDirc("use test")
  2614  	tk.MustInterDirc("drop causet if exists t, other_block, origin")
  2615  
  2616  	// Test repair causet when MilevaDB is not in repair mode.
  2617  	tk.MustInterDirc("CREATE TABLE t (a int primary key, b varchar(10));")
  2618  	_, err := tk.InterDirc("admin repair causet t CREATE TABLE t (a float primary key, b varchar(5));")
  2619  	c.Assert(err, NotNil)
  2620  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: MilevaDB is not in REPAIR MODE")
  2621  
  2622  	// Test repair causet when the repaired list is empty.
  2623  	petriutil.RepairInfo.SetRepairMode(true)
  2624  	_, err = tk.InterDirc("admin repair causet t CREATE TABLE t (a float primary key, b varchar(5));")
  2625  	c.Assert(err, NotNil)
  2626  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: repair list is empty")
  2627  
  2628  	// Test repair causet when it's database isn't in repairInfo.
  2629  	petriutil.RepairInfo.SetRepairBlockList([]string{"test.other_block"})
  2630  	_, err = tk.InterDirc("admin repair causet t CREATE TABLE t (a float primary key, b varchar(5));")
  2631  	c.Assert(err, NotNil)
  2632  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: database test is not in repair")
  2633  
  2634  	// Test repair causet when the causet isn't in repairInfo.
  2635  	tk.MustInterDirc("CREATE TABLE other_block (a int, b varchar(1), key using hash(b));")
  2636  	_, err = tk.InterDirc("admin repair causet t CREATE TABLE t (a float primary key, b varchar(5));")
  2637  	c.Assert(err, NotNil)
  2638  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: causet t is not in repair")
  2639  
  2640  	// Test user can't access to the repaired causet.
  2641  	_, err = tk.InterDirc("select * from other_block")
  2642  	c.Assert(err, NotNil)
  2643  	c.Assert(err.Error(), Equals, "[schemaReplicant:1146]Block 'test.other_block' doesn't exist")
  2644  
  2645  	// Test create memex use the same name with what is in repaired.
  2646  	_, err = tk.InterDirc("CREATE TABLE other_block (a int);")
  2647  	c.Assert(err, NotNil)
  2648  	c.Assert(err.Error(), Equals, "[dbs:1103]Incorrect causet name 'other_block'%!(EXTRA string=this causet is in repair)")
  2649  
  2650  	// Test defCausumn lost in repair causet.
  2651  	_, err = tk.InterDirc("admin repair causet other_block CREATE TABLE other_block (a int, c char(1));")
  2652  	c.Assert(err, NotNil)
  2653  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: DeferredCauset c has lost")
  2654  
  2655  	// Test defCausumn type should be the same.
  2656  	_, err = tk.InterDirc("admin repair causet other_block CREATE TABLE other_block (a bigint, b varchar(1), key using hash(b));")
  2657  	c.Assert(err, NotNil)
  2658  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: DeferredCauset a type should be the same")
  2659  
  2660  	// Test index lost in repair causet.
  2661  	_, err = tk.InterDirc("admin repair causet other_block CREATE TABLE other_block (a int unique);")
  2662  	c.Assert(err, NotNil)
  2663  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Index a has lost")
  2664  
  2665  	// Test index type should be the same.
  2666  	_, err = tk.InterDirc("admin repair causet other_block CREATE TABLE other_block (a int, b varchar(2) unique)")
  2667  	c.Assert(err, NotNil)
  2668  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Index b type should be the same")
  2669  
  2670  	// Test sub create memex in repair memex with the same name.
  2671  	_, err = tk.InterDirc("admin repair causet other_block CREATE TABLE other_block (a int);")
  2672  	c.Assert(err, IsNil)
  2673  
  2674  	// Test whether repair causet name is case sensitive.
  2675  	petriutil.RepairInfo.SetRepairMode(true)
  2676  	petriutil.RepairInfo.SetRepairBlockList([]string{"test.other_block2"})
  2677  	tk.MustInterDirc("CREATE TABLE otHer_tAblE2 (a int, b varchar(1));")
  2678  	_, err = tk.InterDirc("admin repair causet otHer_tAblE2 CREATE TABLE otHeR_tAbLe (a int, b varchar(2));")
  2679  	c.Assert(err, IsNil)
  2680  	repairBlock := testGetBlockByName(c, s.s, "test", "otHeR_tAbLe")
  2681  	c.Assert(repairBlock.Meta().Name.O, Equals, "otHeR_tAbLe")
  2682  
  2683  	// Test memory and system database is not for repair.
  2684  	petriutil.RepairInfo.SetRepairMode(true)
  2685  	petriutil.RepairInfo.SetRepairBlockList([]string{"test.xxx"})
  2686  	_, err = tk.InterDirc("admin repair causet performance_schema.xxx CREATE TABLE yyy (a int);")
  2687  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: memory or system database is not for repair")
  2688  
  2689  	// Test the repair detail.
  2690  	turnRepairModeAndInit(true)
  2691  	defer turnRepairModeAndInit(false)
  2692  	// Petri reload the blockInfo and add it into repairInfo.
  2693  	tk.MustInterDirc("CREATE TABLE origin (a int primary key auto_increment, b varchar(10), c int);")
  2694  	// Repaired blockInfo has been filtered by `petri.SchemaReplicant()`, so get it in repairInfo.
  2695  	originBlockInfo, _ := petriutil.RepairInfo.GetRepairedBlockInfoByBlockName("test", "origin")
  2696  
  2697  	hook := &dbs.TestDBSCallback{}
  2698  	var repairErr error
  2699  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  2700  		if job.Type != perceptron.CausetActionRepairBlock {
  2701  			return
  2702  		}
  2703  		if job.BlockID != originBlockInfo.ID {
  2704  			repairErr = errors.New("causet id should be the same")
  2705  			return
  2706  		}
  2707  		if job.SchemaState != perceptron.StateNone {
  2708  			repairErr = errors.New("repair job state should be the none")
  2709  			return
  2710  		}
  2711  		// Test whether it's readable, when repaired causet is still stateNone.
  2712  		tkInternal := testkit.NewTestKitWithInit(c, s.causetstore)
  2713  		_, repairErr = tkInternal.InterDirc("select * from origin")
  2714  		// Repaired blockInfo has been filtered by `petri.SchemaReplicant()`, here will get an error cause user can't get access to it.
  2715  		if repairErr != nil && terror.ErrorEqual(repairErr, schemareplicant.ErrBlockNotExists) {
  2716  			repairErr = nil
  2717  		}
  2718  	}
  2719  	originalHook := s.dom.DBS().GetHook()
  2720  	defer s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
  2721  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  2722  
  2723  	// InterDirc the repair memex to override the blockInfo.
  2724  	tk.MustInterDirc("admin repair causet origin CREATE TABLE origin (a int primary key auto_increment, b varchar(5), c int);")
  2725  	c.Assert(repairErr, IsNil)
  2726  
  2727  	// Check the repaired blockInfo is exactly the same with old one in blockID, indexID, defCausID.
  2728  	// testGetBlockByName will extract the Block from `petri.SchemaReplicant()` directly.
  2729  	repairBlock = testGetBlockByName(c, s.s, "test", "origin")
  2730  	c.Assert(repairBlock.Meta().ID, Equals, originBlockInfo.ID)
  2731  	c.Assert(len(repairBlock.Meta().DeferredCausets), Equals, 3)
  2732  	c.Assert(repairBlock.Meta().DeferredCausets[0].ID, Equals, originBlockInfo.DeferredCausets[0].ID)
  2733  	c.Assert(repairBlock.Meta().DeferredCausets[1].ID, Equals, originBlockInfo.DeferredCausets[1].ID)
  2734  	c.Assert(repairBlock.Meta().DeferredCausets[2].ID, Equals, originBlockInfo.DeferredCausets[2].ID)
  2735  	c.Assert(len(repairBlock.Meta().Indices), Equals, 1)
  2736  	c.Assert(repairBlock.Meta().Indices[0].ID, Equals, originBlockInfo.DeferredCausets[0].ID)
  2737  	c.Assert(repairBlock.Meta().AutoIncID, Equals, originBlockInfo.AutoIncID)
  2738  
  2739  	c.Assert(repairBlock.Meta().DeferredCausets[0].Tp, Equals, allegrosql.TypeLong)
  2740  	c.Assert(repairBlock.Meta().DeferredCausets[1].Tp, Equals, allegrosql.TypeVarchar)
  2741  	c.Assert(repairBlock.Meta().DeferredCausets[1].Flen, Equals, 5)
  2742  	c.Assert(repairBlock.Meta().DeferredCausets[2].Tp, Equals, allegrosql.TypeLong)
  2743  
  2744  	// InterDirc the show create causet memex to make sure new blockInfo has been set.
  2745  	result := tk.MustQuery("show create causet origin")
  2746  	c.Assert(result.Rows()[0][1], Equals, "CREATE TABLE `origin` (\n  `a` int(11) NOT NULL AUTO_INCREMENT,\n  `b` varchar(5) DEFAULT NULL,\n  `c` int(11) DEFAULT NULL,\n  PRIMARY KEY (`a`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")
  2747  
  2748  }
  2749  
  2750  func turnRepairModeAndInit(on bool) {
  2751  	list := make([]string, 0)
  2752  	if on {
  2753  		list = append(list, "test.origin")
  2754  	}
  2755  	petriutil.RepairInfo.SetRepairMode(on)
  2756  	petriutil.RepairInfo.SetRepairBlockList(list)
  2757  }
  2758  
  2759  func (s *testSerialDBSuite) TestRepairBlockWithPartition(c *C) {
  2760  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/repairFetchCreateBlock", `return(true)`), IsNil)
  2761  	defer func() {
  2762  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/repairFetchCreateBlock"), IsNil)
  2763  	}()
  2764  	tk := testkit.NewTestKit(c, s.causetstore)
  2765  	tk.MustInterDirc("use test")
  2766  	tk.MustInterDirc("drop causet if exists origin")
  2767  
  2768  	turnRepairModeAndInit(true)
  2769  	defer turnRepairModeAndInit(false)
  2770  	// Petri reload the blockInfo and add it into repairInfo.
  2771  	tk.MustInterDirc("create causet origin (a int not null) partition by RANGE(a) (" +
  2772  		"partition p10 values less than (10)," +
  2773  		"partition p30 values less than (30)," +
  2774  		"partition p50 values less than (50)," +
  2775  		"partition p70 values less than (70)," +
  2776  		"partition p90 values less than (90));")
  2777  	// Test for some old partition has lost.
  2778  	_, err := tk.InterDirc("admin repair causet origin create causet origin (a int not null) partition by RANGE(a) (" +
  2779  		"partition p10 values less than (10)," +
  2780  		"partition p30 values less than (30)," +
  2781  		"partition p50 values less than (50)," +
  2782  		"partition p90 values less than (90)," +
  2783  		"partition p100 values less than (100));")
  2784  	c.Assert(err, NotNil)
  2785  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Partition p100 has lost")
  2786  
  2787  	// Test for some partition changed the condition.
  2788  	_, err = tk.InterDirc("admin repair causet origin create causet origin (a int not null) partition by RANGE(a) (" +
  2789  		"partition p10 values less than (10)," +
  2790  		"partition p20 values less than (25)," +
  2791  		"partition p50 values less than (50)," +
  2792  		"partition p90 values less than (90));")
  2793  	c.Assert(err, NotNil)
  2794  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Partition p20 has lost")
  2795  
  2796  	// Test for some partition changed the partition name.
  2797  	_, err = tk.InterDirc("admin repair causet origin create causet origin (a int not null) partition by RANGE(a) (" +
  2798  		"partition p10 values less than (10)," +
  2799  		"partition p30 values less than (30)," +
  2800  		"partition pNew values less than (50)," +
  2801  		"partition p90 values less than (90));")
  2802  	c.Assert(err, NotNil)
  2803  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Partition pnew has lost")
  2804  
  2805  	originBlockInfo, _ := petriutil.RepairInfo.GetRepairedBlockInfoByBlockName("test", "origin")
  2806  	tk.MustInterDirc("admin repair causet origin create causet origin_rename (a int not null) partition by RANGE(a) (" +
  2807  		"partition p10 values less than (10)," +
  2808  		"partition p30 values less than (30)," +
  2809  		"partition p50 values less than (50)," +
  2810  		"partition p90 values less than (90));")
  2811  	repairBlock := testGetBlockByName(c, s.s, "test", "origin_rename")
  2812  	c.Assert(repairBlock.Meta().ID, Equals, originBlockInfo.ID)
  2813  	c.Assert(len(repairBlock.Meta().DeferredCausets), Equals, 1)
  2814  	c.Assert(repairBlock.Meta().DeferredCausets[0].ID, Equals, originBlockInfo.DeferredCausets[0].ID)
  2815  	c.Assert(len(repairBlock.Meta().Partition.Definitions), Equals, 4)
  2816  	c.Assert(repairBlock.Meta().Partition.Definitions[0].ID, Equals, originBlockInfo.Partition.Definitions[0].ID)
  2817  	c.Assert(repairBlock.Meta().Partition.Definitions[1].ID, Equals, originBlockInfo.Partition.Definitions[1].ID)
  2818  	c.Assert(repairBlock.Meta().Partition.Definitions[2].ID, Equals, originBlockInfo.Partition.Definitions[2].ID)
  2819  	c.Assert(repairBlock.Meta().Partition.Definitions[3].ID, Equals, originBlockInfo.Partition.Definitions[4].ID)
  2820  
  2821  	// Test hash partition.
  2822  	tk.MustInterDirc("drop causet if exists origin")
  2823  	petriutil.RepairInfo.SetRepairMode(true)
  2824  	petriutil.RepairInfo.SetRepairBlockList([]string{"test.origin"})
  2825  	tk.MustInterDirc("create causet origin (a varchar(1), b int not null, c int, key idx(c)) partition by hash(b) partitions 30")
  2826  
  2827  	// Test partition num in repair should be exactly same with old one, other wise will cause partition semantic problem.
  2828  	_, err = tk.InterDirc("admin repair causet origin create causet origin (a varchar(2), b int not null, c int, key idx(c)) partition by hash(b) partitions 20")
  2829  	c.Assert(err, NotNil)
  2830  	c.Assert(err.Error(), Equals, "[dbs:8215]Failed to repair causet: Hash partition num should be the same")
  2831  
  2832  	originBlockInfo, _ = petriutil.RepairInfo.GetRepairedBlockInfoByBlockName("test", "origin")
  2833  	tk.MustInterDirc("admin repair causet origin create causet origin (a varchar(3), b int not null, c int, key idx(c)) partition by hash(b) partitions 30")
  2834  	repairBlock = testGetBlockByName(c, s.s, "test", "origin")
  2835  	c.Assert(repairBlock.Meta().ID, Equals, originBlockInfo.ID)
  2836  	c.Assert(len(repairBlock.Meta().Partition.Definitions), Equals, 30)
  2837  	c.Assert(repairBlock.Meta().Partition.Definitions[0].ID, Equals, originBlockInfo.Partition.Definitions[0].ID)
  2838  	c.Assert(repairBlock.Meta().Partition.Definitions[1].ID, Equals, originBlockInfo.Partition.Definitions[1].ID)
  2839  	c.Assert(repairBlock.Meta().Partition.Definitions[29].ID, Equals, originBlockInfo.Partition.Definitions[29].ID)
  2840  }
  2841  
  2842  func (s *testDBSuite2) TestCreateBlockWithSetDefCaus(c *C) {
  2843  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
  2844  	tk.MustInterDirc("create causet t_set (a int, b set('e') default '');")
  2845  	tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" +
  2846  		"  `a` int(11) DEFAULT NULL,\n" +
  2847  		"  `b` set('e') DEFAULT ''\n" +
  2848  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  2849  	tk.MustInterDirc("drop causet t_set")
  2850  	tk.MustInterDirc("create causet t_set (a set('a', 'b', 'c', 'd') default 'a,c,c');")
  2851  	tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" +
  2852  		"  `a` set('a','b','c','d') DEFAULT 'a,c'\n" +
  2853  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  2854  
  2855  	// It's for failure cases.
  2856  	// The type of default value is string.
  2857  	tk.MustInterDirc("drop causet t_set")
  2858  	failedALLEGROSQL := "create causet t_set (a set('1', '4', '10') default '3');"
  2859  	tk.MustGetErrCode(failedALLEGROSQL, errno.ErrInvalidDefault)
  2860  	failedALLEGROSQL = "create causet t_set (a set('1', '4', '10') default '1,4,11');"
  2861  	tk.MustGetErrCode(failedALLEGROSQL, errno.ErrInvalidDefault)
  2862  	failedALLEGROSQL = "create causet t_set (a set('1', '4', '10') default '1 ,4');"
  2863  	tk.MustGetErrCode(failedALLEGROSQL, errno.ErrInvalidDefault)
  2864  	// The type of default value is int.
  2865  	failedALLEGROSQL = "create causet t_set (a set('1', '4', '10') default 0);"
  2866  	tk.MustGetErrCode(failedALLEGROSQL, errno.ErrInvalidDefault)
  2867  	failedALLEGROSQL = "create causet t_set (a set('1', '4', '10') default 8);"
  2868  	tk.MustGetErrCode(failedALLEGROSQL, errno.ErrInvalidDefault)
  2869  
  2870  	// The type of default value is int.
  2871  	// It's for successful cases
  2872  	tk.MustInterDirc("create causet t_set (a set('1', '4', '10', '21') default 1);")
  2873  	tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" +
  2874  		"  `a` set('1','4','10','21') DEFAULT '1'\n" +
  2875  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  2876  	tk.MustInterDirc("drop causet t_set")
  2877  	tk.MustInterDirc("create causet t_set (a set('1', '4', '10', '21') default 2);")
  2878  	tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" +
  2879  		"  `a` set('1','4','10','21') DEFAULT '4'\n" +
  2880  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  2881  	tk.MustInterDirc("drop causet t_set")
  2882  	tk.MustInterDirc("create causet t_set (a set('1', '4', '10', '21') default 3);")
  2883  	tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" +
  2884  		"  `a` set('1','4','10','21') DEFAULT '1,4'\n" +
  2885  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  2886  	tk.MustInterDirc("drop causet t_set")
  2887  	tk.MustInterDirc("create causet t_set (a set('1', '4', '10', '21') default 15);")
  2888  	tk.MustQuery("show create causet t_set").Check(testkit.Rows("t_set CREATE TABLE `t_set` (\n" +
  2889  		"  `a` set('1','4','10','21') DEFAULT '1,4,10,21'\n" +
  2890  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  2891  	tk.MustInterDirc("insert into t_set value()")
  2892  	tk.MustQuery("select * from t_set").Check(testkit.Rows("1,4,10,21"))
  2893  }
  2894  
  2895  func (s *testDBSuite2) TestBlockForeignKey(c *C) {
  2896  	tk := testkit.NewTestKit(c, s.causetstore)
  2897  	tk.MustInterDirc("use test")
  2898  	tk.MustInterDirc("create causet t1 (a int, b int);")
  2899  	// test create causet with foreign key.
  2900  	failALLEGROSQL := "create causet t2 (c int, foreign key (a) references t1(a));"
  2901  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrKeyDeferredCausetDoesNotExits)
  2902  	// test add foreign key.
  2903  	tk.MustInterDirc("create causet t3 (a int, b int);")
  2904  	failALLEGROSQL = "alter causet t1 add foreign key (c) REFERENCES t3(a);"
  2905  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrKeyDeferredCausetDoesNotExits)
  2906  	// test oreign key not match error
  2907  	failALLEGROSQL = "alter causet t1 add foreign key (a) REFERENCES t3(a, b);"
  2908  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrWrongFkDef)
  2909  	// Test drop defCausumn with foreign key.
  2910  	tk.MustInterDirc("create causet t4 (c int,d int,foreign key (d) references t1 (b));")
  2911  	failALLEGROSQL = "alter causet t4 drop defCausumn d"
  2912  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrFkDeferredCausetCannotDrop)
  2913  	// Test change defCausumn with foreign key.
  2914  	failALLEGROSQL = "alter causet t4 change defCausumn d e bigint;"
  2915  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrFKIncompatibleDeferredCausets)
  2916  	// Test modify defCausumn with foreign key.
  2917  	failALLEGROSQL = "alter causet t4 modify defCausumn d bigint;"
  2918  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrFKIncompatibleDeferredCausets)
  2919  	tk.MustQuery("select count(*) from information_schema.KEY_COLUMN_USAGE;")
  2920  	tk.MustInterDirc("alter causet t4 drop foreign key d")
  2921  	tk.MustInterDirc("alter causet t4 modify defCausumn d bigint;")
  2922  	tk.MustInterDirc("drop causet if exists t1,t2,t3,t4;")
  2923  }
  2924  
  2925  func (s *testDBSuite3) TestFKOnGeneratedDeferredCausets(c *C) {
  2926  	tk := testkit.NewTestKit(c, s.causetstore)
  2927  	tk.MustInterDirc("use test")
  2928  	// test add foreign key to generated defCausumn
  2929  
  2930  	// foreign key constraint cannot be defined on a virtual generated defCausumn.
  2931  	tk.MustInterDirc("create causet t1 (a int primary key);")
  2932  	tk.MustGetErrCode("create causet t2 (a int, b int as (a+1) virtual, foreign key (b) references t1(a));", errno.ErrCannotAddForeign)
  2933  	tk.MustInterDirc("create causet t2 (a int, b int generated always as (a+1) virtual);")
  2934  	tk.MustGetErrCode("alter causet t2 add foreign key (b) references t1(a);", errno.ErrCannotAddForeign)
  2935  	tk.MustInterDirc("drop causet t1, t2;")
  2936  
  2937  	// foreign key constraint can be defined on a stored generated defCausumn.
  2938  	tk.MustInterDirc("create causet t2 (a int primary key);")
  2939  	tk.MustInterDirc("create causet t1 (a int, b int as (a+1) stored, foreign key (b) references t2(a));")
  2940  	tk.MustInterDirc("create causet t3 (a int, b int generated always as (a+1) stored);")
  2941  	tk.MustInterDirc("alter causet t3 add foreign key (b) references t2(a);")
  2942  	tk.MustInterDirc("drop causet t1, t2, t3;")
  2943  
  2944  	// foreign key constraint can reference a stored generated defCausumn.
  2945  	tk.MustInterDirc("create causet t1 (a int, b int generated always as (a+1) stored primary key);")
  2946  	tk.MustInterDirc("create causet t2 (a int, foreign key (a) references t1(b));")
  2947  	tk.MustInterDirc("create causet t3 (a int);")
  2948  	tk.MustInterDirc("alter causet t3 add foreign key (a) references t1(b);")
  2949  	tk.MustInterDirc("drop causet t1, t2, t3;")
  2950  
  2951  	// rejected FK options on stored generated defCausumns
  2952  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on uFIDelate set null);", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2953  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on uFIDelate cascade);", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2954  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on uFIDelate set default);", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2955  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on delete set null);", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2956  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on delete set default);", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2957  	tk.MustInterDirc("create causet t2 (a int primary key);")
  2958  	tk.MustInterDirc("create causet t1 (a int, b int generated always as (a+1) stored);")
  2959  	tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on uFIDelate set null;", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2960  	tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on uFIDelate cascade;", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2961  	tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on uFIDelate set default;", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2962  	tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on delete set null;", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2963  	tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on delete set default;", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2964  	tk.MustInterDirc("drop causet t1, t2;")
  2965  	// defCausumn name with uppercase characters
  2966  	tk.MustGetErrCode("create causet t1 (A int, b int generated always as (a+1) stored, foreign key (b) references t2(a) on uFIDelate set null);", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2967  	tk.MustInterDirc("create causet t2 (a int primary key);")
  2968  	tk.MustInterDirc("create causet t1 (A int, b int generated always as (a+1) stored);")
  2969  	tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on uFIDelate set null;", errno.ErrWrongFKOptionForGeneratedDeferredCauset)
  2970  	tk.MustInterDirc("drop causet t1, t2;")
  2971  
  2972  	// special case: MilevaDB error different from MyALLEGROSQL 8.0
  2973  	// MyALLEGROSQL: ERROR 3104 (HY000): Cannot define foreign key with ON UFIDelATE SET NULL clause on a generated defCausumn.
  2974  	// MilevaDB:  ERROR 1146 (42S02): Block 'test.t2' doesn't exist
  2975  	tk.MustInterDirc("create causet t1 (a int, b int generated always as (a+1) stored);")
  2976  	tk.MustGetErrCode("alter causet t1 add foreign key (b) references t2(a) on uFIDelate set null;", errno.ErrNoSuchBlock)
  2977  	tk.MustInterDirc("drop causet t1;")
  2978  
  2979  	// allowed FK options on stored generated defCausumns
  2980  	tk.MustInterDirc("create causet t1 (a int primary key, b char(5));")
  2981  	tk.MustInterDirc("create causet t2 (a int, b int generated always as (a % 10) stored, foreign key (b) references t1(a) on uFIDelate restrict);")
  2982  	tk.MustInterDirc("create causet t3 (a int, b int generated always as (a % 10) stored, foreign key (b) references t1(a) on uFIDelate no action);")
  2983  	tk.MustInterDirc("create causet t4 (a int, b int generated always as (a % 10) stored, foreign key (b) references t1(a) on delete restrict);")
  2984  	tk.MustInterDirc("create causet t5 (a int, b int generated always as (a % 10) stored, foreign key (b) references t1(a) on delete cascade);")
  2985  	tk.MustInterDirc("create causet t6 (a int, b int generated always as (a % 10) stored, foreign key (b) references t1(a) on delete no action);")
  2986  	tk.MustInterDirc("drop causet t2,t3,t4,t5,t6;")
  2987  	tk.MustInterDirc("create causet t2 (a int, b int generated always as (a % 10) stored);")
  2988  	tk.MustInterDirc("alter causet t2 add foreign key (b) references t1(a) on uFIDelate restrict;")
  2989  	tk.MustInterDirc("create causet t3 (a int, b int generated always as (a % 10) stored);")
  2990  	tk.MustInterDirc("alter causet t3 add foreign key (b) references t1(a) on uFIDelate no action;")
  2991  	tk.MustInterDirc("create causet t4 (a int, b int generated always as (a % 10) stored);")
  2992  	tk.MustInterDirc("alter causet t4 add foreign key (b) references t1(a) on delete restrict;")
  2993  	tk.MustInterDirc("create causet t5 (a int, b int generated always as (a % 10) stored);")
  2994  	tk.MustInterDirc("alter causet t5 add foreign key (b) references t1(a) on delete cascade;")
  2995  	tk.MustInterDirc("create causet t6 (a int, b int generated always as (a % 10) stored);")
  2996  	tk.MustInterDirc("alter causet t6 add foreign key (b) references t1(a) on delete no action;")
  2997  	tk.MustInterDirc("drop causet t1,t2,t3,t4,t5,t6;")
  2998  
  2999  	// rejected FK options on the base defCausumns of a stored generated defCausumns
  3000  	tk.MustInterDirc("create causet t2 (a int primary key);")
  3001  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on uFIDelate set null);", errno.ErrCannotAddForeign)
  3002  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on uFIDelate cascade);", errno.ErrCannotAddForeign)
  3003  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on uFIDelate set default);", errno.ErrCannotAddForeign)
  3004  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on delete set null);", errno.ErrCannotAddForeign)
  3005  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on delete cascade);", errno.ErrCannotAddForeign)
  3006  	tk.MustGetErrCode("create causet t1 (a int, b int generated always as (a+1) stored, foreign key (a) references t2(a) on delete set default);", errno.ErrCannotAddForeign)
  3007  	tk.MustInterDirc("create causet t1 (a int, b int generated always as (a+1) stored);")
  3008  	tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on uFIDelate set null;", errno.ErrCannotAddForeign)
  3009  	tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on uFIDelate cascade;", errno.ErrCannotAddForeign)
  3010  	tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on uFIDelate set default;", errno.ErrCannotAddForeign)
  3011  	tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on delete set null;", errno.ErrCannotAddForeign)
  3012  	tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on delete cascade;", errno.ErrCannotAddForeign)
  3013  	tk.MustGetErrCode("alter causet t1 add foreign key (a) references t2(a) on delete set default;", errno.ErrCannotAddForeign)
  3014  	tk.MustInterDirc("drop causet t1, t2;")
  3015  
  3016  	// allowed FK options on the base defCausumns of a stored generated defCausumns
  3017  	tk.MustInterDirc("create causet t1 (a int primary key, b char(5));")
  3018  	tk.MustInterDirc("create causet t2 (a int, b int generated always as (a % 10) stored, foreign key (a) references t1(a) on uFIDelate restrict);")
  3019  	tk.MustInterDirc("create causet t3 (a int, b int generated always as (a % 10) stored, foreign key (a) references t1(a) on uFIDelate no action);")
  3020  	tk.MustInterDirc("create causet t4 (a int, b int generated always as (a % 10) stored, foreign key (a) references t1(a) on delete restrict);")
  3021  	tk.MustInterDirc("create causet t5 (a int, b int generated always as (a % 10) stored, foreign key (a) references t1(a) on delete no action);")
  3022  	tk.MustInterDirc("drop causet t2,t3,t4,t5")
  3023  	tk.MustInterDirc("create causet t2 (a int, b int generated always as (a % 10) stored);")
  3024  	tk.MustInterDirc("alter causet t2 add foreign key (a) references t1(a) on uFIDelate restrict;")
  3025  	tk.MustInterDirc("create causet t3 (a int, b int generated always as (a % 10) stored);")
  3026  	tk.MustInterDirc("alter causet t3 add foreign key (a) references t1(a) on uFIDelate no action;")
  3027  	tk.MustInterDirc("create causet t4 (a int, b int generated always as (a % 10) stored);")
  3028  	tk.MustInterDirc("alter causet t4 add foreign key (a) references t1(a) on delete restrict;")
  3029  	tk.MustInterDirc("create causet t5 (a int, b int generated always as (a % 10) stored);")
  3030  	tk.MustInterDirc("alter causet t5 add foreign key (a) references t1(a) on delete no action;")
  3031  	tk.MustInterDirc("drop causet t1,t2,t3,t4,t5;")
  3032  }
  3033  
  3034  func (s *testSerialDBSuite) TestTruncateBlock(c *C) {
  3035  	tk := testkit.NewTestKit(c, s.causetstore)
  3036  	tk.MustInterDirc("use test")
  3037  	tk.MustInterDirc("create causet truncate_block (c1 int, c2 int)")
  3038  	tk.MustInterDirc("insert truncate_block values (1, 1), (2, 2)")
  3039  	ctx := tk.Se.(stochastikctx.Context)
  3040  	is := petri.GetPetri(ctx).SchemaReplicant()
  3041  	oldTblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("truncate_block"))
  3042  	c.Assert(err, IsNil)
  3043  	oldTblID := oldTblInfo.Meta().ID
  3044  
  3045  	tk.MustInterDirc("truncate causet truncate_block")
  3046  
  3047  	tk.MustInterDirc("insert truncate_block values (3, 3), (4, 4)")
  3048  	tk.MustQuery("select * from truncate_block").Check(testkit.Rows("3 3", "4 4"))
  3049  
  3050  	is = petri.GetPetri(ctx).SchemaReplicant()
  3051  	newTblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("truncate_block"))
  3052  	c.Assert(err, IsNil)
  3053  	c.Assert(newTblInfo.Meta().ID, Greater, oldTblID)
  3054  
  3055  	// Verify that the old causet data has been deleted by background worker.
  3056  	blockPrefix := blockcodec.EncodeBlockPrefix(oldTblID)
  3057  	hasOldBlockData := true
  3058  	for i := 0; i < waitForCleanDataRound; i++ {
  3059  		err = ekv.RunInNewTxn(s.causetstore, false, func(txn ekv.Transaction) error {
  3060  			it, err1 := txn.Iter(blockPrefix, nil)
  3061  			if err1 != nil {
  3062  				return err1
  3063  			}
  3064  			if !it.Valid() {
  3065  				hasOldBlockData = false
  3066  			} else {
  3067  				hasOldBlockData = it.Key().HasPrefix(blockPrefix)
  3068  			}
  3069  			it.Close()
  3070  			return nil
  3071  		})
  3072  		c.Assert(err, IsNil)
  3073  		if !hasOldBlockData {
  3074  			break
  3075  		}
  3076  		time.Sleep(waitForCleanDataInterval)
  3077  	}
  3078  	c.Assert(hasOldBlockData, IsFalse)
  3079  
  3080  	// Test for truncate causet should clear the tiflash available status.
  3081  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil)
  3082  	defer failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount")
  3083  
  3084  	tk.MustInterDirc("drop causet if exists t1;")
  3085  	tk.MustInterDirc("create causet t1 (a int);")
  3086  	tk.MustInterDirc("alter causet t1 set tiflash replica 3 location labels 'a','b';")
  3087  	t1 := testGetBlockByName(c, s.s, "test", "t1")
  3088  	// Mock for causet tiflash replica was available.
  3089  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, t1.Meta().ID, true)
  3090  	c.Assert(err, IsNil)
  3091  	t1 = testGetBlockByName(c, s.s, "test", "t1")
  3092  	c.Assert(t1.Meta().TiFlashReplica, NotNil)
  3093  	c.Assert(t1.Meta().TiFlashReplica.Available, IsTrue)
  3094  
  3095  	tk.MustInterDirc("truncate causet t1")
  3096  	t2 := testGetBlockByName(c, s.s, "test", "t1")
  3097  	c.Assert(t2.Meta().TiFlashReplica.Count, Equals, t1.Meta().TiFlashReplica.Count)
  3098  	c.Assert(t2.Meta().TiFlashReplica.LocationLabels, DeepEquals, t1.Meta().TiFlashReplica.LocationLabels)
  3099  	c.Assert(t2.Meta().TiFlashReplica.Available, IsFalse)
  3100  	c.Assert(t2.Meta().TiFlashReplica.AvailablePartitionIDs, HasLen, 0)
  3101  
  3102  	// Test for truncate partition should clear the tiflash available status.
  3103  	tk.MustInterDirc("drop causet if exists t1;")
  3104  	tk.MustInterDirc("create causet t1 (a int) partition by hash(a) partitions 2;")
  3105  	tk.MustInterDirc("alter causet t1 set tiflash replica 3 location labels 'a','b';")
  3106  	t1 = testGetBlockByName(c, s.s, "test", "t1")
  3107  	// Mock for all partitions replica was available.
  3108  	partition := t1.Meta().Partition
  3109  	c.Assert(len(partition.Definitions), Equals, 2)
  3110  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true)
  3111  	c.Assert(err, IsNil)
  3112  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[1].ID, true)
  3113  	c.Assert(err, IsNil)
  3114  	t1 = testGetBlockByName(c, s.s, "test", "t1")
  3115  	c.Assert(t1.Meta().TiFlashReplica, NotNil)
  3116  	c.Assert(t1.Meta().TiFlashReplica.Available, IsTrue)
  3117  	c.Assert(t1.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID, partition.Definitions[1].ID})
  3118  
  3119  	tk.MustInterDirc("alter causet t1 truncate partition p0")
  3120  	t2 = testGetBlockByName(c, s.s, "test", "t1")
  3121  	c.Assert(t2.Meta().TiFlashReplica.Count, Equals, t1.Meta().TiFlashReplica.Count)
  3122  	c.Assert(t2.Meta().TiFlashReplica.LocationLabels, DeepEquals, t1.Meta().TiFlashReplica.LocationLabels)
  3123  	c.Assert(t2.Meta().TiFlashReplica.Available, IsFalse)
  3124  	c.Assert(t2.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[1].ID})
  3125  	// Test for truncate twice.
  3126  	tk.MustInterDirc("alter causet t1 truncate partition p0")
  3127  	t2 = testGetBlockByName(c, s.s, "test", "t1")
  3128  	c.Assert(t2.Meta().TiFlashReplica.Count, Equals, t1.Meta().TiFlashReplica.Count)
  3129  	c.Assert(t2.Meta().TiFlashReplica.LocationLabels, DeepEquals, t1.Meta().TiFlashReplica.LocationLabels)
  3130  	c.Assert(t2.Meta().TiFlashReplica.Available, IsFalse)
  3131  	c.Assert(t2.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[1].ID})
  3132  
  3133  }
  3134  
  3135  func (s *testDBSuite4) TestRenameBlock(c *C) {
  3136  	isAlterBlock := false
  3137  	s.testRenameBlock(c, "rename causet %s to %s", isAlterBlock)
  3138  }
  3139  
  3140  func (s *testDBSuite5) TestAlterBlockRenameBlock(c *C) {
  3141  	isAlterBlock := true
  3142  	s.testRenameBlock(c, "alter causet %s rename to %s", isAlterBlock)
  3143  }
  3144  
  3145  func (s *testDBSuite) testRenameBlock(c *C, allegrosql string, isAlterBlock bool) {
  3146  	tk := testkit.NewTestKit(c, s.causetstore)
  3147  	tk.MustInterDirc("use test")
  3148  	// for different databases
  3149  	tk.MustInterDirc("create causet t (c1 int, c2 int)")
  3150  	tk.MustInterDirc("insert t values (1, 1), (2, 2)")
  3151  	ctx := tk.Se.(stochastikctx.Context)
  3152  	is := petri.GetPetri(ctx).SchemaReplicant()
  3153  	oldTblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t"))
  3154  	c.Assert(err, IsNil)
  3155  	oldTblID := oldTblInfo.Meta().ID
  3156  	tk.MustInterDirc("create database test1")
  3157  	tk.MustInterDirc("use test1")
  3158  	tk.MustInterDirc(fmt.Sprintf(allegrosql, "test.t", "test1.t1"))
  3159  	is = petri.GetPetri(ctx).SchemaReplicant()
  3160  	newTblInfo, err := is.BlockByName(perceptron.NewCIStr("test1"), perceptron.NewCIStr("t1"))
  3161  	c.Assert(err, IsNil)
  3162  	c.Assert(newTblInfo.Meta().ID, Equals, oldTblID)
  3163  	tk.MustQuery("select * from t1").Check(testkit.Rows("1 1", "2 2"))
  3164  	tk.MustInterDirc("use test")
  3165  
  3166  	// Make sure t doesn't exist.
  3167  	tk.MustInterDirc("create causet t (c1 int, c2 int)")
  3168  	tk.MustInterDirc("drop causet t")
  3169  
  3170  	// for the same database
  3171  	tk.MustInterDirc("use test1")
  3172  	tk.MustInterDirc(fmt.Sprintf(allegrosql, "t1", "t2"))
  3173  	is = petri.GetPetri(ctx).SchemaReplicant()
  3174  	newTblInfo, err = is.BlockByName(perceptron.NewCIStr("test1"), perceptron.NewCIStr("t2"))
  3175  	c.Assert(err, IsNil)
  3176  	c.Assert(newTblInfo.Meta().ID, Equals, oldTblID)
  3177  	tk.MustQuery("select * from t2").Check(testkit.Rows("1 1", "2 2"))
  3178  	isExist := is.BlockExists(perceptron.NewCIStr("test1"), perceptron.NewCIStr("t1"))
  3179  	c.Assert(isExist, IsFalse)
  3180  	tk.MustQuery("show blocks").Check(testkit.Rows("t2"))
  3181  
  3182  	// for failure case
  3183  	failALLEGROSQL := fmt.Sprintf(allegrosql, "test_not_exist.t", "test_not_exist.t")
  3184  	if isAlterBlock {
  3185  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock)
  3186  	} else {
  3187  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrFileNotFound)
  3188  	}
  3189  	failALLEGROSQL = fmt.Sprintf(allegrosql, "test.test_not_exist", "test.test_not_exist")
  3190  	if isAlterBlock {
  3191  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock)
  3192  	} else {
  3193  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrFileNotFound)
  3194  	}
  3195  	failALLEGROSQL = fmt.Sprintf(allegrosql, "test.t_not_exist", "test_not_exist.t")
  3196  	if isAlterBlock {
  3197  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock)
  3198  	} else {
  3199  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrFileNotFound)
  3200  	}
  3201  	failALLEGROSQL = fmt.Sprintf(allegrosql, "test1.t2", "test_not_exist.t")
  3202  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrErrorOnRename)
  3203  
  3204  	tk.MustInterDirc("use test1")
  3205  	tk.MustInterDirc("create causet if not exists t_exist (c1 int, c2 int)")
  3206  	failALLEGROSQL = fmt.Sprintf(allegrosql, "test1.t2", "test1.t_exist")
  3207  	tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockExists)
  3208  	failALLEGROSQL = fmt.Sprintf(allegrosql, "test.t_not_exist", "test1.t_exist")
  3209  	if isAlterBlock {
  3210  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock)
  3211  	} else {
  3212  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockExists)
  3213  	}
  3214  	failALLEGROSQL = fmt.Sprintf(allegrosql, "test_not_exist.t", "test1.t_exist")
  3215  	if isAlterBlock {
  3216  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock)
  3217  	} else {
  3218  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrBlockExists)
  3219  	}
  3220  	failALLEGROSQL = fmt.Sprintf(allegrosql, "test_not_exist.t", "test1.t_not_exist")
  3221  	if isAlterBlock {
  3222  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrNoSuchBlock)
  3223  	} else {
  3224  		tk.MustGetErrCode(failALLEGROSQL, errno.ErrFileNotFound)
  3225  	}
  3226  
  3227  	// for the same causet name
  3228  	tk.MustInterDirc("use test1")
  3229  	tk.MustInterDirc("create causet if not exists t (c1 int, c2 int)")
  3230  	tk.MustInterDirc("create causet if not exists t1 (c1 int, c2 int)")
  3231  	if isAlterBlock {
  3232  		tk.MustInterDirc(fmt.Sprintf(allegrosql, "test1.t", "t"))
  3233  		tk.MustInterDirc(fmt.Sprintf(allegrosql, "test1.t1", "test1.T1"))
  3234  	} else {
  3235  		tk.MustGetErrCode(fmt.Sprintf(allegrosql, "test1.t", "t"), errno.ErrBlockExists)
  3236  		tk.MustGetErrCode(fmt.Sprintf(allegrosql, "test1.t1", "test1.T1"), errno.ErrBlockExists)
  3237  	}
  3238  
  3239  	// Test rename causet name too long.
  3240  	tk.MustGetErrCode("rename causet test1.t1 to test1.txxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", errno.ErrTooLongIdent)
  3241  	tk.MustGetErrCode("alter  causet test1.t1 rename to test1.txxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", errno.ErrTooLongIdent)
  3242  
  3243  	tk.MustInterDirc("drop database test1")
  3244  }
  3245  
  3246  func (s *testDBSuite1) TestRenameMultiBlocks(c *C) {
  3247  	tk := testkit.NewTestKit(c, s.causetstore)
  3248  	tk.MustInterDirc("use test")
  3249  	tk.MustInterDirc("create causet t1(id int)")
  3250  	tk.MustInterDirc("create causet t2(id int)")
  3251  	// Currently it will fail only.
  3252  	allegrosql := fmt.Sprintf("rename causet t1 to t3, t2 to t4")
  3253  	_, err := tk.InterDirc(allegrosql)
  3254  	c.Assert(err, NotNil)
  3255  	originErr := errors.Cause(err)
  3256  	c.Assert(originErr.Error(), Equals, "can't run multi schemaReplicant change")
  3257  
  3258  	tk.MustInterDirc("drop causet t1, t2")
  3259  }
  3260  
  3261  func (s *testDBSuite2) TestAddNotNullDeferredCauset(c *C) {
  3262  	tk := testkit.NewTestKit(c, s.causetstore)
  3263  	tk.MustInterDirc("use test_db")
  3264  	// for different databases
  3265  	tk.MustInterDirc("create causet tnn (c1 int primary key auto_increment, c2 int)")
  3266  	tk.MustInterDirc("insert tnn (c2) values (0)" + strings.Repeat(",(0)", 99))
  3267  	done := make(chan error, 1)
  3268  	testdbsutil.StochastikInterDircInGoroutine(c, s.causetstore, "alter causet tnn add defCausumn c3 int not null default 3", done)
  3269  	uFIDelateCnt := 0
  3270  out:
  3271  	for {
  3272  		select {
  3273  		case err := <-done:
  3274  			c.Assert(err, IsNil)
  3275  			break out
  3276  		default:
  3277  			tk.MustInterDirc("uFIDelate tnn set c2 = c2 + 1 where c1 = 99")
  3278  			uFIDelateCnt++
  3279  		}
  3280  	}
  3281  	expected := fmt.Sprintf("%d %d", uFIDelateCnt, 3)
  3282  	tk.MustQuery("select c2, c3 from tnn where c1 = 99").Check(testkit.Rows(expected))
  3283  
  3284  	tk.MustInterDirc("drop causet tnn")
  3285  }
  3286  
  3287  func (s *testDBSuite3) TestGeneratedDeferredCausetDBS(c *C) {
  3288  	tk := testkit.NewTestKit(c, s.causetstore)
  3289  	tk.MustInterDirc("use test")
  3290  
  3291  	// Check create causet with virtual and stored generated defCausumns.
  3292  	tk.MustInterDirc(`CREATE TABLE test_gv_dbs(a int, b int as (a+8) virtual, c int as (b + 2) stored)`)
  3293  
  3294  	// Check desc causet with virtual and stored generated defCausumns.
  3295  	result := tk.MustQuery(`DESC test_gv_dbs`)
  3296  	result.Check(testkit.Rows(`a int(11) YES  <nil> `, `b int(11) YES  <nil> VIRTUAL GENERATED`, `c int(11) YES  <nil> STORED GENERATED`))
  3297  
  3298  	// Check show create causet with virtual and stored generated defCausumns.
  3299  	result = tk.MustQuery(`show create causet test_gv_dbs`)
  3300  	result.Check(testkit.Rows(
  3301  		"test_gv_dbs CREATE TABLE `test_gv_dbs` (\n  `a` int(11) DEFAULT NULL,\n  `b` int(11) GENERATED ALWAYS AS (`a` + 8) VIRTUAL,\n  `c` int(11) GENERATED ALWAYS AS (`b` + 2) STORED\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
  3302  	))
  3303  
  3304  	// Check generated memex with blanks.
  3305  	tk.MustInterDirc("create causet block_with_gen_defCaus_blanks (a int, b char(20) as (cast( \r\n\t a \r\n\tas  char)), c int as (a+100))")
  3306  	result = tk.MustQuery(`show create causet block_with_gen_defCaus_blanks`)
  3307  	result.Check(testkit.Rows("block_with_gen_defCaus_blanks CREATE TABLE `block_with_gen_defCaus_blanks` (\n" +
  3308  		"  `a` int(11) DEFAULT NULL,\n" +
  3309  		"  `b` char(20) GENERATED ALWAYS AS (cast(`a` as char)) VIRTUAL,\n" +
  3310  		"  `c` int(11) GENERATED ALWAYS AS (`a` + 100) VIRTUAL\n" +
  3311  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  3312  
  3313  	// Check generated memex with charset latin1 ("latin1" != allegrosql.DefaultCharset).
  3314  	tk.MustInterDirc("create causet block_with_gen_defCaus_latin1 (a int, b char(20) as (cast( \r\n\t a \r\n\tas  char charset latin1)), c int as (a+100))")
  3315  	result = tk.MustQuery(`show create causet block_with_gen_defCaus_latin1`)
  3316  	result.Check(testkit.Rows("block_with_gen_defCaus_latin1 CREATE TABLE `block_with_gen_defCaus_latin1` (\n" +
  3317  		"  `a` int(11) DEFAULT NULL,\n" +
  3318  		"  `b` char(20) GENERATED ALWAYS AS (cast(`a` as char charset latin1)) VIRTUAL,\n" +
  3319  		"  `c` int(11) GENERATED ALWAYS AS (`a` + 100) VIRTUAL\n" +
  3320  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  3321  
  3322  	// Check generated memex with string (issue 9457).
  3323  	tk.MustInterDirc("create causet block_with_gen_defCaus_string (first_name varchar(10), last_name varchar(10), full_name varchar(255) AS (CONCAT(first_name,' ',last_name)))")
  3324  	result = tk.MustQuery(`show create causet block_with_gen_defCaus_string`)
  3325  	result.Check(testkit.Rows("block_with_gen_defCaus_string CREATE TABLE `block_with_gen_defCaus_string` (\n" +
  3326  		"  `first_name` varchar(10) DEFAULT NULL,\n" +
  3327  		"  `last_name` varchar(10) DEFAULT NULL,\n" +
  3328  		"  `full_name` varchar(255) GENERATED ALWAYS AS (concat(`first_name`, ' ', `last_name`)) VIRTUAL\n" +
  3329  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  3330  
  3331  	tk.MustInterDirc("alter causet block_with_gen_defCaus_string modify defCausumn full_name varchar(255) GENERATED ALWAYS AS (CONCAT(last_name,' ' ,first_name) ) VIRTUAL")
  3332  	result = tk.MustQuery(`show create causet block_with_gen_defCaus_string`)
  3333  	result.Check(testkit.Rows("block_with_gen_defCaus_string CREATE TABLE `block_with_gen_defCaus_string` (\n" +
  3334  		"  `first_name` varchar(10) DEFAULT NULL,\n" +
  3335  		"  `last_name` varchar(10) DEFAULT NULL,\n" +
  3336  		"  `full_name` varchar(255) GENERATED ALWAYS AS (concat(`last_name`, ' ', `first_name`)) VIRTUAL\n" +
  3337  		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  3338  
  3339  	genExprTests := []struct {
  3340  		stmt string
  3341  		err  int
  3342  	}{
  3343  		// Drop/rename defCausumns dependent by other defCausumn.
  3344  		{`alter causet test_gv_dbs drop defCausumn a`, errno.ErrDependentByGeneratedDeferredCauset},
  3345  		{`alter causet test_gv_dbs change defCausumn a anew int`, errno.ErrBadField},
  3346  
  3347  		// Modify/change stored status of generated defCausumns.
  3348  		{`alter causet test_gv_dbs modify defCausumn b bigint`, errno.ErrUnsupportedOnGeneratedDeferredCauset},
  3349  		{`alter causet test_gv_dbs change defCausumn c cnew bigint as (a+100)`, errno.ErrUnsupportedOnGeneratedDeferredCauset},
  3350  
  3351  		// Modify/change generated defCausumns breaking prior.
  3352  		{`alter causet test_gv_dbs modify defCausumn b int as (c+100)`, errno.ErrGeneratedDeferredCausetNonPrior},
  3353  		{`alter causet test_gv_dbs change defCausumn b bnew int as (c+100)`, errno.ErrGeneratedDeferredCausetNonPrior},
  3354  
  3355  		// Refer not exist defCausumns in generation memex.
  3356  		{`create causet test_gv_dbs_bad (a int, b int as (c+8))`, errno.ErrBadField},
  3357  
  3358  		// Refer generated defCausumns non prior.
  3359  		{`create causet test_gv_dbs_bad (a int, b int as (c+1), c int as (a+1))`, errno.ErrGeneratedDeferredCausetNonPrior},
  3360  
  3361  		// Virtual generated defCausumns cannot be primary key.
  3362  		{`create causet test_gv_dbs_bad (a int, b int, c int as (a+b) primary key)`, errno.ErrUnsupportedOnGeneratedDeferredCauset},
  3363  		{`create causet test_gv_dbs_bad (a int, b int, c int as (a+b), primary key(c))`, errno.ErrUnsupportedOnGeneratedDeferredCauset},
  3364  		{`create causet test_gv_dbs_bad (a int, b int, c int as (a+b), primary key(a, c))`, errno.ErrUnsupportedOnGeneratedDeferredCauset},
  3365  
  3366  		// Add stored generated defCausumn through alter causet.
  3367  		{`alter causet test_gv_dbs add defCausumn d int as (b+2) stored`, errno.ErrUnsupportedOnGeneratedDeferredCauset},
  3368  		{`alter causet test_gv_dbs modify defCausumn b int as (a + 8) stored`, errno.ErrUnsupportedOnGeneratedDeferredCauset},
  3369  	}
  3370  	for _, tt := range genExprTests {
  3371  		tk.MustGetErrCode(tt.stmt, tt.err)
  3372  	}
  3373  
  3374  	// Check alter causet modify/change generated defCausumn.
  3375  	modStoredDefCausErrMsg := "[dbs:3106]'modifying a stored defCausumn' is not supported for generated defCausumns."
  3376  	_, err := tk.InterDirc(`alter causet test_gv_dbs modify defCausumn c bigint as (b+200) stored`)
  3377  	c.Assert(err, NotNil)
  3378  	c.Assert(err.Error(), Equals, modStoredDefCausErrMsg)
  3379  
  3380  	result = tk.MustQuery(`DESC test_gv_dbs`)
  3381  	result.Check(testkit.Rows(`a int(11) YES  <nil> `, `b int(11) YES  <nil> VIRTUAL GENERATED`, `c int(11) YES  <nil> STORED GENERATED`))
  3382  
  3383  	tk.MustInterDirc(`alter causet test_gv_dbs change defCausumn b b bigint as (a+100) virtual`)
  3384  	result = tk.MustQuery(`DESC test_gv_dbs`)
  3385  	result.Check(testkit.Rows(`a int(11) YES  <nil> `, `b bigint(20) YES  <nil> VIRTUAL GENERATED`, `c int(11) YES  <nil> STORED GENERATED`))
  3386  
  3387  	tk.MustInterDirc(`alter causet test_gv_dbs change defCausumn c cnew bigint`)
  3388  	result = tk.MustQuery(`DESC test_gv_dbs`)
  3389  	result.Check(testkit.Rows(`a int(11) YES  <nil> `, `b bigint(20) YES  <nil> VIRTUAL GENERATED`, `cnew bigint(20) YES  <nil> `))
  3390  }
  3391  
  3392  func (s *testDBSuite4) TestComment(c *C) {
  3393  	tk := testkit.NewTestKit(c, s.causetstore)
  3394  	tk.MustInterDirc("use " + s.schemaName)
  3395  	tk.MustInterDirc("drop causet if exists ct, ct1")
  3396  
  3397  	validComment := strings.Repeat("a", 1024)
  3398  	invalidComment := strings.Repeat("b", 1025)
  3399  
  3400  	tk.MustInterDirc("create causet ct (c int, d int, e int, key (c) comment '" + validComment + "')")
  3401  	tk.MustInterDirc("create index i on ct (d) comment '" + validComment + "'")
  3402  	tk.MustInterDirc("alter causet ct add key (e) comment '" + validComment + "'")
  3403  
  3404  	tk.MustGetErrCode("create causet ct1 (c int, key (c) comment '"+invalidComment+"')", errno.ErrTooLongIndexComment)
  3405  	tk.MustGetErrCode("create index i1 on ct (d) comment '"+invalidComment+"b"+"'", errno.ErrTooLongIndexComment)
  3406  	tk.MustGetErrCode("alter causet ct add key (e) comment '"+invalidComment+"'", errno.ErrTooLongIndexComment)
  3407  
  3408  	tk.MustInterDirc("set @@sql_mode=''")
  3409  	tk.MustInterDirc("create causet ct1 (c int, d int, e int, key (c) comment '" + invalidComment + "')")
  3410  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  3411  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|1688|Comment for index 'c' is too long (max = 1024)"))
  3412  	tk.MustInterDirc("create index i1 on ct1 (d) comment '" + invalidComment + "b" + "'")
  3413  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  3414  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|1688|Comment for index 'i1' is too long (max = 1024)"))
  3415  	tk.MustInterDirc("alter causet ct1 add key (e) comment '" + invalidComment + "'")
  3416  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  3417  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|1688|Comment for index 'e' is too long (max = 1024)"))
  3418  
  3419  	tk.MustInterDirc("drop causet if exists ct, ct1")
  3420  }
  3421  
  3422  func (s *testSerialDBSuite) TestRebaseAutoID(c *C) {
  3423  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/spacetime/autoid/mockAutoIDChange", `return(true)`), IsNil)
  3424  	defer func() {
  3425  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/spacetime/autoid/mockAutoIDChange"), IsNil)
  3426  	}()
  3427  	tk := testkit.NewTestKit(c, s.causetstore)
  3428  	tk.MustInterDirc("use " + s.schemaName)
  3429  
  3430  	tk.MustInterDirc("drop database if exists milevadb;")
  3431  	tk.MustInterDirc("create database milevadb;")
  3432  	tk.MustInterDirc("use milevadb;")
  3433  	tk.MustInterDirc("create causet milevadb.test (a int auto_increment primary key, b int);")
  3434  	tk.MustInterDirc("insert milevadb.test values (null, 1);")
  3435  	tk.MustQuery("select * from milevadb.test").Check(testkit.Rows("1 1"))
  3436  	tk.MustInterDirc("alter causet milevadb.test auto_increment = 6000;")
  3437  	tk.MustInterDirc("insert milevadb.test values (null, 1);")
  3438  	tk.MustQuery("select * from milevadb.test").Check(testkit.Rows("1 1", "6000 1"))
  3439  	tk.MustInterDirc("alter causet milevadb.test auto_increment = 5;")
  3440  	tk.MustInterDirc("insert milevadb.test values (null, 1);")
  3441  	tk.MustQuery("select * from milevadb.test").Check(testkit.Rows("1 1", "6000 1", "11000 1"))
  3442  
  3443  	// Current range for causet test is [11000, 15999].
  3444  	// Though it does not have a tuple "a = 15999", its global next auto increment id should be 16000.
  3445  	// Anyway it is not compatible with MyALLEGROSQL.
  3446  	tk.MustInterDirc("alter causet milevadb.test auto_increment = 12000;")
  3447  	tk.MustInterDirc("insert milevadb.test values (null, 1);")
  3448  	tk.MustQuery("select * from milevadb.test").Check(testkit.Rows("1 1", "6000 1", "11000 1", "16000 1"))
  3449  
  3450  	tk.MustInterDirc("create causet milevadb.test2 (a int);")
  3451  	tk.MustGetErrCode("alter causet milevadb.test2 add defCausumn b int auto_increment key, auto_increment=10;", errno.ErrUnsupportedDBSOperation)
  3452  }
  3453  
  3454  func (s *testDBSuite5) TestCheckDeferredCausetDefaultValue(c *C) {
  3455  	tk := testkit.NewTestKit(c, s.causetstore)
  3456  	tk.MustInterDirc("use test;")
  3457  	tk.MustInterDirc("drop causet if exists text_default_text;")
  3458  	tk.MustGetErrCode("create causet text_default_text(c1 text not null default '');", errno.ErrBlobCantHaveDefault)
  3459  	tk.MustGetErrCode("create causet text_default_text(c1 text not null default 'scds');", errno.ErrBlobCantHaveDefault)
  3460  
  3461  	tk.MustInterDirc("drop causet if exists text_default_json;")
  3462  	tk.MustGetErrCode("create causet text_default_json(c1 json not null default '');", errno.ErrBlobCantHaveDefault)
  3463  	tk.MustGetErrCode("create causet text_default_json(c1 json not null default 'dfew555');", errno.ErrBlobCantHaveDefault)
  3464  
  3465  	tk.MustInterDirc("drop causet if exists text_default_blob;")
  3466  	tk.MustGetErrCode("create causet text_default_blob(c1 blob not null default '');", errno.ErrBlobCantHaveDefault)
  3467  	tk.MustGetErrCode("create causet text_default_blob(c1 blob not null default 'scds54');", errno.ErrBlobCantHaveDefault)
  3468  
  3469  	tk.MustInterDirc("set sql_mode='';")
  3470  	tk.MustInterDirc("create causet text_default_text(c1 text not null default '');")
  3471  	tk.MustQuery(`show create causet text_default_text`).Check(solitonutil.RowsWithSep("|",
  3472  		"text_default_text CREATE TABLE `text_default_text` (\n"+
  3473  			"  `c1` text NOT NULL\n"+
  3474  			") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
  3475  	))
  3476  	ctx := tk.Se.(stochastikctx.Context)
  3477  	is := petri.GetPetri(ctx).SchemaReplicant()
  3478  	tblInfo, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("text_default_text"))
  3479  	c.Assert(err, IsNil)
  3480  	c.Assert(tblInfo.Meta().DeferredCausets[0].DefaultValue, Equals, "")
  3481  
  3482  	tk.MustInterDirc("create causet text_default_blob(c1 blob not null default '');")
  3483  	tk.MustQuery(`show create causet text_default_blob`).Check(solitonutil.RowsWithSep("|",
  3484  		"text_default_blob CREATE TABLE `text_default_blob` (\n"+
  3485  			"  `c1` blob NOT NULL\n"+
  3486  			") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
  3487  	))
  3488  	is = petri.GetPetri(ctx).SchemaReplicant()
  3489  	tblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("text_default_blob"))
  3490  	c.Assert(err, IsNil)
  3491  	c.Assert(tblInfo.Meta().DeferredCausets[0].DefaultValue, Equals, "")
  3492  
  3493  	tk.MustInterDirc("create causet text_default_json(c1 json not null default '');")
  3494  	tk.MustQuery(`show create causet text_default_json`).Check(solitonutil.RowsWithSep("|",
  3495  		"text_default_json CREATE TABLE `text_default_json` (\n"+
  3496  			"  `c1` json NOT NULL DEFAULT 'null'\n"+
  3497  			") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
  3498  	))
  3499  	is = petri.GetPetri(ctx).SchemaReplicant()
  3500  	tblInfo, err = is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("text_default_json"))
  3501  	c.Assert(err, IsNil)
  3502  	c.Assert(tblInfo.Meta().DeferredCausets[0].DefaultValue, Equals, `null`)
  3503  }
  3504  
  3505  func (s *testDBSuite1) TestCharacterSetInDeferredCausets(c *C) {
  3506  	tk := testkit.NewTestKit(c, s.causetstore)
  3507  	tk.MustInterDirc("create database varchar_test;")
  3508  	defer tk.MustInterDirc("drop database varchar_test;")
  3509  	tk.MustInterDirc("use varchar_test")
  3510  	tk.MustInterDirc("create causet t (c1 int, s1 varchar(10), s2 text)")
  3511  	tk.MustQuery("select count(*) from information_schema.defCausumns where block_schema = 'varchar_test' and character_set_name != 'utf8mb4'").Check(testkit.Rows("0"))
  3512  	tk.MustQuery("select count(*) from information_schema.defCausumns where block_schema = 'varchar_test' and character_set_name = 'utf8mb4'").Check(testkit.Rows("2"))
  3513  
  3514  	tk.MustInterDirc("create causet t1(id int) charset=UTF8;")
  3515  	tk.MustInterDirc("create causet t2(id int) charset=BINARY;")
  3516  	tk.MustInterDirc("create causet t3(id int) charset=LATIN1;")
  3517  	tk.MustInterDirc("create causet t4(id int) charset=ASCII;")
  3518  	tk.MustInterDirc("create causet t5(id int) charset=UTF8MB4;")
  3519  
  3520  	tk.MustInterDirc("create causet t11(id int) charset=utf8;")
  3521  	tk.MustInterDirc("create causet t12(id int) charset=binary;")
  3522  	tk.MustInterDirc("create causet t13(id int) charset=latin1;")
  3523  	tk.MustInterDirc("create causet t14(id int) charset=ascii;")
  3524  	tk.MustInterDirc("create causet t15(id int) charset=utf8mb4;")
  3525  }
  3526  
  3527  func (s *testDBSuite2) TestAddNotNullDeferredCausetWhileInsertOnDupUFIDelate(c *C) {
  3528  	tk1 := testkit.NewTestKit(c, s.causetstore)
  3529  	tk1.MustInterDirc("use " + s.schemaName)
  3530  	tk2 := testkit.NewTestKit(c, s.causetstore)
  3531  	tk2.MustInterDirc("use " + s.schemaName)
  3532  	closeCh := make(chan bool)
  3533  	wg := new(sync.WaitGroup)
  3534  	wg.Add(1)
  3535  	tk1.MustInterDirc("create causet nn (a int primary key, b int)")
  3536  	tk1.MustInterDirc("insert nn values (1, 1)")
  3537  	var tk2Err error
  3538  	go func() {
  3539  		defer wg.Done()
  3540  		for {
  3541  			select {
  3542  			case <-closeCh:
  3543  				return
  3544  			default:
  3545  			}
  3546  			_, tk2Err = tk2.InterDirc("insert nn (a, b) values (1, 1) on duplicate key uFIDelate a = 1, b = values(b) + 1")
  3547  			if tk2Err != nil {
  3548  				return
  3549  			}
  3550  		}
  3551  	}()
  3552  	tk1.MustInterDirc("alter causet nn add defCausumn c int not null default 3 after a")
  3553  	close(closeCh)
  3554  	wg.Wait()
  3555  	c.Assert(tk2Err, IsNil)
  3556  	tk1.MustQuery("select * from nn").Check(testkit.Rows("1 3 2"))
  3557  }
  3558  
  3559  func (s *testDBSuite3) TestDeferredCausetModifyingDefinition(c *C) {
  3560  	tk := testkit.NewTestKit(c, s.causetstore)
  3561  	tk.MustInterDirc("use test")
  3562  	tk.MustInterDirc("drop causet if exists test2;")
  3563  	tk.MustInterDirc("create causet test2 (c1 int, c2 int, c3 int default 1, index (c1));")
  3564  	tk.MustInterDirc("alter causet test2 change c2 a int not null;")
  3565  	ctx := tk.Se.(stochastikctx.Context)
  3566  	is := petri.GetPetri(ctx).SchemaReplicant()
  3567  	t, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("test2"))
  3568  	c.Assert(err, IsNil)
  3569  	var c2 *causet.DeferredCauset
  3570  	for _, defCaus := range t.DefCauss() {
  3571  		if defCaus.Name.L == "a" {
  3572  			c2 = defCaus
  3573  		}
  3574  	}
  3575  	c.Assert(allegrosql.HasNotNullFlag(c2.Flag), IsTrue)
  3576  
  3577  	tk.MustInterDirc("drop causet if exists test2;")
  3578  	tk.MustInterDirc("create causet test2 (c1 int, c2 int, c3 int default 1, index (c1));")
  3579  	tk.MustInterDirc("insert into test2(c2) values (null);")
  3580  	tk.MustGetErrCode("alter causet test2 change c2 a int not null", errno.ErrInvalidUseOfNull)
  3581  	tk.MustGetErrCode("alter causet test2 change c1 a1 bigint not null;", allegrosql.WarnDataTruncated)
  3582  }
  3583  
  3584  func (s *testDBSuite4) TestCheckTooBigFieldLength(c *C) {
  3585  	tk := testkit.NewTestKit(c, s.causetstore)
  3586  	tk.MustInterDirc("use test")
  3587  	tk.MustInterDirc("drop causet if exists tr_01;")
  3588  	tk.MustInterDirc("create causet tr_01 (id int, name varchar(20000), purchased date )  default charset=utf8 defCauslate=utf8_bin;")
  3589  
  3590  	tk.MustInterDirc("drop causet if exists tr_02;")
  3591  	tk.MustInterDirc("create causet tr_02 (id int, name varchar(16000), purchased date )  default charset=utf8mb4 defCauslate=utf8mb4_bin;")
  3592  
  3593  	tk.MustInterDirc("drop causet if exists tr_03;")
  3594  	tk.MustInterDirc("create causet tr_03 (id int, name varchar(65534), purchased date ) default charset=latin1;")
  3595  
  3596  	tk.MustInterDirc("drop causet if exists tr_04;")
  3597  	tk.MustInterDirc("create causet tr_04 (a varchar(20000) ) default charset utf8;")
  3598  	tk.MustGetErrCode("alter causet tr_04 add defCausumn b varchar(20000) charset utf8mb4;", errno.ErrTooBigFieldlength)
  3599  	tk.MustGetErrCode("alter causet tr_04 convert to character set utf8mb4;", errno.ErrTooBigFieldlength)
  3600  	tk.MustGetErrCode("create causet tr (id int, name varchar(30000), purchased date )  default charset=utf8 defCauslate=utf8_bin;", errno.ErrTooBigFieldlength)
  3601  	tk.MustGetErrCode("create causet tr (id int, name varchar(20000) charset utf8mb4, purchased date ) default charset=utf8 defCauslate=utf8_bin;", errno.ErrTooBigFieldlength)
  3602  	tk.MustGetErrCode("create causet tr (id int, name varchar(65536), purchased date ) default charset=latin1;", errno.ErrTooBigFieldlength)
  3603  
  3604  	tk.MustInterDirc("drop causet if exists tr_05;")
  3605  	tk.MustInterDirc("create causet tr_05 (a varchar(16000) charset utf8);")
  3606  	tk.MustInterDirc("alter causet tr_05 modify defCausumn a varchar(16000) charset utf8;")
  3607  	tk.MustInterDirc("alter causet tr_05 modify defCausumn a varchar(16000) charset utf8mb4;")
  3608  }
  3609  
  3610  func (s *testDBSuite5) TestCheckConvertToCharacter(c *C) {
  3611  	tk := testkit.NewTestKit(c, s.causetstore)
  3612  	tk.MustInterDirc("use test")
  3613  	tk.MustInterDirc("drop causet if exists t")
  3614  	defer tk.MustInterDirc("drop causet t")
  3615  	tk.MustInterDirc("create causet t(a varchar(10) charset binary);")
  3616  	ctx := tk.Se.(stochastikctx.Context)
  3617  	is := petri.GetPetri(ctx).SchemaReplicant()
  3618  	t, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t"))
  3619  	c.Assert(err, IsNil)
  3620  	tk.MustGetErrCode("alter causet t modify defCausumn a varchar(10) charset utf8 defCauslate utf8_bin", errno.ErrUnsupportedDBSOperation)
  3621  	tk.MustGetErrCode("alter causet t modify defCausumn a varchar(10) charset utf8mb4 defCauslate utf8mb4_bin", errno.ErrUnsupportedDBSOperation)
  3622  	tk.MustGetErrCode("alter causet t modify defCausumn a varchar(10) charset latin1 defCauslate latin1_bin", errno.ErrUnsupportedDBSOperation)
  3623  	c.Assert(t.DefCauss()[0].Charset, Equals, "binary")
  3624  }
  3625  
  3626  func (s *testDBSuite5) TestModifyDeferredCausetRollBack(c *C) {
  3627  	tk := testkit.NewTestKit(c, s.causetstore)
  3628  	s.mustInterDirc(tk, c, "use test_db")
  3629  	s.mustInterDirc(tk, c, "drop causet if exists t1")
  3630  	s.mustInterDirc(tk, c, "create causet t1 (c1 int, c2 int, c3 int default 1, index (c1));")
  3631  
  3632  	var c2 *causet.DeferredCauset
  3633  	var checkErr error
  3634  	hook := &dbs.TestDBSCallback{}
  3635  	hook.OnJobUFIDelatedExported = func(job *perceptron.Job) {
  3636  		if checkErr != nil {
  3637  			return
  3638  		}
  3639  
  3640  		t := s.testGetBlock(c, "t1")
  3641  		for _, defCaus := range t.DefCauss() {
  3642  			if defCaus.Name.L == "c2" {
  3643  				c2 = defCaus
  3644  			}
  3645  		}
  3646  		if allegrosql.HasPreventNullInsertFlag(c2.Flag) {
  3647  			tk.MustGetErrCode("insert into t1(c2) values (null);", errno.ErrBadNull)
  3648  		}
  3649  
  3650  		hookCtx := mock.NewContext()
  3651  		hookCtx.CausetStore = s.causetstore
  3652  		err := hookCtx.NewTxn(context.Background())
  3653  		if err != nil {
  3654  			checkErr = errors.Trace(err)
  3655  			return
  3656  		}
  3657  
  3658  		jobIDs := []int64{job.ID}
  3659  		txn, err := hookCtx.Txn(true)
  3660  		if err != nil {
  3661  			checkErr = errors.Trace(err)
  3662  			return
  3663  		}
  3664  		errs, err := admin.CancelJobs(txn, jobIDs)
  3665  		if err != nil {
  3666  			checkErr = errors.Trace(err)
  3667  			return
  3668  		}
  3669  		// It only tests cancel one DBS job.
  3670  		if errs[0] != nil {
  3671  			checkErr = errors.Trace(errs[0])
  3672  			return
  3673  		}
  3674  
  3675  		txn, err = hookCtx.Txn(true)
  3676  		if err != nil {
  3677  			checkErr = errors.Trace(err)
  3678  			return
  3679  		}
  3680  		err = txn.Commit(context.Background())
  3681  		if err != nil {
  3682  			checkErr = errors.Trace(err)
  3683  		}
  3684  	}
  3685  
  3686  	originalHook := s.dom.DBS().GetHook()
  3687  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  3688  	done := make(chan error, 1)
  3689  	go backgroundInterDirc(s.causetstore, "alter causet t1 change c2 c2 bigint not null;", done)
  3690  
  3691  	err := <-done
  3692  	c.Assert(err, NotNil)
  3693  	c.Assert(err.Error(), Equals, "[dbs:8214]Cancelled DBS job")
  3694  	s.mustInterDirc(tk, c, "insert into t1(c2) values (null);")
  3695  
  3696  	t := s.testGetBlock(c, "t1")
  3697  	for _, defCaus := range t.DefCauss() {
  3698  		if defCaus.Name.L == "c2" {
  3699  			c2 = defCaus
  3700  		}
  3701  	}
  3702  	c.Assert(allegrosql.HasNotNullFlag(c2.Flag), IsFalse)
  3703  	s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
  3704  	s.mustInterDirc(tk, c, "drop causet t1")
  3705  }
  3706  
  3707  func (s *testSerialDBSuite) TestModifyDeferredCausetNullToNotNullWithChangingVal2(c *C) {
  3708  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
  3709  
  3710  	enableChangeDeferredCausetType := tk.Se.GetStochastikVars().EnableChangeDeferredCausetType
  3711  	tk.Se.GetStochastikVars().EnableChangeDeferredCausetType = true
  3712  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/dbs/mockInsertValueAfterCheckNull", `return("insert into test.tt values (NULL, NULL)")`), IsNil)
  3713  	defer func() {
  3714  		tk.Se.GetStochastikVars().EnableChangeDeferredCausetType = enableChangeDeferredCausetType
  3715  		failpoint.Disable("github.com/whtcorpsinc/milevadb/dbs/mockInsertValueAfterCheckNull")
  3716  	}()
  3717  
  3718  	tk.MustInterDirc(`create causet tt (a bigint, b int, unique index idx(a));`)
  3719  	tk.MustInterDirc("insert into tt values (1,1),(2,2),(3,3);")
  3720  	_, err := tk.InterDirc("alter causet tt modify a int not null;")
  3721  	c.Assert(err.Error(), Equals, "[dbs:1265]Data truncated for defCausumn 'a' at event 1")
  3722  	tk.MustInterDirc("drop causet tt")
  3723  }
  3724  
  3725  func (s *testDBSuite1) TestModifyDeferredCausetNullToNotNull(c *C) {
  3726  	sql1 := "alter causet t1 change c2 c2 int not null;"
  3727  	sql2 := "alter causet t1 change c2 c2 int not null;"
  3728  	testModifyDeferredCausetNullToNotNull(c, s.testDBSuite, false, sql1, sql2)
  3729  }
  3730  
  3731  func (s *testSerialDBSuite) TestModifyDeferredCausetNullToNotNullWithChangingVal(c *C) {
  3732  	sql1 := "alter causet t1 change c2 c2 tinyint not null;"
  3733  	sql2 := "alter causet t1 change c2 c2 tinyint not null;"
  3734  	testModifyDeferredCausetNullToNotNull(c, s.testDBSuite, true, sql1, sql2)
  3735  	c2 := getModifyDeferredCauset(c, s.s.(stochastikctx.Context), s.schemaName, "t1", "c2", false)
  3736  	c.Assert(c2.FieldType.Tp, Equals, allegrosql.TypeTiny)
  3737  }
  3738  
  3739  func getModifyDeferredCauset(c *C, ctx stochastikctx.Context, EDB, tbl, defCausName string, allDeferredCauset bool) *causet.DeferredCauset {
  3740  	t := testGetBlockByName(c, ctx, EDB, tbl)
  3741  	defCausName = strings.ToLower(defCausName)
  3742  	var defcaus []*causet.DeferredCauset
  3743  	if allDeferredCauset {
  3744  		defcaus = t.(*blocks.BlockCommon).DeferredCausets
  3745  	} else {
  3746  		defcaus = t.DefCauss()
  3747  	}
  3748  	for _, defCaus := range defcaus {
  3749  		if defCaus.Name.L == defCausName {
  3750  			return defCaus
  3751  		}
  3752  	}
  3753  	return nil
  3754  }
  3755  
  3756  func testModifyDeferredCausetNullToNotNull(c *C, s *testDBSuite, enableChangeDeferredCausetType bool, sql1, sql2 string) {
  3757  	tk := testkit.NewTestKit(c, s.causetstore)
  3758  	tk2 := testkit.NewTestKit(c, s.causetstore)
  3759  	tk2.MustInterDirc("use test_db")
  3760  	s.mustInterDirc(tk, c, "use test_db")
  3761  	s.mustInterDirc(tk, c, "drop causet if exists t1")
  3762  	s.mustInterDirc(tk, c, "create causet t1 (c1 int, c2 int);")
  3763  
  3764  	if enableChangeDeferredCausetType {
  3765  		enableChangeDeferredCausetType := tk.Se.GetStochastikVars().EnableChangeDeferredCausetType
  3766  		tk.Se.GetStochastikVars().EnableChangeDeferredCausetType = true
  3767  		defer func() {
  3768  			tk.Se.GetStochastikVars().EnableChangeDeferredCausetType = enableChangeDeferredCausetType
  3769  		}()
  3770  	}
  3771  
  3772  	tbl := s.testGetBlock(c, "t1")
  3773  	getModifyDeferredCauset(c, s.s.(stochastikctx.Context), s.schemaName, "t1", "c2", false)
  3774  
  3775  	originalHook := s.dom.DBS().GetHook()
  3776  	defer s.dom.DBS().(dbs.DBSForTest).SetHook(originalHook)
  3777  
  3778  	// Check insert null before job first uFIDelate.
  3779  	times := 0
  3780  	hook := &dbs.TestDBSCallback{}
  3781  	tk.MustInterDirc("delete from t1")
  3782  	var checkErr error
  3783  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  3784  		if tbl.Meta().ID != job.BlockID {
  3785  			return
  3786  		}
  3787  		if times == 0 {
  3788  			_, checkErr = tk2.InterDirc("insert into t1 values ();")
  3789  		}
  3790  		times++
  3791  	}
  3792  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  3793  	_, err := tk.InterDirc(sql1)
  3794  	c.Assert(checkErr, IsNil)
  3795  	c.Assert(err, NotNil)
  3796  	if enableChangeDeferredCausetType {
  3797  		c.Assert(err.Error(), Equals, "[dbs:1265]Data truncated for defCausumn 'c2' at event 1")
  3798  	} else {
  3799  		c.Assert(err.Error(), Equals, "[dbs:1138]Invalid use of NULL value")
  3800  	}
  3801  	tk.MustQuery("select * from t1").Check(testkit.Rows("<nil> <nil>"))
  3802  
  3803  	// Check insert error when defCausumn has PreventNullInsertFlag.
  3804  	tk.MustInterDirc("delete from t1")
  3805  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  3806  		if tbl.Meta().ID != job.BlockID {
  3807  			return
  3808  		}
  3809  		if job.State != perceptron.JobStateRunning {
  3810  			return
  3811  		}
  3812  		// now c2 has PreventNullInsertFlag, an error is expected.
  3813  		_, checkErr = tk2.InterDirc("insert into t1 values ();")
  3814  	}
  3815  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  3816  	tk.MustInterDirc(sql2)
  3817  	c.Assert(checkErr.Error(), Equals, "[causet:1048]DeferredCauset 'c2' cannot be null")
  3818  
  3819  	c2 := getModifyDeferredCauset(c, s.s.(stochastikctx.Context), s.schemaName, "t1", "c2", false)
  3820  	c.Assert(allegrosql.HasNotNullFlag(c2.Flag), IsTrue)
  3821  	c.Assert(allegrosql.HasPreventNullInsertFlag(c2.Flag), IsFalse)
  3822  	_, err = tk.InterDirc("insert into t1 values ();")
  3823  	c.Assert(err, NotNil)
  3824  	c.Assert(err.Error(), Equals, "[causet:1364]Field 'c2' doesn't have a default value")
  3825  }
  3826  
  3827  func (s *testDBSuite2) TestTransactionOnAddDropDeferredCauset(c *C) {
  3828  	tk := testkit.NewTestKit(c, s.causetstore)
  3829  	s.mustInterDirc(tk, c, "use test_db")
  3830  	s.mustInterDirc(tk, c, "drop causet if exists t1")
  3831  	s.mustInterDirc(tk, c, "create causet t1 (a int, b int);")
  3832  	s.mustInterDirc(tk, c, "create causet t2 (a int, b int);")
  3833  	s.mustInterDirc(tk, c, "insert into t2 values (2,0)")
  3834  
  3835  	transactions := [][]string{
  3836  		{
  3837  			"begin",
  3838  			"insert into t1 set a=1",
  3839  			"uFIDelate t1 set b=1 where a=1",
  3840  			"commit",
  3841  		},
  3842  		{
  3843  			"begin",
  3844  			"insert into t1 select a,b from t2",
  3845  			"uFIDelate t1 set b=2 where a=2",
  3846  			"commit",
  3847  		},
  3848  	}
  3849  
  3850  	originHook := s.dom.DBS().GetHook()
  3851  	defer s.dom.DBS().(dbs.DBSForTest).SetHook(originHook)
  3852  	hook := &dbs.TestDBSCallback{}
  3853  	var checkErr error
  3854  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  3855  		if checkErr != nil {
  3856  			return
  3857  		}
  3858  		switch job.SchemaState {
  3859  		case perceptron.StateWriteOnly, perceptron.StateWriteReorganization, perceptron.StateDeleteOnly, perceptron.StateDeleteReorganization:
  3860  		default:
  3861  			return
  3862  		}
  3863  		// do transaction.
  3864  		for _, transaction := range transactions {
  3865  			for _, allegrosql := range transaction {
  3866  				if _, checkErr = tk.InterDirc(allegrosql); checkErr != nil {
  3867  					checkErr = errors.Errorf("err: %s, allegrosql: %s, job schemaReplicant state: %s", checkErr.Error(), allegrosql, job.SchemaState)
  3868  					return
  3869  				}
  3870  			}
  3871  		}
  3872  	}
  3873  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  3874  	done := make(chan error, 1)
  3875  	// test transaction on add defCausumn.
  3876  	go backgroundInterDirc(s.causetstore, "alter causet t1 add defCausumn c int not null after a", done)
  3877  	err := <-done
  3878  	c.Assert(err, IsNil)
  3879  	c.Assert(checkErr, IsNil)
  3880  	tk.MustQuery("select a,b from t1 order by a").Check(testkit.Rows("1 1", "1 1", "1 1", "2 2", "2 2", "2 2"))
  3881  	s.mustInterDirc(tk, c, "delete from t1")
  3882  
  3883  	// test transaction on drop defCausumn.
  3884  	go backgroundInterDirc(s.causetstore, "alter causet t1 drop defCausumn c", done)
  3885  	err = <-done
  3886  	c.Assert(err, IsNil)
  3887  	c.Assert(checkErr, IsNil)
  3888  	tk.MustQuery("select a,b from t1 order by a").Check(testkit.Rows("1 1", "1 1", "1 1", "2 2", "2 2", "2 2"))
  3889  }
  3890  
  3891  func (s *testDBSuite3) TestTransactionWithWriteOnlyDeferredCauset(c *C) {
  3892  	tk := testkit.NewTestKit(c, s.causetstore)
  3893  	s.mustInterDirc(tk, c, "use test_db")
  3894  	s.mustInterDirc(tk, c, "drop causet if exists t1")
  3895  	s.mustInterDirc(tk, c, "create causet t1 (a int key);")
  3896  
  3897  	transactions := [][]string{
  3898  		{
  3899  			"begin",
  3900  			"insert into t1 set a=1",
  3901  			"uFIDelate t1 set a=2 where a=1",
  3902  			"commit",
  3903  		},
  3904  	}
  3905  
  3906  	originHook := s.dom.DBS().GetHook()
  3907  	defer s.dom.DBS().(dbs.DBSForTest).SetHook(originHook)
  3908  	hook := &dbs.TestDBSCallback{}
  3909  	var checkErr error
  3910  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  3911  		if checkErr != nil {
  3912  			return
  3913  		}
  3914  		switch job.SchemaState {
  3915  		case perceptron.StateWriteOnly:
  3916  		default:
  3917  			return
  3918  		}
  3919  		// do transaction.
  3920  		for _, transaction := range transactions {
  3921  			for _, allegrosql := range transaction {
  3922  				if _, checkErr = tk.InterDirc(allegrosql); checkErr != nil {
  3923  					checkErr = errors.Errorf("err: %s, allegrosql: %s, job schemaReplicant state: %s", checkErr.Error(), allegrosql, job.SchemaState)
  3924  					return
  3925  				}
  3926  			}
  3927  		}
  3928  	}
  3929  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  3930  	done := make(chan error, 1)
  3931  	// test transaction on add defCausumn.
  3932  	go backgroundInterDirc(s.causetstore, "alter causet t1 add defCausumn c int not null", done)
  3933  	err := <-done
  3934  	c.Assert(err, IsNil)
  3935  	c.Assert(checkErr, IsNil)
  3936  	tk.MustQuery("select a from t1").Check(testkit.Rows("2"))
  3937  	s.mustInterDirc(tk, c, "delete from t1")
  3938  
  3939  	// test transaction on drop defCausumn.
  3940  	go backgroundInterDirc(s.causetstore, "alter causet t1 drop defCausumn c", done)
  3941  	err = <-done
  3942  	c.Assert(err, IsNil)
  3943  	c.Assert(checkErr, IsNil)
  3944  	tk.MustQuery("select a from t1").Check(testkit.Rows("2"))
  3945  }
  3946  
  3947  func (s *testDBSuite4) TestAddDeferredCauset2(c *C) {
  3948  	tk := testkit.NewTestKit(c, s.causetstore)
  3949  	s.mustInterDirc(tk, c, "use test_db")
  3950  	s.mustInterDirc(tk, c, "drop causet if exists t1")
  3951  	s.mustInterDirc(tk, c, "create causet t1 (a int key, b int);")
  3952  	defer s.mustInterDirc(tk, c, "drop causet if exists t1, t2")
  3953  
  3954  	originHook := s.dom.DBS().GetHook()
  3955  	defer s.dom.DBS().(dbs.DBSForTest).SetHook(originHook)
  3956  	hook := &dbs.TestDBSCallback{}
  3957  	var writeOnlyBlock causet.Block
  3958  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  3959  		if job.SchemaState == perceptron.StateWriteOnly {
  3960  			writeOnlyBlock, _ = s.dom.SchemaReplicant().BlockByID(job.BlockID)
  3961  		}
  3962  	}
  3963  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  3964  	done := make(chan error, 1)
  3965  	// test transaction on add defCausumn.
  3966  	go backgroundInterDirc(s.causetstore, "alter causet t1 add defCausumn c int not null", done)
  3967  	err := <-done
  3968  	c.Assert(err, IsNil)
  3969  
  3970  	s.mustInterDirc(tk, c, "insert into t1 values (1,1,1)")
  3971  	tk.MustQuery("select a,b,c from t1").Check(testkit.Rows("1 1 1"))
  3972  
  3973  	// mock for outdated milevadb uFIDelate record.
  3974  	c.Assert(writeOnlyBlock, NotNil)
  3975  	ctx := context.Background()
  3976  	err = tk.Se.NewTxn(ctx)
  3977  	c.Assert(err, IsNil)
  3978  	oldRow, err := writeOnlyBlock.RowWithDefCauss(tk.Se, ekv.IntHandle(1), writeOnlyBlock.WriblockDefCauss())
  3979  	c.Assert(err, IsNil)
  3980  	c.Assert(len(oldRow), Equals, 3)
  3981  	err = writeOnlyBlock.RemoveRecord(tk.Se, ekv.IntHandle(1), oldRow)
  3982  	c.Assert(err, IsNil)
  3983  	_, err = writeOnlyBlock.AddRecord(tk.Se, types.MakeCausets(oldRow[0].GetInt64(), 2, oldRow[2].GetInt64()), causet.IsUFIDelate)
  3984  	c.Assert(err, IsNil)
  3985  	tk.Se.StmtCommit()
  3986  	err = tk.Se.CommitTxn(ctx)
  3987  	c.Assert(err, IsNil)
  3988  
  3989  	tk.MustQuery("select a,b,c from t1").Check(testkit.Rows("1 2 1"))
  3990  
  3991  	// Test for _milevadb_rowid
  3992  	var re *testkit.Result
  3993  	s.mustInterDirc(tk, c, "create causet t2 (a int);")
  3994  	hook.OnJobRunBeforeExported = func(job *perceptron.Job) {
  3995  		if job.SchemaState != perceptron.StateWriteOnly {
  3996  			return
  3997  		}
  3998  		// allow write _milevadb_rowid first
  3999  		s.mustInterDirc(tk, c, "set @@milevadb_opt_write_row_id=1")
  4000  		s.mustInterDirc(tk, c, "begin")
  4001  		s.mustInterDirc(tk, c, "insert into t2 (a,_milevadb_rowid) values (1,2);")
  4002  		re = tk.MustQuery(" select a,_milevadb_rowid from t2;")
  4003  		s.mustInterDirc(tk, c, "commit")
  4004  
  4005  	}
  4006  	s.dom.DBS().(dbs.DBSForTest).SetHook(hook)
  4007  
  4008  	go backgroundInterDirc(s.causetstore, "alter causet t2 add defCausumn b int not null default 3", done)
  4009  	err = <-done
  4010  	c.Assert(err, IsNil)
  4011  	re.Check(testkit.Rows("1 2"))
  4012  	tk.MustQuery("select a,b,_milevadb_rowid from t2").Check(testkit.Rows("1 3 2"))
  4013  }
  4014  
  4015  func (s *testDBSuite4) TestIfNotExists(c *C) {
  4016  	tk := testkit.NewTestKit(c, s.causetstore)
  4017  	tk.MustInterDirc("use test_db")
  4018  	s.mustInterDirc(tk, c, "drop causet if exists t1")
  4019  	s.mustInterDirc(tk, c, "create causet t1 (a int key);")
  4020  
  4021  	// ADD COLUMN
  4022  	allegrosql := "alter causet t1 add defCausumn b int"
  4023  	s.mustInterDirc(tk, c, allegrosql)
  4024  	tk.MustGetErrCode(allegrosql, errno.ErrDupFieldName)
  4025  	s.mustInterDirc(tk, c, "alter causet t1 add defCausumn if not exists b int")
  4026  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  4027  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1060|Duplicate defCausumn name 'b'"))
  4028  
  4029  	// ADD INDEX
  4030  	allegrosql = "alter causet t1 add index idx_b (b)"
  4031  	s.mustInterDirc(tk, c, allegrosql)
  4032  	tk.MustGetErrCode(allegrosql, errno.ErrDupKeyName)
  4033  	s.mustInterDirc(tk, c, "alter causet t1 add index if not exists idx_b (b)")
  4034  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  4035  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1061|index already exist idx_b"))
  4036  
  4037  	// CREATE INDEX
  4038  	allegrosql = "create index idx_b on t1 (b)"
  4039  	tk.MustGetErrCode(allegrosql, errno.ErrDupKeyName)
  4040  	s.mustInterDirc(tk, c, "create index if not exists idx_b on t1 (b)")
  4041  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  4042  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1061|index already exist idx_b"))
  4043  
  4044  	// ADD PARTITION
  4045  	s.mustInterDirc(tk, c, "drop causet if exists t2")
  4046  	s.mustInterDirc(tk, c, "create causet t2 (a int key) partition by range(a) (partition p0 values less than (10), partition p1 values less than (20))")
  4047  	allegrosql = "alter causet t2 add partition (partition p2 values less than (30))"
  4048  	s.mustInterDirc(tk, c, allegrosql)
  4049  	tk.MustGetErrCode(allegrosql, errno.ErrSameNamePartition)
  4050  	s.mustInterDirc(tk, c, "alter causet t2 add partition if not exists (partition p2 values less than (30))")
  4051  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  4052  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1517|Duplicate partition name p2"))
  4053  }
  4054  
  4055  func (s *testDBSuite4) TestIfExists(c *C) {
  4056  	tk := testkit.NewTestKit(c, s.causetstore)
  4057  	tk.MustInterDirc("use test_db")
  4058  	s.mustInterDirc(tk, c, "drop causet if exists t1")
  4059  	s.mustInterDirc(tk, c, "create causet t1 (a int key, b int);")
  4060  
  4061  	// DROP COLUMN
  4062  	allegrosql := "alter causet t1 drop defCausumn b"
  4063  	s.mustInterDirc(tk, c, allegrosql)
  4064  	tk.MustGetErrCode(allegrosql, errno.ErrCantDropFieldOrKey)
  4065  	s.mustInterDirc(tk, c, "alter causet t1 drop defCausumn if exists b") // only `a` exists now
  4066  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  4067  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1091|defCausumn b doesn't exist"))
  4068  
  4069  	// CHANGE COLUMN
  4070  	allegrosql = "alter causet t1 change defCausumn b c int"
  4071  	tk.MustGetErrCode(allegrosql, errno.ErrBadField)
  4072  	s.mustInterDirc(tk, c, "alter causet t1 change defCausumn if exists b c int")
  4073  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  4074  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1054|Unknown defCausumn 'b' in 't1'"))
  4075  	s.mustInterDirc(tk, c, "alter causet t1 change defCausumn if exists a c int") // only `c` exists now
  4076  
  4077  	// MODIFY COLUMN
  4078  	allegrosql = "alter causet t1 modify defCausumn a bigint"
  4079  	tk.MustGetErrCode(allegrosql, errno.ErrBadField)
  4080  	s.mustInterDirc(tk, c, "alter causet t1 modify defCausumn if exists a bigint")
  4081  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  4082  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1054|Unknown defCausumn 'a' in 't1'"))
  4083  	s.mustInterDirc(tk, c, "alter causet t1 modify defCausumn if exists c bigint") // only `c` exists now
  4084  
  4085  	// DROP INDEX
  4086  	s.mustInterDirc(tk, c, "alter causet t1 add index idx_c (c)")
  4087  	allegrosql = "alter causet t1 drop index idx_c"
  4088  	s.mustInterDirc(tk, c, allegrosql)
  4089  	tk.MustGetErrCode(allegrosql, errno.ErrCantDropFieldOrKey)
  4090  	s.mustInterDirc(tk, c, "alter causet t1 drop index if exists idx_c")
  4091  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  4092  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1091|index idx_c doesn't exist"))
  4093  
  4094  	// DROP PARTITION
  4095  	s.mustInterDirc(tk, c, "drop causet if exists t2")
  4096  	s.mustInterDirc(tk, c, "create causet t2 (a int key) partition by range(a) (partition p0 values less than (10), partition p1 values less than (20))")
  4097  	allegrosql = "alter causet t2 drop partition p1"
  4098  	s.mustInterDirc(tk, c, allegrosql)
  4099  	tk.MustGetErrCode(allegrosql, errno.ErrDropPartitionNonExistent)
  4100  	s.mustInterDirc(tk, c, "alter causet t2 drop partition if exists p1")
  4101  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  4102  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Note|1507|Error in list of partitions to p1"))
  4103  }
  4104  
  4105  func testAddIndexForGeneratedDeferredCauset(tk *testkit.TestKit, s *testSerialDBSuite, c *C) {
  4106  	tk.MustInterDirc("use test_db")
  4107  	tk.MustInterDirc("drop causet if exists t")
  4108  	tk.MustInterDirc("create causet t(y year NOT NULL DEFAULT '2155')")
  4109  	defer s.mustInterDirc(tk, c, "drop causet t;")
  4110  	for i := 0; i < 50; i++ {
  4111  		s.mustInterDirc(tk, c, "insert into t values (?)", i)
  4112  	}
  4113  	tk.MustInterDirc("insert into t values()")
  4114  	tk.MustInterDirc("ALTER TABLE t ADD COLUMN y1 year as (y + 2)")
  4115  	_, err := tk.InterDirc("ALTER TABLE t ADD INDEX idx_y(y1)")
  4116  	c.Assert(err, IsNil)
  4117  
  4118  	t := s.testGetBlock(c, "t")
  4119  	for _, idx := range t.Indices() {
  4120  		c.Assert(strings.EqualFold(idx.Meta().Name.L, "idx_c2"), IsFalse)
  4121  	}
  4122  	// NOTE: this test case contains a bug, it should be uncommented after the bug is fixed.
  4123  	// TODO: Fix bug https://github.com/whtcorpsinc/milevadb/issues/12181
  4124  	//s.mustInterDirc(c, "delete from t where y = 2155")
  4125  	//s.mustInterDirc(c, "alter causet t add index idx_y(y1)")
  4126  	//s.mustInterDirc(c, "alter causet t drop index idx_y")
  4127  
  4128  	// Fix issue 9311.
  4129  	tk.MustInterDirc("drop causet if exists gcai_block")
  4130  	tk.MustInterDirc("create causet gcai_block (id int primary key);")
  4131  	tk.MustInterDirc("insert into gcai_block values(1);")
  4132  	tk.MustInterDirc("ALTER TABLE gcai_block ADD COLUMN d date DEFAULT '9999-12-31';")
  4133  	tk.MustInterDirc("ALTER TABLE gcai_block ADD COLUMN d1 date as (DATE_SUB(d, INTERVAL 31 DAY));")
  4134  	tk.MustInterDirc("ALTER TABLE gcai_block ADD INDEX idx(d1);")
  4135  	tk.MustQuery("select * from gcai_block").Check(testkit.Rows("1 9999-12-31 9999-11-30"))
  4136  	tk.MustQuery("select d1 from gcai_block use index(idx)").Check(testkit.Rows("9999-11-30"))
  4137  	tk.MustInterDirc("admin check causet gcai_block")
  4138  	// The defCausumn is PKIsHandle in generated defCausumn memex.
  4139  	tk.MustInterDirc("ALTER TABLE gcai_block ADD COLUMN id1 int as (id+5);")
  4140  	tk.MustInterDirc("ALTER TABLE gcai_block ADD INDEX idx1(id1);")
  4141  	tk.MustQuery("select * from gcai_block").Check(testkit.Rows("1 9999-12-31 9999-11-30 6"))
  4142  	tk.MustQuery("select id1 from gcai_block use index(idx1)").Check(testkit.Rows("6"))
  4143  	tk.MustInterDirc("admin check causet gcai_block")
  4144  }
  4145  func (s *testSerialDBSuite) TestAddIndexForGeneratedDeferredCauset(c *C) {
  4146  	tk := testkit.NewTestKit(c, s.causetstore)
  4147  	defer config.RestoreFunc()()
  4148  	config.UFIDelateGlobal(func(conf *config.Config) {
  4149  		conf.AlterPrimaryKey = false
  4150  	})
  4151  
  4152  	testAddIndexForGeneratedDeferredCauset(tk, s, c)
  4153  	tk.MustInterDirc("set @@milevadb_enable_clustered_index = 1;")
  4154  	testAddIndexForGeneratedDeferredCauset(tk, s, c)
  4155  }
  4156  
  4157  func (s *testDBSuite5) TestModifyGeneratedDeferredCauset(c *C) {
  4158  	tk := testkit.NewTestKit(c, s.causetstore)
  4159  	tk.MustInterDirc("create database if not exists test;")
  4160  	tk.MustInterDirc("use test")
  4161  	modIdxDefCausErrMsg := "[dbs:3106]'modifying an indexed defCausumn' is not supported for generated defCausumns."
  4162  	modStoredDefCausErrMsg := "[dbs:3106]'modifying a stored defCausumn' is not supported for generated defCausumns."
  4163  
  4164  	// Modify defCausumn with single-defCaus-index.
  4165  	tk.MustInterDirc("drop causet if exists t1;")
  4166  	tk.MustInterDirc("create causet t1 (a int, b int as (a+1), index idx(b));")
  4167  	tk.MustInterDirc("insert into t1 set a=1;")
  4168  	_, err := tk.InterDirc("alter causet t1 modify defCausumn b int as (a+2);")
  4169  	c.Assert(err, NotNil)
  4170  	c.Assert(err.Error(), Equals, modIdxDefCausErrMsg)
  4171  	tk.MustInterDirc("drop index idx on t1;")
  4172  	tk.MustInterDirc("alter causet t1 modify b int as (a+2);")
  4173  	tk.MustQuery("select * from t1").Check(testkit.Rows("1 3"))
  4174  
  4175  	// Modify defCausumn with multi-defCaus-index.
  4176  	tk.MustInterDirc("drop causet t1;")
  4177  	tk.MustInterDirc("create causet t1 (a int, b int as (a+1), index idx(a, b));")
  4178  	tk.MustInterDirc("insert into t1 set a=1;")
  4179  	_, err = tk.InterDirc("alter causet t1 modify defCausumn b int as (a+2);")
  4180  	c.Assert(err, NotNil)
  4181  	c.Assert(err.Error(), Equals, modIdxDefCausErrMsg)
  4182  	tk.MustInterDirc("drop index idx on t1;")
  4183  	tk.MustInterDirc("alter causet t1 modify b int as (a+2);")
  4184  	tk.MustQuery("select * from t1").Check(testkit.Rows("1 3"))
  4185  
  4186  	// Modify defCausumn with stored status to a different memex.
  4187  	tk.MustInterDirc("drop causet t1;")
  4188  	tk.MustInterDirc("create causet t1 (a int, b int as (a+1) stored);")
  4189  	tk.MustInterDirc("insert into t1 set a=1;")
  4190  	_, err = tk.InterDirc("alter causet t1 modify defCausumn b int as (a+2) stored;")
  4191  	c.Assert(err, NotNil)
  4192  	c.Assert(err.Error(), Equals, modStoredDefCausErrMsg)
  4193  
  4194  	// Modify defCausumn with stored status to the same memex.
  4195  	tk.MustInterDirc("drop causet t1;")
  4196  	tk.MustInterDirc("create causet t1 (a int, b int as (a+1) stored);")
  4197  	tk.MustInterDirc("insert into t1 set a=1;")
  4198  	tk.MustInterDirc("alter causet t1 modify defCausumn b bigint as (a+1) stored;")
  4199  	tk.MustInterDirc("alter causet t1 modify defCausumn b bigint as (a + 1) stored;")
  4200  	tk.MustQuery("select * from t1").Check(testkit.Rows("1 2"))
  4201  
  4202  	// Modify defCausumn with index to the same memex.
  4203  	tk.MustInterDirc("drop causet t1;")
  4204  	tk.MustInterDirc("create causet t1 (a int, b int as (a+1), index idx(b));")
  4205  	tk.MustInterDirc("insert into t1 set a=1;")
  4206  	tk.MustInterDirc("alter causet t1 modify defCausumn b bigint as (a+1);")
  4207  	tk.MustInterDirc("alter causet t1 modify defCausumn b bigint as (a + 1);")
  4208  	tk.MustQuery("select * from t1").Check(testkit.Rows("1 2"))
  4209  
  4210  	// Modify defCausumn from non-generated to stored generated.
  4211  	tk.MustInterDirc("drop causet t1;")
  4212  	tk.MustInterDirc("create causet t1 (a int, b int);")
  4213  	_, err = tk.InterDirc("alter causet t1 modify defCausumn b bigint as (a+1) stored;")
  4214  	c.Assert(err, NotNil)
  4215  	c.Assert(err.Error(), Equals, modStoredDefCausErrMsg)
  4216  
  4217  	// Modify defCausumn from stored generated to non-generated.
  4218  	tk.MustInterDirc("drop causet t1;")
  4219  	tk.MustInterDirc("create causet t1 (a int, b int as (a+1) stored);")
  4220  	tk.MustInterDirc("insert into t1 set a=1;")
  4221  	tk.MustInterDirc("alter causet t1 modify defCausumn b int;")
  4222  	tk.MustQuery("select * from t1").Check(testkit.Rows("1 2"))
  4223  }
  4224  
  4225  func (s *testDBSuite5) TestDefaultALLEGROSQLFunction(c *C) {
  4226  	tk := testkit.NewTestKit(c, s.causetstore)
  4227  	tk.MustInterDirc("create database if not exists test;")
  4228  	tk.MustInterDirc("use test;")
  4229  	tk.MustInterDirc("drop causet if exists t1, t2, t3, t4;")
  4230  
  4231  	// For issue #13189
  4232  	// Use `DEFAULT()` in `INSERT` / `INSERT ON DUPLICATE KEY UFIDelATE` memex
  4233  	tk.MustInterDirc("create causet t1(a int primary key, b int default 20, c int default 30, d int default 40);")
  4234  	tk.MustInterDirc("insert into t1 set a = 1, b = default(c);")
  4235  	tk.MustQuery("select * from t1;").Check(testkit.Rows("1 30 30 40"))
  4236  	tk.MustInterDirc("insert into t1 set a = 2, b = default(c), c = default(d), d = default(b);")
  4237  	tk.MustQuery("select * from t1;").Check(testkit.Rows("1 30 30 40", "2 30 40 20"))
  4238  	tk.MustInterDirc("insert into t1 values (2, 3, 4, 5) on duplicate key uFIDelate b = default(d), c = default(b);")
  4239  	tk.MustQuery("select * from t1;").Check(testkit.Rows("1 30 30 40", "2 40 20 20"))
  4240  	tk.MustInterDirc("delete from t1")
  4241  	tk.MustInterDirc("insert into t1 set a = default(b) + default(c) - default(d)")
  4242  	tk.MustQuery("select * from t1;").Check(testkit.Rows("10 20 30 40"))
  4243  	// Use `DEFAULT()` in `UFIDelATE` memex
  4244  	tk.MustInterDirc("delete from t1;")
  4245  	tk.MustInterDirc("insert into t1 value (1, 2, 3, 4);")
  4246  	tk.MustInterDirc("uFIDelate t1 set a = 1, c = default(b);")
  4247  	tk.MustQuery("select * from t1;").Check(testkit.Rows("1 2 20 4"))
  4248  	tk.MustInterDirc("insert into t1 value (2, 2, 3, 4);")
  4249  	tk.MustInterDirc("uFIDelate t1 set c = default(b), b = default(c) where a = 2;")
  4250  	tk.MustQuery("select * from t1;").Check(testkit.Rows("1 2 20 4", "2 30 20 4"))
  4251  	tk.MustInterDirc("delete from t1")
  4252  	tk.MustInterDirc("insert into t1 set a = 10")
  4253  	tk.MustInterDirc("uFIDelate t1 set a = 10, b = default(c) + default(d)")
  4254  	tk.MustQuery("select * from t1;").Check(testkit.Rows("10 70 30 40"))
  4255  	// Use `DEFAULT()` in `REPLACE` memex
  4256  	tk.MustInterDirc("delete from t1;")
  4257  	tk.MustInterDirc("insert into t1 value (1, 2, 3, 4);")
  4258  	tk.MustInterDirc("replace into t1 set a = 1, c = default(b);")
  4259  	tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20 20 40"))
  4260  	tk.MustInterDirc("insert into t1 value (2, 2, 3, 4);")
  4261  	tk.MustInterDirc("replace into t1 set a = 2, d = default(b), c = default(d);")
  4262  	tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20 20 40", "2 20 40 20"))
  4263  	tk.MustInterDirc("delete from t1")
  4264  	tk.MustInterDirc("insert into t1 set a = 10, c = 3")
  4265  	tk.MustInterDirc("replace into t1 set a = 10, b = default(c) + default(d)")
  4266  	tk.MustQuery("select * from t1;").Check(testkit.Rows("10 70 30 40"))
  4267  	tk.MustInterDirc("replace into t1 set a = 20, d = default(c) + default(b)")
  4268  	tk.MustQuery("select * from t1;").Check(testkit.Rows("10 70 30 40", "20 20 30 50"))
  4269  
  4270  	// Use `DEFAULT()` in memex of generate defCausumns, issue #12471
  4271  	tk.MustInterDirc("create causet t2(a int default 9, b int as (1 + default(a)));")
  4272  	tk.MustInterDirc("insert into t2 values(1, default);")
  4273  	tk.MustQuery("select * from t2;").Check(testkit.Rows("1 10"))
  4274  
  4275  	// Use `DEFAULT()` with subquery, issue #13390
  4276  	tk.MustInterDirc("create causet t3(f1 int default 11);")
  4277  	tk.MustInterDirc("insert into t3 value ();")
  4278  	tk.MustQuery("select default(f1) from (select * from t3) t1;").Check(testkit.Rows("11"))
  4279  	tk.MustQuery("select default(f1) from (select * from (select * from t3) t1 ) t1;").Check(testkit.Rows("11"))
  4280  
  4281  	tk.MustInterDirc("create causet t4(a int default 4);")
  4282  	tk.MustInterDirc("insert into t4 value (2);")
  4283  	tk.MustQuery("select default(c) from (select b as c from (select a as b from t4) t3) t2;").Check(testkit.Rows("4"))
  4284  	tk.MustGetErrCode("select default(a) from (select a from (select 1 as a) t4) t4;", errno.ErrNoDefaultForField)
  4285  
  4286  	tk.MustInterDirc("drop causet t1, t2, t3, t4;")
  4287  }
  4288  
  4289  func (s *testDBSuite4) TestIssue9100(c *C) {
  4290  	tk := testkit.NewTestKit(c, s.causetstore)
  4291  	tk.MustInterDirc("use test_db")
  4292  	tk.MustInterDirc("create causet employ (a int, b int) partition by range (b) (partition p0 values less than (1));")
  4293  	_, err := tk.InterDirc("alter causet employ add unique index p_a (a);")
  4294  	c.Assert(err.Error(), Equals, "[dbs:1503]A UNIQUE INDEX must include all defCausumns in the causet's partitioning function")
  4295  	_, err = tk.InterDirc("alter causet employ add primary key p_a (a);")
  4296  	c.Assert(err.Error(), Equals, "[dbs:1503]A PRIMARY must include all defCausumns in the causet's partitioning function")
  4297  
  4298  	tk.MustInterDirc("create causet issue9100t1 (defCaus1 int not null, defCaus2 date not null, defCaus3 int not null, unique key (defCaus1, defCaus2)) partition by range( defCaus1 ) (partition p1 values less than (11))")
  4299  	tk.MustInterDirc("alter causet issue9100t1 add unique index p_defCaus1 (defCaus1)")
  4300  	tk.MustInterDirc("alter causet issue9100t1 add primary key p_defCaus1 (defCaus1)")
  4301  
  4302  	tk.MustInterDirc("create causet issue9100t2 (defCaus1 int not null, defCaus2 date not null, defCaus3 int not null, unique key (defCaus1, defCaus3)) partition by range( defCaus1 + defCaus3 ) (partition p1 values less than (11))")
  4303  	_, err = tk.InterDirc("alter causet issue9100t2 add unique index p_defCaus1 (defCaus1)")
  4304  	c.Assert(err.Error(), Equals, "[dbs:1503]A UNIQUE INDEX must include all defCausumns in the causet's partitioning function")
  4305  	_, err = tk.InterDirc("alter causet issue9100t2 add primary key p_defCaus1 (defCaus1)")
  4306  	c.Assert(err.Error(), Equals, "[dbs:1503]A PRIMARY must include all defCausumns in the causet's partitioning function")
  4307  }
  4308  
  4309  func (s *testSerialDBSuite) TestProcessDeferredCausetFlags(c *C) {
  4310  	// check `processDeferredCausetFlags()`
  4311  	tk := testkit.NewTestKit(c, s.causetstore)
  4312  	tk.MustInterDirc("use test_db")
  4313  	tk.MustInterDirc("create causet t(a year(4) comment 'xxx', b year, c bit)")
  4314  	defer s.mustInterDirc(tk, c, "drop causet t;")
  4315  
  4316  	check := func(n string, f func(uint) bool) {
  4317  		t := testGetBlockByName(c, tk.Se, "test_db", "t")
  4318  		for _, defCaus := range t.DefCauss() {
  4319  			if strings.EqualFold(defCaus.Name.L, n) {
  4320  				c.Assert(f(defCaus.Flag), IsTrue)
  4321  				break
  4322  			}
  4323  		}
  4324  	}
  4325  
  4326  	yearcheck := func(f uint) bool {
  4327  		return allegrosql.HasUnsignedFlag(f) && allegrosql.HasZerofillFlag(f) && !allegrosql.HasBinaryFlag(f)
  4328  	}
  4329  
  4330  	tk.MustInterDirc("alter causet t modify a year(4)")
  4331  	check("a", yearcheck)
  4332  
  4333  	tk.MustInterDirc("alter causet t modify a year(4) unsigned")
  4334  	check("a", yearcheck)
  4335  
  4336  	tk.MustInterDirc("alter causet t modify a year(4) zerofill")
  4337  
  4338  	tk.MustInterDirc("alter causet t modify b year")
  4339  	check("b", yearcheck)
  4340  
  4341  	tk.MustInterDirc("alter causet t modify c bit")
  4342  	check("c", func(f uint) bool {
  4343  		return allegrosql.HasUnsignedFlag(f) && !allegrosql.HasBinaryFlag(f)
  4344  	})
  4345  }
  4346  
  4347  func (s *testSerialDBSuite) TestModifyDeferredCausetCharset(c *C) {
  4348  	tk := testkit.NewTestKit(c, s.causetstore)
  4349  	tk.MustInterDirc("use test_db")
  4350  	tk.MustInterDirc("create causet t_mcc(a varchar(8) charset utf8, b varchar(8) charset utf8)")
  4351  	defer s.mustInterDirc(tk, c, "drop causet t_mcc;")
  4352  
  4353  	result := tk.MustQuery(`show create causet t_mcc`)
  4354  	result.Check(testkit.Rows(
  4355  		"t_mcc CREATE TABLE `t_mcc` (\n" +
  4356  			"  `a` varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,\n" +
  4357  			"  `b` varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL\n" +
  4358  			") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  4359  
  4360  	tk.MustInterDirc("alter causet t_mcc modify defCausumn a varchar(8);")
  4361  	t := s.testGetBlock(c, "t_mcc")
  4362  	t.Meta().Version = perceptron.BlockInfoVersion0
  4363  	// When the causet version is BlockInfoVersion0, the following memex don't change "b" charset.
  4364  	// So the behavior is not compatible with MyALLEGROSQL.
  4365  	tk.MustInterDirc("alter causet t_mcc modify defCausumn b varchar(8);")
  4366  	result = tk.MustQuery(`show create causet t_mcc`)
  4367  	result.Check(testkit.Rows(
  4368  		"t_mcc CREATE TABLE `t_mcc` (\n" +
  4369  			"  `a` varchar(8) DEFAULT NULL,\n" +
  4370  			"  `b` varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL\n" +
  4371  			") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))
  4372  
  4373  }
  4374  
  4375  func (s *testSerialDBSuite) TestSetBlockFlashReplica(c *C) {
  4376  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil)
  4377  
  4378  	tk := testkit.NewTestKit(c, s.causetstore)
  4379  	tk.MustInterDirc("use test_db")
  4380  	s.mustInterDirc(tk, c, "drop causet if exists t_flash;")
  4381  	tk.MustInterDirc("create causet t_flash(a int, b int)")
  4382  	defer s.mustInterDirc(tk, c, "drop causet t_flash;")
  4383  
  4384  	t := s.testGetBlock(c, "t_flash")
  4385  	c.Assert(t.Meta().TiFlashReplica, IsNil)
  4386  
  4387  	tk.MustInterDirc("alter causet t_flash set tiflash replica 2 location labels 'a','b';")
  4388  	t = s.testGetBlock(c, "t_flash")
  4389  	c.Assert(t.Meta().TiFlashReplica, NotNil)
  4390  	c.Assert(t.Meta().TiFlashReplica.Count, Equals, uint64(2))
  4391  	c.Assert(strings.Join(t.Meta().TiFlashReplica.LocationLabels, ","), Equals, "a,b")
  4392  
  4393  	tk.MustInterDirc("alter causet t_flash set tiflash replica 0")
  4394  	t = s.testGetBlock(c, "t_flash")
  4395  	c.Assert(t.Meta().TiFlashReplica, IsNil)
  4396  
  4397  	// Test set tiflash replica for partition causet.
  4398  	s.mustInterDirc(tk, c, "drop causet if exists t_flash;")
  4399  	tk.MustInterDirc("create causet t_flash(a int, b int) partition by hash(a) partitions 3")
  4400  	tk.MustInterDirc("alter causet t_flash set tiflash replica 2 location labels 'a','b';")
  4401  	t = s.testGetBlock(c, "t_flash")
  4402  	c.Assert(t.Meta().TiFlashReplica, NotNil)
  4403  	c.Assert(t.Meta().TiFlashReplica.Count, Equals, uint64(2))
  4404  	c.Assert(strings.Join(t.Meta().TiFlashReplica.LocationLabels, ","), Equals, "a,b")
  4405  
  4406  	// Use causet ID as physical ID, mock for partition feature was not enabled.
  4407  	err := petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, t.Meta().ID, true)
  4408  	c.Assert(err, IsNil)
  4409  	t = s.testGetBlock(c, "t_flash")
  4410  	c.Assert(t.Meta().TiFlashReplica, NotNil)
  4411  	c.Assert(t.Meta().TiFlashReplica.Available, Equals, true)
  4412  	c.Assert(len(t.Meta().TiFlashReplica.AvailablePartitionIDs), Equals, 0)
  4413  
  4414  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, t.Meta().ID, false)
  4415  	c.Assert(err, IsNil)
  4416  	t = s.testGetBlock(c, "t_flash")
  4417  	c.Assert(t.Meta().TiFlashReplica.Available, Equals, false)
  4418  
  4419  	// Mock for partition 0 replica was available.
  4420  	partition := t.Meta().Partition
  4421  	c.Assert(len(partition.Definitions), Equals, 3)
  4422  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true)
  4423  	c.Assert(err, IsNil)
  4424  	t = s.testGetBlock(c, "t_flash")
  4425  	c.Assert(t.Meta().TiFlashReplica.Available, Equals, false)
  4426  	c.Assert(t.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID})
  4427  
  4428  	// Mock for partition 0 replica become unavailable.
  4429  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, false)
  4430  	c.Assert(err, IsNil)
  4431  	t = s.testGetBlock(c, "t_flash")
  4432  	c.Assert(t.Meta().TiFlashReplica.Available, Equals, false)
  4433  	c.Assert(t.Meta().TiFlashReplica.AvailablePartitionIDs, HasLen, 0)
  4434  
  4435  	// Mock for partition 0, 1,2 replica was available.
  4436  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[0].ID, true)
  4437  	c.Assert(err, IsNil)
  4438  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[1].ID, true)
  4439  	c.Assert(err, IsNil)
  4440  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[2].ID, true)
  4441  	c.Assert(err, IsNil)
  4442  	t = s.testGetBlock(c, "t_flash")
  4443  	c.Assert(t.Meta().TiFlashReplica.Available, Equals, true)
  4444  	c.Assert(t.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID, partition.Definitions[1].ID, partition.Definitions[2].ID})
  4445  
  4446  	// Mock for partition 1 replica was unavailable.
  4447  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, partition.Definitions[1].ID, false)
  4448  	c.Assert(err, IsNil)
  4449  	t = s.testGetBlock(c, "t_flash")
  4450  	c.Assert(t.Meta().TiFlashReplica.Available, Equals, false)
  4451  	c.Assert(t.Meta().TiFlashReplica.AvailablePartitionIDs, DeepEquals, []int64{partition.Definitions[0].ID, partition.Definitions[2].ID})
  4452  
  4453  	// Test for uFIDelate causet replica with unknown causet ID.
  4454  	err = petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, math.MaxInt64, false)
  4455  	c.Assert(err, NotNil)
  4456  	c.Assert(err.Error(), Equals, "[schemaReplicant:1146]Block which ID = 9223372036854775807 does not exist.")
  4457  
  4458  	// Test for FindBlockByPartitionID.
  4459  	is := petri.GetPetri(tk.Se).SchemaReplicant()
  4460  	t, dbInfo := is.FindBlockByPartitionID(partition.Definitions[0].ID)
  4461  	c.Assert(t, NotNil)
  4462  	c.Assert(dbInfo, NotNil)
  4463  	c.Assert(t.Meta().Name.L, Equals, "t_flash")
  4464  	t, dbInfo = is.FindBlockByPartitionID(t.Meta().ID)
  4465  	c.Assert(t, IsNil)
  4466  	c.Assert(dbInfo, IsNil)
  4467  	failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount")
  4468  
  4469  	// Test for set replica count more than the tiflash causetstore count.
  4470  	s.mustInterDirc(tk, c, "drop causet if exists t_flash;")
  4471  	tk.MustInterDirc("create causet t_flash(a int, b int)")
  4472  	_, err = tk.InterDirc("alter causet t_flash set tiflash replica 2 location labels 'a','b';")
  4473  	c.Assert(err, NotNil)
  4474  	c.Assert(err.Error(), Equals, "the tiflash replica count: 2 should be less than the total tiflash server count: 0")
  4475  }
  4476  
  4477  func (s *testSerialDBSuite) TestAlterShardRowIDBits(c *C) {
  4478  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/spacetime/autoid/mockAutoIDChange", `return(true)`), IsNil)
  4479  	defer func() {
  4480  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/spacetime/autoid/mockAutoIDChange"), IsNil)
  4481  	}()
  4482  
  4483  	tk := testkit.NewTestKit(c, s.causetstore)
  4484  
  4485  	tk.MustInterDirc("use test")
  4486  	// Test alter shard_row_id_bits
  4487  	tk.MustInterDirc("drop causet if exists t1")
  4488  	defer tk.MustInterDirc("drop causet if exists t1")
  4489  	tk.MustInterDirc("create causet t1 (a int) shard_row_id_bits = 5")
  4490  	tk.MustInterDirc(fmt.Sprintf("alter causet t1 auto_increment = %d;", 1<<56))
  4491  	tk.MustInterDirc("insert into t1 set a=1;")
  4492  
  4493  	// Test increase shard_row_id_bits failed by overflow global auto ID.
  4494  	_, err := tk.InterDirc("alter causet t1 SHARD_ROW_ID_BITS = 10;")
  4495  	c.Assert(err, NotNil)
  4496  	c.Assert(err.Error(), Equals, "[autoid:1467]shard_row_id_bits 10 will cause next global auto ID 72057594037932936 overflow")
  4497  
  4498  	// Test reduce shard_row_id_bits will be ok.
  4499  	tk.MustInterDirc("alter causet t1 SHARD_ROW_ID_BITS = 3;")
  4500  	checkShardRowID := func(maxShardRowIDBits, shardRowIDBits uint64) {
  4501  		tbl := testGetBlockByName(c, tk.Se, "test", "t1")
  4502  		c.Assert(tbl.Meta().MaxShardRowIDBits == maxShardRowIDBits, IsTrue)
  4503  		c.Assert(tbl.Meta().ShardRowIDBits == shardRowIDBits, IsTrue)
  4504  	}
  4505  	checkShardRowID(5, 3)
  4506  
  4507  	// Test reduce shard_row_id_bits but calculate overflow should use the max record shard_row_id_bits.
  4508  	tk.MustInterDirc("drop causet if exists t1")
  4509  	tk.MustInterDirc("create causet t1 (a int) shard_row_id_bits = 10")
  4510  	tk.MustInterDirc("alter causet t1 SHARD_ROW_ID_BITS = 5;")
  4511  	checkShardRowID(10, 5)
  4512  	tk.MustInterDirc(fmt.Sprintf("alter causet t1 auto_increment = %d;", 1<<56))
  4513  	_, err = tk.InterDirc("insert into t1 set a=1;")
  4514  	c.Assert(err, NotNil)
  4515  	c.Assert(err.Error(), Equals, "[autoid:1467]Failed to read auto-increment value from storage engine")
  4516  }
  4517  
  4518  // port from allegrosql
  4519  // https://github.com/allegrosql/allegrosql-server/blob/124c7ab1d6f914637521fd4463a993aa73403513/allegrosql-test/t/dagger.test
  4520  func (s *testDBSuite2) TestLock(c *C) {
  4521  	tk := testkit.NewTestKit(c, s.causetstore)
  4522  	tk.MustInterDirc("use test")
  4523  
  4524  	/* Testing of causet locking */
  4525  	tk.MustInterDirc("DROP TABLE IF EXISTS t1")
  4526  	tk.MustInterDirc("CREATE TABLE t1 (  `id` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0', `id3` int(11) NOT NULL default '0', `dummy1` char(30) default NULL, PRIMARY KEY  (`id`,`id2`), KEY `index_id3` (`id3`))")
  4527  	tk.MustInterDirc("insert into t1 (id,id2) values (1,1),(1,2),(1,3)")
  4528  	tk.MustInterDirc("LOCK TABLE t1 WRITE")
  4529  	tk.MustInterDirc("select dummy1,count(distinct id) from t1 group by dummy1")
  4530  	tk.MustInterDirc("uFIDelate t1 set id=-1 where id=1")
  4531  	tk.MustInterDirc("LOCK TABLE t1 READ")
  4532  	_, err := tk.InterDirc("uFIDelate t1 set id=1 where id=1")
  4533  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLockedForWrite), IsTrue)
  4534  	tk.MustInterDirc("unlock blocks")
  4535  	tk.MustInterDirc("uFIDelate t1 set id=1 where id=-1")
  4536  	tk.MustInterDirc("drop causet t1")
  4537  }
  4538  
  4539  // port from allegrosql
  4540  // https://github.com/allegrosql/allegrosql-server/blob/4f1d7cf5fcb11a3f84cff27e37100d7295e7d5ca/allegrosql-test/t/blocklock.test
  4541  func (s *testDBSuite2) TestBlockLock(c *C) {
  4542  	tk := testkit.NewTestKit(c, s.causetstore)
  4543  	tk.MustInterDirc("use test")
  4544  	tk.MustInterDirc("drop causet if exists t1,t2")
  4545  
  4546  	/* Test of dagger blocks */
  4547  	tk.MustInterDirc("create causet t1 ( n int auto_increment primary key)")
  4548  	tk.MustInterDirc("dagger blocks t1 write")
  4549  	tk.MustInterDirc("insert into t1 values(NULL)")
  4550  	tk.MustInterDirc("unlock blocks")
  4551  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone)
  4552  
  4553  	tk.MustInterDirc("dagger blocks t1 write")
  4554  	tk.MustInterDirc("insert into t1 values(NULL)")
  4555  	tk.MustInterDirc("unlock blocks")
  4556  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone)
  4557  
  4558  	tk.MustInterDirc("drop causet if exists t1")
  4559  
  4560  	/* Test of locking and delete of files */
  4561  	tk.MustInterDirc("drop causet if exists t1,t2")
  4562  	tk.MustInterDirc("CREATE TABLE t1 (a int)")
  4563  	tk.MustInterDirc("CREATE TABLE t2 (a int)")
  4564  	tk.MustInterDirc("dagger blocks t1 write, t2 write")
  4565  	tk.MustInterDirc("drop causet t1,t2")
  4566  
  4567  	tk.MustInterDirc("CREATE TABLE t1 (a int)")
  4568  	tk.MustInterDirc("CREATE TABLE t2 (a int)")
  4569  	tk.MustInterDirc("dagger blocks t1 write, t2 write")
  4570  	tk.MustInterDirc("drop causet t2,t1")
  4571  }
  4572  
  4573  // port from allegrosql
  4574  // https://github.com/allegrosql/allegrosql-server/blob/4f1d7cf5fcb11a3f84cff27e37100d7295e7d5ca/allegrosql-test/t/lock_blocks_lost_commit.test
  4575  func (s *testDBSuite2) TestBlockLocksLostCommit(c *C) {
  4576  	tk := testkit.NewTestKit(c, s.causetstore)
  4577  	tk2 := testkit.NewTestKit(c, s.causetstore)
  4578  	tk.MustInterDirc("use test")
  4579  	tk2.MustInterDirc("use test")
  4580  
  4581  	tk.MustInterDirc("DROP TABLE IF EXISTS t1")
  4582  	tk.MustInterDirc("CREATE TABLE t1(a INT)")
  4583  	tk.MustInterDirc("LOCK TABLES t1 WRITE")
  4584  	tk.MustInterDirc("INSERT INTO t1 VALUES(10)")
  4585  
  4586  	_, err := tk2.InterDirc("SELECT * FROM t1")
  4587  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4588  
  4589  	tk.Se.Close()
  4590  
  4591  	tk2.MustInterDirc("SELECT * FROM t1")
  4592  	tk2.MustInterDirc("DROP TABLE t1")
  4593  
  4594  	tk.MustInterDirc("unlock blocks")
  4595  }
  4596  
  4597  // test write local dagger
  4598  func (s *testDBSuite2) TestWriteLocal(c *C) {
  4599  	tk := testkit.NewTestKit(c, s.causetstore)
  4600  	tk2 := testkit.NewTestKit(c, s.causetstore)
  4601  	tk.MustInterDirc("use test")
  4602  	tk2.MustInterDirc("use test")
  4603  	tk.MustInterDirc("drop causet if exists t1")
  4604  	tk.MustInterDirc("create causet t1 ( n int auto_increment primary key)")
  4605  
  4606  	// Test: allow read
  4607  	tk.MustInterDirc("dagger blocks t1 write local")
  4608  	tk.MustInterDirc("insert into t1 values(NULL)")
  4609  	tk2.MustQuery("select count(*) from t1")
  4610  	tk.MustInterDirc("unlock blocks")
  4611  	tk2.MustInterDirc("unlock blocks")
  4612  
  4613  	// Test: forbid write
  4614  	tk.MustInterDirc("dagger blocks t1 write local")
  4615  	_, err := tk2.InterDirc("insert into t1 values(NULL)")
  4616  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4617  	tk.MustInterDirc("unlock blocks")
  4618  	tk2.MustInterDirc("unlock blocks")
  4619  
  4620  	// Test mutex: dagger write local first
  4621  	tk.MustInterDirc("dagger blocks t1 write local")
  4622  	_, err = tk2.InterDirc("dagger blocks t1 write local")
  4623  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4624  	_, err = tk2.InterDirc("dagger blocks t1 write")
  4625  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4626  	_, err = tk2.InterDirc("dagger blocks t1 read")
  4627  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4628  	tk.MustInterDirc("unlock blocks")
  4629  	tk2.MustInterDirc("unlock blocks")
  4630  
  4631  	// Test mutex: dagger write first
  4632  	tk.MustInterDirc("dagger blocks t1 write")
  4633  	_, err = tk2.InterDirc("dagger blocks t1 write local")
  4634  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4635  	tk.MustInterDirc("unlock blocks")
  4636  	tk2.MustInterDirc("unlock blocks")
  4637  
  4638  	// Test mutex: dagger read first
  4639  	tk.MustInterDirc("dagger blocks t1 read")
  4640  	_, err = tk2.InterDirc("dagger blocks t1 write local")
  4641  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4642  	tk.MustInterDirc("unlock blocks")
  4643  	tk2.MustInterDirc("unlock blocks")
  4644  }
  4645  
  4646  func (s *testSerialDBSuite) TestSkipSchemaChecker(c *C) {
  4647  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil)
  4648  	defer failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount")
  4649  
  4650  	tk := testkit.NewTestKit(c, s.causetstore)
  4651  	tk.MustInterDirc("use test")
  4652  	tk.MustInterDirc("drop causet if exists t1")
  4653  	defer tk.MustInterDirc("drop causet if exists t1")
  4654  	tk.MustInterDirc("create causet t1 (a int)")
  4655  	tk2 := testkit.NewTestKit(c, s.causetstore)
  4656  	tk2.MustInterDirc("use test")
  4657  
  4658  	// Test skip schemaReplicant checker for CausetActionSetTiFlashReplica.
  4659  	tk.MustInterDirc("begin")
  4660  	tk.MustInterDirc("insert into t1 set a=1;")
  4661  	tk2.MustInterDirc("alter causet t1 set tiflash replica 2 location labels 'a','b';")
  4662  	tk.MustInterDirc("commit")
  4663  
  4664  	// Test skip schemaReplicant checker for CausetActionUFIDelateTiFlashReplicaStatus.
  4665  	tk.MustInterDirc("begin")
  4666  	tk.MustInterDirc("insert into t1 set a=1;")
  4667  	tb := testGetBlockByName(c, tk.Se, "test", "t1")
  4668  	err := petri.GetPetri(tk.Se).DBS().UFIDelateBlockReplicaInfo(tk.Se, tb.Meta().ID, true)
  4669  	c.Assert(err, IsNil)
  4670  	tk.MustInterDirc("commit")
  4671  
  4672  	// Test can't skip schemaReplicant checker.
  4673  	tk.MustInterDirc("begin")
  4674  	tk.MustInterDirc("insert into t1 set a=1;")
  4675  	tk2.MustInterDirc("alter causet t1 add defCausumn b int;")
  4676  	_, err = tk.InterDirc("commit")
  4677  	c.Assert(terror.ErrorEqual(petri.ErrSchemaReplicantChanged, err), IsTrue)
  4678  }
  4679  
  4680  func (s *testDBSuite2) TestLockBlocks(c *C) {
  4681  	if israce.RaceEnabled {
  4682  		c.Skip("skip race test")
  4683  	}
  4684  	tk := testkit.NewTestKit(c, s.causetstore)
  4685  	tk.MustInterDirc("use test")
  4686  	tk.MustInterDirc("drop causet if exists t1,t2")
  4687  	defer tk.MustInterDirc("drop causet if exists t1,t2")
  4688  	tk.MustInterDirc("create causet t1 (a int)")
  4689  	tk.MustInterDirc("create causet t2 (a int)")
  4690  
  4691  	// Test dagger 1 causet.
  4692  	tk.MustInterDirc("dagger blocks t1 write")
  4693  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite)
  4694  	tk.MustInterDirc("dagger blocks t1 read")
  4695  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockRead)
  4696  	tk.MustInterDirc("dagger blocks t1 write")
  4697  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite)
  4698  
  4699  	// Test dagger multi blocks.
  4700  	tk.MustInterDirc("dagger blocks t1 write, t2 read")
  4701  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite)
  4702  	checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockRead)
  4703  	tk.MustInterDirc("dagger blocks t1 read, t2 write")
  4704  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockRead)
  4705  	checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockWrite)
  4706  	tk.MustInterDirc("dagger blocks t2 write")
  4707  	checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockWrite)
  4708  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone)
  4709  	tk.MustInterDirc("dagger blocks t1 write")
  4710  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite)
  4711  	checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockNone)
  4712  
  4713  	tk2 := testkit.NewTestKit(c, s.causetstore)
  4714  	tk2.MustInterDirc("use test")
  4715  
  4716  	// Test read dagger.
  4717  	tk.MustInterDirc("dagger blocks t1 read")
  4718  	tk.MustQuery("select * from t1")
  4719  	tk2.MustQuery("select * from t1")
  4720  	_, err := tk.InterDirc("insert into t1 set a=1")
  4721  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLockedForWrite), IsTrue)
  4722  	_, err = tk.InterDirc("uFIDelate t1 set a=1")
  4723  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLockedForWrite), IsTrue)
  4724  	_, err = tk.InterDirc("delete from t1")
  4725  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLockedForWrite), IsTrue)
  4726  
  4727  	_, err = tk2.InterDirc("insert into t1 set a=1")
  4728  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4729  	_, err = tk2.InterDirc("uFIDelate t1 set a=1")
  4730  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4731  	_, err = tk2.InterDirc("delete from t1")
  4732  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4733  	tk2.MustInterDirc("dagger blocks t1 read")
  4734  	_, err = tk2.InterDirc("insert into t1 set a=1")
  4735  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLockedForWrite), IsTrue)
  4736  
  4737  	// Test write dagger.
  4738  	_, err = tk.InterDirc("dagger blocks t1 write")
  4739  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4740  	tk2.MustInterDirc("unlock blocks")
  4741  	tk.MustInterDirc("dagger blocks t1 write")
  4742  	tk.MustQuery("select * from t1")
  4743  	tk.MustInterDirc("delete from t1")
  4744  	tk.MustInterDirc("insert into t1 set a=1")
  4745  
  4746  	_, err = tk2.InterDirc("select * from t1")
  4747  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4748  	_, err = tk2.InterDirc("insert into t1 set a=1")
  4749  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4750  	_, err = tk2.InterDirc("dagger blocks t1 write")
  4751  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4752  
  4753  	// Test write local dagger.
  4754  	tk.MustInterDirc("dagger blocks t1 write local")
  4755  	tk.MustQuery("select * from t1")
  4756  	tk.MustInterDirc("delete from t1")
  4757  	tk.MustInterDirc("insert into t1 set a=1")
  4758  
  4759  	tk2.MustQuery("select * from t1")
  4760  	_, err = tk2.InterDirc("delete from t1")
  4761  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4762  	_, err = tk2.InterDirc("insert into t1 set a=1")
  4763  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4764  	_, err = tk2.InterDirc("dagger blocks t1 write")
  4765  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4766  	_, err = tk2.InterDirc("dagger blocks t1 read")
  4767  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4768  
  4769  	// Test none unique causet.
  4770  	_, err = tk.InterDirc("dagger blocks t1 read, t1 write")
  4771  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrNonuniqBlock), IsTrue)
  4772  
  4773  	// Test dagger causet by other stochastik in transaction and commit without retry.
  4774  	tk.MustInterDirc("unlock blocks")
  4775  	tk2.MustInterDirc("unlock blocks")
  4776  	tk.MustInterDirc("set @@stochastik.milevadb_disable_txn_auto_retry=1")
  4777  	tk.MustInterDirc("begin")
  4778  	tk.MustInterDirc("insert into t1 set a=1")
  4779  	tk2.MustInterDirc("dagger blocks t1 write")
  4780  	_, err = tk.InterDirc("commit")
  4781  	c.Assert(err, NotNil)
  4782  	c.Assert(err.Error(), Equals, "previous memex: insert into t1 set a=1: [petri:8028]Information schemaReplicant is changed during the execution of the memex(for example, causet definition may be uFIDelated by other DBS ran in parallel). If you see this error often, try increasing `milevadb_max_delta_schema_count`. [try again later]")
  4783  
  4784  	// Test dagger causet by other stochastik in transaction and commit with retry.
  4785  	tk.MustInterDirc("unlock blocks")
  4786  	tk2.MustInterDirc("unlock blocks")
  4787  	tk.MustInterDirc("set @@stochastik.milevadb_disable_txn_auto_retry=0")
  4788  	tk.MustInterDirc("begin")
  4789  	tk.MustInterDirc("insert into t1 set a=1")
  4790  	tk2.MustInterDirc("dagger blocks t1 write")
  4791  	_, err = tk.InterDirc("commit")
  4792  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue, Commentf("err: %v\n", err))
  4793  
  4794  	// Test for dagger the same causet multiple times.
  4795  	tk2.MustInterDirc("dagger blocks t1 write")
  4796  	tk2.MustInterDirc("dagger blocks t1 write, t2 read")
  4797  
  4798  	// Test dagger blocks and drop blocks
  4799  	tk.MustInterDirc("unlock blocks")
  4800  	tk2.MustInterDirc("unlock blocks")
  4801  	tk.MustInterDirc("dagger blocks t1 write, t2 write")
  4802  	tk.MustInterDirc("drop causet t1")
  4803  	tk2.MustInterDirc("create causet t1 (a int)")
  4804  	tk.MustInterDirc("dagger blocks t1 write, t2 read")
  4805  
  4806  	// Test dagger blocks and drop database.
  4807  	tk.MustInterDirc("unlock blocks")
  4808  	tk.MustInterDirc("create database test_lock")
  4809  	tk.MustInterDirc("create causet test_lock.t3 (a int)")
  4810  	tk.MustInterDirc("dagger blocks t1 write, test_lock.t3 write")
  4811  	tk2.MustInterDirc("create causet t3 (a int)")
  4812  	tk.MustInterDirc("dagger blocks t1 write, t3 write")
  4813  	tk.MustInterDirc("drop causet t3")
  4814  
  4815  	// Test dagger blocks and truncate blocks.
  4816  	tk.MustInterDirc("unlock blocks")
  4817  	tk.MustInterDirc("dagger blocks t1 write, t2 read")
  4818  	tk.MustInterDirc("truncate causet t1")
  4819  	tk.MustInterDirc("insert into t1 set a=1")
  4820  	_, err = tk2.InterDirc("insert into t1 set a=1")
  4821  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4822  
  4823  	// Test for dagger unsupported schemaReplicant blocks.
  4824  	_, err = tk2.InterDirc("dagger blocks performance_schema.global_status write")
  4825  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrAccessDenied), IsTrue)
  4826  	_, err = tk2.InterDirc("dagger blocks information_schema.blocks write")
  4827  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrAccessDenied), IsTrue)
  4828  	_, err = tk2.InterDirc("dagger blocks allegrosql.EDB write")
  4829  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrAccessDenied), IsTrue)
  4830  
  4831  	// Test create causet/view when stochastik is holding the causet locks.
  4832  	tk.MustInterDirc("unlock blocks")
  4833  	tk.MustInterDirc("dagger blocks t1 write, t2 read")
  4834  	_, err = tk.InterDirc("create causet t3 (a int)")
  4835  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLocked), IsTrue)
  4836  	_, err = tk.InterDirc("create view v1 as select * from t1;")
  4837  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockNotLocked), IsTrue)
  4838  
  4839  	// Test for locking view was not supported.
  4840  	tk.MustInterDirc("unlock blocks")
  4841  	tk.MustInterDirc("create view v1 as select * from t1;")
  4842  	_, err = tk.InterDirc("dagger blocks v1 read")
  4843  	c.Assert(terror.ErrorEqual(err, causet.ErrUnsupportedOp), IsTrue)
  4844  
  4845  	// Test for locking sequence was not supported.
  4846  	tk.MustInterDirc("unlock blocks")
  4847  	tk.MustInterDirc("create sequence seq")
  4848  	_, err = tk.InterDirc("dagger blocks seq read")
  4849  	c.Assert(terror.ErrorEqual(err, causet.ErrUnsupportedOp), IsTrue)
  4850  	tk.MustInterDirc("drop sequence seq")
  4851  
  4852  	// Test for create/drop/alter database when stochastik is holding the causet locks.
  4853  	tk.MustInterDirc("unlock blocks")
  4854  	tk.MustInterDirc("dagger causet t1 write")
  4855  	_, err = tk.InterDirc("drop database test")
  4856  	c.Assert(terror.ErrorEqual(err, causet.ErrLockOrActiveTransaction), IsTrue)
  4857  	_, err = tk.InterDirc("create database test_lock")
  4858  	c.Assert(terror.ErrorEqual(err, causet.ErrLockOrActiveTransaction), IsTrue)
  4859  	_, err = tk.InterDirc("alter database test charset='utf8mb4'")
  4860  	c.Assert(terror.ErrorEqual(err, causet.ErrLockOrActiveTransaction), IsTrue)
  4861  	// Test alter/drop database when other stochastik is holding the causet locks of the database.
  4862  	tk2.MustInterDirc("create database test_lock2")
  4863  	_, err = tk2.InterDirc("drop database test")
  4864  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4865  	_, err = tk2.InterDirc("alter database test charset='utf8mb4'")
  4866  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4867  
  4868  	// Test for admin cleanup causet locks.
  4869  	tk.MustInterDirc("unlock blocks")
  4870  	tk.MustInterDirc("dagger causet t1 write, t2 write")
  4871  	_, err = tk2.InterDirc("dagger blocks t1 write, t2 read")
  4872  	c.Assert(terror.ErrorEqual(err, schemareplicant.ErrBlockLocked), IsTrue)
  4873  	tk2.MustInterDirc("admin cleanup causet dagger t1,t2")
  4874  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone)
  4875  	checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockNone)
  4876  	// cleanup unlocked causet.
  4877  	tk2.MustInterDirc("admin cleanup causet dagger t1,t2")
  4878  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone)
  4879  	checkBlockLock(c, tk.Se, "test", "t2", perceptron.BlockLockNone)
  4880  	tk2.MustInterDirc("dagger blocks t1 write, t2 read")
  4881  	checkBlockLock(c, tk2.Se, "test", "t1", perceptron.BlockLockWrite)
  4882  	checkBlockLock(c, tk2.Se, "test", "t2", perceptron.BlockLockRead)
  4883  
  4884  	tk.MustInterDirc("unlock blocks")
  4885  	tk2.MustInterDirc("unlock blocks")
  4886  }
  4887  
  4888  func (s *testDBSuite2) TestBlocksLockDelayClean(c *C) {
  4889  	if israce.RaceEnabled {
  4890  		c.Skip("skip race test")
  4891  	}
  4892  	tk := testkit.NewTestKit(c, s.causetstore)
  4893  	tk2 := testkit.NewTestKit(c, s.causetstore)
  4894  	tk2.MustInterDirc("use test")
  4895  	tk.MustInterDirc("use test")
  4896  	tk.MustInterDirc("drop causet if exists t1,t2")
  4897  	defer tk.MustInterDirc("drop causet if exists t1,t2")
  4898  	tk.MustInterDirc("create causet t1 (a int)")
  4899  	tk.MustInterDirc("create causet t2 (a int)")
  4900  
  4901  	tk.MustInterDirc("dagger blocks t1 write")
  4902  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite)
  4903  	config.UFIDelateGlobal(func(conf *config.Config) {
  4904  		conf.DelayCleanBlockLock = 100
  4905  	})
  4906  	var wg sync.WaitGroup
  4907  	wg.Add(1)
  4908  	var startTime time.Time
  4909  	go func() {
  4910  		startTime = time.Now()
  4911  		tk.Se.Close()
  4912  		wg.Done()
  4913  	}()
  4914  	time.Sleep(50 * time.Millisecond)
  4915  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockWrite)
  4916  	wg.Wait()
  4917  	c.Assert(time.Since(startTime).Seconds() > 0.1, IsTrue)
  4918  	checkBlockLock(c, tk.Se, "test", "t1", perceptron.BlockLockNone)
  4919  	config.UFIDelateGlobal(func(conf *config.Config) {
  4920  		conf.DelayCleanBlockLock = 0
  4921  	})
  4922  }
  4923  
  4924  // TestConcurrentLockBlocks test concurrent dagger/unlock blocks.
  4925  func (s *testDBSuite4) TestConcurrentLockBlocks(c *C) {
  4926  	if israce.RaceEnabled {
  4927  		c.Skip("skip race test")
  4928  	}
  4929  	tk := testkit.NewTestKit(c, s.causetstore)
  4930  	tk2 := testkit.NewTestKit(c, s.causetstore)
  4931  	tk.MustInterDirc("use test")
  4932  	tk.MustInterDirc("drop causet if exists t1")
  4933  	defer tk.MustInterDirc("drop causet if exists t1")
  4934  	tk.MustInterDirc("create causet t1 (a int)")
  4935  	tk2.MustInterDirc("use test")
  4936  
  4937  	// Test concurrent dagger blocks read.
  4938  	sql1 := "dagger blocks t1 read"
  4939  	sql2 := "dagger blocks t1 read"
  4940  	s.testParallelInterDircALLEGROSQL(c, sql1, sql2, tk.Se, tk2.Se, func(c *C, err1, err2 error) {
  4941  		c.Assert(err1, IsNil)
  4942  		c.Assert(err2, IsNil)
  4943  	})
  4944  	tk.MustInterDirc("unlock blocks")
  4945  	tk2.MustInterDirc("unlock blocks")
  4946  
  4947  	// Test concurrent dagger blocks write.
  4948  	sql1 = "dagger blocks t1 write"
  4949  	sql2 = "dagger blocks t1 write"
  4950  	s.testParallelInterDircALLEGROSQL(c, sql1, sql2, tk.Se, tk2.Se, func(c *C, err1, err2 error) {
  4951  		c.Assert(err1, IsNil)
  4952  		c.Assert(terror.ErrorEqual(err2, schemareplicant.ErrBlockLocked), IsTrue)
  4953  	})
  4954  	tk.MustInterDirc("unlock blocks")
  4955  	tk2.MustInterDirc("unlock blocks")
  4956  
  4957  	// Test concurrent dagger blocks write local.
  4958  	sql1 = "dagger blocks t1 write local"
  4959  	sql2 = "dagger blocks t1 write local"
  4960  	s.testParallelInterDircALLEGROSQL(c, sql1, sql2, tk.Se, tk2.Se, func(c *C, err1, err2 error) {
  4961  		c.Assert(err1, IsNil)
  4962  		c.Assert(terror.ErrorEqual(err2, schemareplicant.ErrBlockLocked), IsTrue)
  4963  	})
  4964  
  4965  	tk.MustInterDirc("unlock blocks")
  4966  	tk2.MustInterDirc("unlock blocks")
  4967  }
  4968  
  4969  func (s *testDBSuite4) testParallelInterDircALLEGROSQL(c *C, sql1, sql2 string, se1, se2 stochastik.Stochastik, f checkRet) {
  4970  	callback := &dbs.TestDBSCallback{}
  4971  	times := 0
  4972  	callback.OnJobRunBeforeExported = func(job *perceptron.Job) {
  4973  		if times != 0 {
  4974  			return
  4975  		}
  4976  		var qLen int
  4977  		for {
  4978  			err := ekv.RunInNewTxn(s.causetstore, false, func(txn ekv.Transaction) error {
  4979  				jobs, err1 := admin.GetDBSJobs(txn)
  4980  				if err1 != nil {
  4981  					return err1
  4982  				}
  4983  				qLen = len(jobs)
  4984  				return nil
  4985  			})
  4986  			c.Assert(err, IsNil)
  4987  			if qLen == 2 {
  4988  				break
  4989  			}
  4990  			time.Sleep(5 * time.Millisecond)
  4991  		}
  4992  		times++
  4993  	}
  4994  	d := s.dom.DBS()
  4995  	originalCallback := d.GetHook()
  4996  	defer d.(dbs.DBSForTest).SetHook(originalCallback)
  4997  	d.(dbs.DBSForTest).SetHook(callback)
  4998  
  4999  	wg := sync.WaitGroup{}
  5000  	var err1 error
  5001  	var err2 error
  5002  	wg.Add(2)
  5003  	ch := make(chan struct{})
  5004  	// Make sure the sql1 is put into the DBSJobQueue.
  5005  	go func() {
  5006  		var qLen int
  5007  		for {
  5008  			err := ekv.RunInNewTxn(s.causetstore, false, func(txn ekv.Transaction) error {
  5009  				jobs, err3 := admin.GetDBSJobs(txn)
  5010  				if err3 != nil {
  5011  					return err3
  5012  				}
  5013  				qLen = len(jobs)
  5014  				return nil
  5015  			})
  5016  			c.Assert(err, IsNil)
  5017  			if qLen == 1 {
  5018  				// Make sure sql2 is executed after the sql1.
  5019  				close(ch)
  5020  				break
  5021  			}
  5022  			time.Sleep(5 * time.Millisecond)
  5023  		}
  5024  	}()
  5025  	go func() {
  5026  		defer wg.Done()
  5027  		_, err1 = se1.InterDircute(context.Background(), sql1)
  5028  	}()
  5029  	go func() {
  5030  		defer wg.Done()
  5031  		<-ch
  5032  		_, err2 = se2.InterDircute(context.Background(), sql2)
  5033  	}()
  5034  
  5035  	wg.Wait()
  5036  	f(c, err1, err2)
  5037  }
  5038  
  5039  func checkBlockLock(c *C, se stochastik.Stochastik, dbName, blockName string, lockTp perceptron.BlockLockType) {
  5040  	tb := testGetBlockByName(c, se, dbName, blockName)
  5041  	dom := petri.GetPetri(se)
  5042  	if lockTp != perceptron.BlockLockNone {
  5043  		c.Assert(tb.Meta().Lock, NotNil)
  5044  		c.Assert(tb.Meta().Lock.Tp, Equals, lockTp)
  5045  		c.Assert(tb.Meta().Lock.State, Equals, perceptron.BlockLockStatePublic)
  5046  		c.Assert(len(tb.Meta().Lock.Stochastiks) == 1, IsTrue)
  5047  		c.Assert(tb.Meta().Lock.Stochastiks[0].ServerID, Equals, dom.DBS().GetID())
  5048  		c.Assert(tb.Meta().Lock.Stochastiks[0].StochastikID, Equals, se.GetStochastikVars().ConnectionID)
  5049  	} else {
  5050  		c.Assert(tb.Meta().Lock, IsNil)
  5051  	}
  5052  }
  5053  
  5054  func (s *testDBSuite2) TestDBSWithInvalidBlockInfo(c *C) {
  5055  	tk := testkit.NewTestKit(c, s.causetstore)
  5056  
  5057  	tk.MustInterDirc("use test")
  5058  	tk.MustInterDirc("drop causet if exists t")
  5059  	defer tk.MustInterDirc("drop causet if exists t")
  5060  	// Test create with invalid memex.
  5061  	_, err := tk.InterDirc(`CREATE TABLE t (
  5062  		c0 int(11) ,
  5063    		c1 int(11),
  5064      	c2 decimal(16,4) GENERATED ALWAYS AS ((case when (c0 = 0) then 0when (c0 > 0) then (c1 / c0) end))
  5065  	);`)
  5066  	c.Assert(err, NotNil)
  5067  	c.Assert(err.Error(), Equals, "[BerolinaSQL:1064]You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use line 4 defCausumn 88 near \"then (c1 / c0) end))\n\t);\" ")
  5068  
  5069  	tk.MustInterDirc("create causet t (a bigint, b int, c int generated always as (b+1)) partition by hash(a) partitions 4;")
  5070  	// Test drop partition defCausumn.
  5071  	_, err = tk.InterDirc("alter causet t drop defCausumn a;")
  5072  	c.Assert(err, NotNil)
  5073  	c.Assert(err.Error(), Equals, "[memex:1054]Unknown defCausumn 'a' in 'memex'")
  5074  	// Test modify defCausumn with invalid memex.
  5075  	_, err = tk.InterDirc("alter causet t modify defCausumn c int GENERATED ALWAYS AS ((case when (a = 0) then 0when (a > 0) then (b / a) end));")
  5076  	c.Assert(err, NotNil)
  5077  	c.Assert(err.Error(), Equals, "[BerolinaSQL:1064]You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use line 1 defCausumn 97 near \"then (b / a) end));\" ")
  5078  	// Test add defCausumn with invalid memex.
  5079  	_, err = tk.InterDirc("alter causet t add defCausumn d int GENERATED ALWAYS AS ((case when (a = 0) then 0when (a > 0) then (b / a) end));")
  5080  	c.Assert(err, NotNil)
  5081  	c.Assert(err.Error(), Equals, "[BerolinaSQL:1064]You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use line 1 defCausumn 94 near \"then (b / a) end));\" ")
  5082  }
  5083  
  5084  func (s *testDBSuite4) TestDeferredCausetCheck(c *C) {
  5085  	tk := testkit.NewTestKit(c, s.causetstore)
  5086  	tk.MustInterDirc("use " + s.schemaName)
  5087  	tk.MustInterDirc("drop causet if exists defCausumn_check")
  5088  	tk.MustInterDirc("create causet defCausumn_check (pk int primary key, a int check (a > 1))")
  5089  	defer tk.MustInterDirc("drop causet if exists defCausumn_check")
  5090  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  5091  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8231|DeferredCauset check is not supported"))
  5092  }
  5093  
  5094  func (s *testDBSuite5) TestAlterCheck(c *C) {
  5095  	tk := testkit.NewTestKit(c, s.causetstore)
  5096  	tk.MustInterDirc("use " + s.schemaName)
  5097  	tk.MustInterDirc("drop causet if exists alter_check")
  5098  	tk.MustInterDirc("create causet alter_check (pk int primary key)")
  5099  	defer tk.MustInterDirc("drop causet if exists alter_check")
  5100  	tk.MustInterDirc("alter causet alter_check alter check crcn ENFORCED")
  5101  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  5102  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8231|ALTER CHECK is not supported"))
  5103  }
  5104  
  5105  func (s *testDBSuite6) TestDropCheck(c *C) {
  5106  	tk := testkit.NewTestKit(c, s.causetstore)
  5107  	tk.MustInterDirc("use " + s.schemaName)
  5108  	tk.MustInterDirc("drop causet if exists drop_check")
  5109  	tk.MustInterDirc("create causet drop_check (pk int primary key)")
  5110  	defer tk.MustInterDirc("drop causet if exists drop_check")
  5111  	tk.MustInterDirc("alter causet drop_check drop check crcn")
  5112  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  5113  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8231|DROP CHECK is not supported"))
  5114  }
  5115  
  5116  func (s *testDBSuite7) TestAddConstraintCheck(c *C) {
  5117  	tk := testkit.NewTestKit(c, s.causetstore)
  5118  	tk.MustInterDirc("use " + s.schemaName)
  5119  	tk.MustInterDirc("drop causet if exists add_constraint_check")
  5120  	tk.MustInterDirc("create causet add_constraint_check (pk int primary key, a int)")
  5121  	defer tk.MustInterDirc("drop causet if exists add_constraint_check")
  5122  	tk.MustInterDirc("alter causet add_constraint_check add constraint crn check (a > 1)")
  5123  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  5124  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8231|ADD CONSTRAINT CHECK is not supported"))
  5125  }
  5126  
  5127  func (s *testDBSuite6) TestAlterOrderBy(c *C) {
  5128  	tk := testkit.NewTestKit(c, s.causetstore)
  5129  	tk.MustInterDirc("use " + s.schemaName)
  5130  	tk.MustInterDirc("create causet ob (pk int primary key, c int default 1, c1 int default 1, KEY cl(c1))")
  5131  
  5132  	// Test order by with primary key
  5133  	tk.MustInterDirc("alter causet ob order by c")
  5134  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  5135  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|1105|ORDER BY ignored as there is a user-defined clustered index in the causet 'ob'"))
  5136  
  5137  	// Test order by with no primary key
  5138  	tk.MustInterDirc("drop causet if exists ob")
  5139  	tk.MustInterDirc("create causet ob (c int default 1, c1 int default 1, KEY cl(c1))")
  5140  	tk.MustInterDirc("alter causet ob order by c")
  5141  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(0))
  5142  	tk.MustInterDirc("drop causet if exists ob")
  5143  }
  5144  
  5145  func (s *testSerialDBSuite) TestDBSJobErrorCount(c *C) {
  5146  	tk := testkit.NewTestKit(c, s.causetstore)
  5147  	tk.MustInterDirc("use test")
  5148  	tk.MustInterDirc("drop causet if exists dbs_error_block, new_dbs_error_block")
  5149  	tk.MustInterDirc("create causet dbs_error_block(a int)")
  5150  	is := s.dom.SchemaReplicant()
  5151  	schemaName := perceptron.NewCIStr("test")
  5152  	blockName := perceptron.NewCIStr("dbs_error_block")
  5153  	schemaReplicant, ok := is.SchemaByName(schemaName)
  5154  	c.Assert(ok, IsTrue)
  5155  	tbl, err := is.BlockByName(schemaName, blockName)
  5156  	c.Assert(err, IsNil)
  5157  
  5158  	newBlockName := perceptron.NewCIStr("new_dbs_error_block")
  5159  	job := &perceptron.Job{
  5160  		SchemaID:   schemaReplicant.ID,
  5161  		BlockID:    tbl.Meta().ID,
  5162  		SchemaName: schemaReplicant.Name.L,
  5163  		Type:       perceptron.CausetActionRenameBlock,
  5164  		BinlogInfo: &perceptron.HistoryInfo{},
  5165  		Args:       []interface{}{schemaReplicant.ID, newBlockName},
  5166  	}
  5167  
  5168  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/dbs/mockErrEntrySizeTooLarge", `return(true)`), IsNil)
  5169  	defer func() {
  5170  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/dbs/mockErrEntrySizeTooLarge"), IsNil)
  5171  	}()
  5172  
  5173  	txn, err := s.causetstore.Begin()
  5174  	c.Assert(err, IsNil)
  5175  	t := spacetime.NewMeta(txn)
  5176  	job.ID, err = t.GenGlobalID()
  5177  	c.Assert(err, IsNil)
  5178  	job.Version = 1
  5179  	job.StartTS = txn.StartTS()
  5180  
  5181  	err = t.EnQueueDBSJob(job)
  5182  	c.Assert(err, IsNil)
  5183  	err = txn.Commit(context.Background())
  5184  	c.Assert(err, IsNil)
  5185  
  5186  	ticker := time.NewTicker(s.lease)
  5187  	defer ticker.Stop()
  5188  	for range ticker.C {
  5189  		historyJob, err := getHistoryDBSJob(s.causetstore, job.ID)
  5190  		c.Assert(err, IsNil)
  5191  		if historyJob == nil {
  5192  			continue
  5193  		}
  5194  		c.Assert(historyJob.ErrorCount, Equals, int64(1), Commentf("%v", historyJob))
  5195  		ekv.ErrEntryTooLarge.Equal(historyJob.Error)
  5196  		break
  5197  	}
  5198  }
  5199  
  5200  func (s *testDBSuite1) TestAlterBlockWithValidation(c *C) {
  5201  	tk := testkit.NewTestKit(c, s.causetstore)
  5202  	tk.MustInterDirc("use test")
  5203  	tk.MustInterDirc("drop causet if exists t1")
  5204  	defer tk.MustInterDirc("drop causet if exists t1")
  5205  
  5206  	tk.MustInterDirc("create causet t1 (c1 int, c2 int as (c1 + 1));")
  5207  
  5208  	// Test for alter causet with validation.
  5209  	tk.MustInterDirc("alter causet t1 with validation")
  5210  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  5211  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8200|ALTER TABLE WITH VALIDATION is currently unsupported"))
  5212  
  5213  	// Test for alter causet without validation.
  5214  	tk.MustInterDirc("alter causet t1 without validation")
  5215  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.WarningCount(), Equals, uint16(1))
  5216  	tk.MustQuery("show warnings").Check(solitonutil.RowsWithSep("|", "Warning|8200|ALTER TABLE WITHOUT VALIDATION is currently unsupported"))
  5217  }
  5218  
  5219  func (s *testSerialDBSuite) TestCommitTxnWithIndexChange(c *C) {
  5220  	// Prepare work.
  5221  	tk := testkit.NewTestKit(c, s.causetstore)
  5222  	tk.MustInterDirc("drop database if exists test_db")
  5223  	tk.MustInterDirc("create database test_db")
  5224  	tk.MustInterDirc("use test_db")
  5225  	tk.MustInterDirc("create causet t1 (c1 int primary key, c2 int, c3 int, index ok2(c2))")
  5226  	tk.MustInterDirc("insert t1 values (1, 10, 100), (2, 20, 200)")
  5227  	tk.MustInterDirc("alter causet t1 add index k2(c2)")
  5228  	tk.MustInterDirc("alter causet t1 drop index k2")
  5229  	tk.MustInterDirc("alter causet t1 add index k2(c2)")
  5230  	tk.MustInterDirc("alter causet t1 drop index k2")
  5231  	tk2 := testkit.NewTestKit(c, s.causetstore)
  5232  	tk2.MustInterDirc("use test_db")
  5233  
  5234  	// tkALLEGROSQLs are the allegrosql memexs for the pessimistic transaction.
  5235  	// tk2DBS are the dbs memexs executed before the pessimistic transaction.
  5236  	// idxDBS is the DBS memex executed between pessimistic transaction begin and commit.
  5237  	// failCommit means the pessimistic transaction commit should fail not.
  5238  	type caseUnit struct {
  5239  		tkALLEGROSQLs    []string
  5240  		tk2DBS           []string
  5241  		idxDBS           string
  5242  		checkALLEGROSQLs []string
  5243  		rowsExps         [][]string
  5244  		failCommit       bool
  5245  		stateEnd         perceptron.SchemaState
  5246  	}
  5247  
  5248  	cases := []caseUnit{
  5249  		// Test secondary index
  5250  		{[]string{"insert into t1 values(3, 30, 300)",
  5251  			"insert into t2 values(11, 11, 11)"},
  5252  			[]string{"alter causet t1 add index k2(c2)",
  5253  				"alter causet t1 drop index k2",
  5254  				"alter causet t1 add index kk2(c2, c1)",
  5255  				"alter causet t1 add index k2(c2)",
  5256  				"alter causet t1 drop index k2"},
  5257  			"alter causet t1 add index k2(c2)",
  5258  			[]string{"select c3, c2 from t1 use index(k2) where c2 = 20",
  5259  				"select c3, c2 from t1 use index(k2) where c2 = 10",
  5260  				"select * from t1",
  5261  				"select * from t2 where c1 = 11"},
  5262  			[][]string{{"200 20"},
  5263  				{"100 10"},
  5264  				{"1 10 100", "2 20 200", "3 30 300"},
  5265  				{"11 11 11"}},
  5266  			false,
  5267  			perceptron.StateNone},
  5268  		// Test secondary index
  5269  		{[]string{"insert into t2 values(5, 50, 500)",
  5270  			"insert into t2 values(11, 11, 11)",
  5271  			"delete from t2 where c2 = 11",
  5272  			"uFIDelate t2 set c2 = 110 where c1 = 11"},
  5273  			//"uFIDelate t2 set c1 = 10 where c3 = 100"},
  5274  			[]string{"alter causet t1 add index k2(c2)",
  5275  				"alter causet t1 drop index k2",
  5276  				"alter causet t1 add index kk2(c2, c1)",
  5277  				"alter causet t1 add index k2(c2)",
  5278  				"alter causet t1 drop index k2"},
  5279  			"alter causet t1 add index k2(c2)",
  5280  			[]string{"select c3, c2 from t1 use index(k2) where c2 = 20",
  5281  				"select c3, c2 from t1 use index(k2) where c2 = 10",
  5282  				"select * from t1",
  5283  				"select * from t2 where c1 = 11",
  5284  				"select * from t2 where c3 = 100"},
  5285  			[][]string{{"200 20"},
  5286  				{"100 10"},
  5287  				{"1 10 100", "2 20 200"},
  5288  				{},
  5289  				{"1 10 100"}},
  5290  			false,
  5291  			perceptron.StateNone},
  5292  		// Test unique index
  5293  		/* TODO unique index is not supported now.
  5294  		{[]string{"insert into t1 values(3, 30, 300)",
  5295  			"insert into t1 values(4, 40, 400)",
  5296  			"insert into t2 values(11, 11, 11)",
  5297  			"insert into t2 values(12, 12, 11)"},
  5298  			[]string{"alter causet t1 add unique index uk3(c3)",
  5299  				"alter causet t1 drop index uk3",
  5300  				"alter causet t2 add unique index ukc1c3(c1, c3)",
  5301  				"alter causet t2 add unique index ukc3(c3)",
  5302  				"alter causet t2 drop index ukc1c3",
  5303  				"alter causet t2 drop index ukc3",
  5304  				"alter causet t2 add index kc3(c3)"},
  5305  			"alter causet t1 add unique index uk3(c3)",
  5306  			[]string{"select c3, c2 from t1 use index(uk3) where c3 = 200",
  5307  				"select c3, c2 from t1 use index(uk3) where c3 = 300",
  5308  				"select c3, c2 from t1 use index(uk3) where c3 = 400",
  5309  				"select * from t1",
  5310  				"select * from t2"},
  5311  			[][]string{{"200 20"},
  5312  				{"300 30"},
  5313  				{"400 40"},
  5314  				{"1 10 100", "2 20 200", "3 30 300", "4 40 400"},
  5315  				{"1 10 100", "2 20 200", "11 11 11", "12 12 11"}},
  5316  			false, perceptron.StateNone},
  5317  		// Test unique index fail to commit, this case needs the new index could be inserted
  5318  		{[]string{"insert into t1 values(3, 30, 300)",
  5319  			"insert into t1 values(4, 40, 300)",
  5320  			"insert into t2 values(11, 11, 11)",
  5321  			"insert into t2 values(12, 11, 12)"},
  5322  			//[]string{"alter causet t1 add unique index uk3(c3)", "alter causet t1 drop index uk3"},
  5323  			[]string{},
  5324  			"alter causet t1 add unique index uk3(c3)",
  5325  			[]string{"select c3, c2 from t1 use index(uk3) where c3 = 200",
  5326  				"select c3, c2 from t1 use index(uk3) where c3 = 300",
  5327  				"select c3, c2 from t1 where c1 = 4",
  5328  				"select * from t1",
  5329  				"select * from t2"},
  5330  			[][]string{{"200 20"},
  5331  				{},
  5332  				{},
  5333  				{"1 10 100", "2 20 200"},
  5334  				{"1 10 100", "2 20 200"}},
  5335  			true,
  5336  			perceptron.StateWriteOnly},
  5337  		*/
  5338  	}
  5339  	tk.MustQuery("select * from t1;").Check(testkit.Rows("1 10 100", "2 20 200"))
  5340  
  5341  	// Test add index state change
  5342  	do := s.dom.DBS()
  5343  	startStates := []perceptron.SchemaState{perceptron.StateNone, perceptron.StateDeleteOnly}
  5344  	for _, startState := range startStates {
  5345  		endStatMap := stochastik.ConstOpAddIndex[startState]
  5346  		var endStates []perceptron.SchemaState
  5347  		for st := range endStatMap {
  5348  			endStates = append(endStates, st)
  5349  		}
  5350  		sort.Slice(endStates, func(i, j int) bool { return endStates[i] < endStates[j] })
  5351  		for _, endState := range endStates {
  5352  			for _, curCase := range cases {
  5353  				if endState < curCase.stateEnd {
  5354  					break
  5355  				}
  5356  				tk2.MustInterDirc("drop causet if exists t1")
  5357  				tk2.MustInterDirc("drop causet if exists t2")
  5358  				tk2.MustInterDirc("create causet t1 (c1 int primary key, c2 int, c3 int, index ok2(c2))")
  5359  				tk2.MustInterDirc("create causet t2 (c1 int primary key, c2 int, c3 int, index ok2(c2))")
  5360  				tk2.MustInterDirc("insert t1 values (1, 10, 100), (2, 20, 200)")
  5361  				tk2.MustInterDirc("insert t2 values (1, 10, 100), (2, 20, 200)")
  5362  				tk2.MustQuery("select * from t1;").Check(testkit.Rows("1 10 100", "2 20 200"))
  5363  				tk.MustQuery("select * from t1;").Check(testkit.Rows("1 10 100", "2 20 200"))
  5364  				tk.MustQuery("select * from t2;").Check(testkit.Rows("1 10 100", "2 20 200"))
  5365  
  5366  				for _, DBSALLEGROSQL := range curCase.tk2DBS {
  5367  					tk2.MustInterDirc(DBSALLEGROSQL)
  5368  				}
  5369  				hook := &dbs.TestDBSCallback{}
  5370  				prepared := false
  5371  				committed := false
  5372  				hook.OnJobUFIDelatedExported = func(job *perceptron.Job) {
  5373  					if job.SchemaState == startState {
  5374  						if !prepared {
  5375  							tk.MustInterDirc("begin pessimistic")
  5376  							for _, tkALLEGROSQL := range curCase.tkALLEGROSQLs {
  5377  								tk.MustInterDirc(tkALLEGROSQL)
  5378  							}
  5379  							prepared = true
  5380  						}
  5381  					} else if job.SchemaState == endState {
  5382  						if !committed {
  5383  							if curCase.failCommit {
  5384  								_, err := tk.InterDirc("commit")
  5385  								c.Assert(err, NotNil)
  5386  							} else {
  5387  								tk.MustInterDirc("commit")
  5388  							}
  5389  						}
  5390  						committed = true
  5391  					}
  5392  				}
  5393  				originalCallback := do.GetHook()
  5394  				do.(dbs.DBSForTest).SetHook(hook)
  5395  				tk2.MustInterDirc(curCase.idxDBS)
  5396  				do.(dbs.DBSForTest).SetHook(originalCallback)
  5397  				tk2.MustInterDirc("admin check causet t1")
  5398  				for i, checkALLEGROSQL := range curCase.checkALLEGROSQLs {
  5399  					if len(curCase.rowsExps[i]) > 0 {
  5400  						tk2.MustQuery(checkALLEGROSQL).Check(testkit.Rows(curCase.rowsExps[i]...))
  5401  					} else {
  5402  						tk2.MustQuery(checkALLEGROSQL).Check(nil)
  5403  					}
  5404  				}
  5405  			}
  5406  		}
  5407  	}
  5408  	tk.MustInterDirc("admin check causet t1")
  5409  }
  5410  
  5411  // TestAddIndexFailOnCaseWhenCanExit is used to close #19325.
  5412  func (s *testSerialDBSuite) TestAddIndexFailOnCaseWhenCanExit(c *C) {
  5413  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/dbs/MockCaseWhenParseFailure", `return(true)`), IsNil)
  5414  	defer func() {
  5415  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/dbs/MockCaseWhenParseFailure"), IsNil)
  5416  	}()
  5417  	tk := testkit.NewTestKit(c, s.causetstore)
  5418  	tk.MustInterDirc("use test")
  5419  	tk.MustInterDirc("drop causet if exists t")
  5420  	tk.MustInterDirc("create causet t(a int, b int)")
  5421  	tk.MustInterDirc("insert into t values(1, 1)")
  5422  	_, err := tk.InterDirc("alter causet t add index idx(b)")
  5423  	c.Assert(err, NotNil)
  5424  	c.Assert(err.Error(), Equals, "[dbs:-1]DBS job rollback, error msg: job.ErrCount:512, mock unknown type: ast.whenClause.")
  5425  	tk.MustInterDirc("drop causet if exists t")
  5426  }
  5427  
  5428  func init() {
  5429  	// Make sure it will only be executed once.
  5430  	petri.SchemaOutOfDateRetryInterval = int64(50 * time.Millisecond)
  5431  	petri.SchemaOutOfDateRetryTimes = int32(50)
  5432  }
  5433  
  5434  func (s *testSerialDBSuite) TestCreateBlockWithIntegerLengthWaring(c *C) {
  5435  	// Inject the strict-integer-display-width variable in BerolinaSQL directly.
  5436  	BerolinaSQLtypes.MilevaDBStrictIntegerDisplayWidth = true
  5437  	defer func() {
  5438  		BerolinaSQLtypes.MilevaDBStrictIntegerDisplayWidth = false
  5439  	}()
  5440  	tk := testkit.NewTestKit(c, s.causetstore)
  5441  	tk.MustInterDirc("use test")
  5442  	tk.MustInterDirc("drop causet if exists t")
  5443  
  5444  	tk.MustInterDirc("create causet t(a tinyint(1))")
  5445  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5446  
  5447  	tk.MustInterDirc("drop causet if exists t")
  5448  	tk.MustInterDirc("create causet t(a smallint(2))")
  5449  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5450  
  5451  	tk.MustInterDirc("drop causet if exists t")
  5452  	tk.MustInterDirc("create causet t(a int(2))")
  5453  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5454  
  5455  	tk.MustInterDirc("drop causet if exists t")
  5456  	tk.MustInterDirc("create causet t(a mediumint(2))")
  5457  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5458  
  5459  	tk.MustInterDirc("drop causet if exists t")
  5460  	tk.MustInterDirc("create causet t(a bigint(2))")
  5461  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5462  
  5463  	tk.MustInterDirc("drop causet if exists t")
  5464  	tk.MustInterDirc("create causet t(a integer(2))")
  5465  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5466  
  5467  	tk.MustInterDirc("drop causet if exists t")
  5468  	tk.MustInterDirc("create causet t(a int1(1))")
  5469  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5470  
  5471  	tk.MustInterDirc("drop causet if exists t")
  5472  	tk.MustInterDirc("create causet t(a int2(2))")
  5473  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5474  
  5475  	tk.MustInterDirc("drop causet if exists t")
  5476  	tk.MustInterDirc("create causet t(a int3(2))")
  5477  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5478  
  5479  	tk.MustInterDirc("drop causet if exists t")
  5480  	tk.MustInterDirc("create causet t(a int4(2))")
  5481  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5482  
  5483  	tk.MustInterDirc("drop causet if exists t")
  5484  	tk.MustInterDirc("create causet t(a int8(2))")
  5485  	tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1064 You have an error in your ALLEGROALLEGROSQL syntax; check the manual that corresponds to your MilevaDB version for the right syntax to use [BerolinaSQL:1681]Integer display width is deprecated and will be removed in a future release."))
  5486  
  5487  	tk.MustInterDirc("drop causet if exists t")
  5488  }