Files
tidb/br/pkg/restore/internal/prealloc_db/db_test.go

651 lines
22 KiB
Go

// Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0.
package preallocdb_test
import (
"context"
"fmt"
"math"
"strconv"
"sync"
"testing"
"github.com/pingcap/tidb/br/pkg/gluetidb"
"github.com/pingcap/tidb/br/pkg/metautil"
"github.com/pingcap/tidb/br/pkg/restore"
preallocdb "github.com/pingcap/tidb/br/pkg/restore/internal/prealloc_db"
prealloctableid "github.com/pingcap/tidb/br/pkg/restore/internal/prealloc_table_id"
"github.com/pingcap/tidb/br/pkg/utiltest"
"github.com/pingcap/tidb/pkg/domain"
"github.com/pingcap/tidb/pkg/kv"
"github.com/pingcap/tidb/pkg/meta"
"github.com/pingcap/tidb/pkg/meta/autoid"
"github.com/pingcap/tidb/pkg/meta/model"
pmodel "github.com/pingcap/tidb/pkg/parser/model"
"github.com/pingcap/tidb/pkg/parser/mysql"
"github.com/pingcap/tidb/pkg/parser/types"
"github.com/pingcap/tidb/pkg/testkit"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRestoreAutoIncID(t *testing.T) {
s := utiltest.CreateRestoreSchemaSuite(t)
tk := testkit.NewTestKit(t, s.Mock.Storage)
tk.MustExec("use test")
tk.MustExec("set @@sql_mode=''")
tk.MustExec("drop table if exists `\"t\"`;")
// Test SQL Mode
tk.MustExec("create table `\"t\"` (" +
"a int not null," +
"time timestamp not null default '0000-00-00 00:00:00');",
)
tk.MustExec("insert into `\"t\"` values (10, '0000-00-00 00:00:00');")
// Query the current AutoIncID
autoIncID, err := strconv.ParseUint(tk.MustQuery("admin show `\"t\"` next_row_id").Rows()[0][3].(string), 10, 64)
require.NoErrorf(t, err, "Error query auto inc id: %s", err)
// Get schemas of db and table
info, err := s.Mock.Domain.GetSnapshotInfoSchema(math.MaxUint64)
require.NoErrorf(t, err, "Error get snapshot info schema: %s", err)
dbInfo, exists := info.SchemaByName(pmodel.NewCIStr("test"))
require.Truef(t, exists, "Error get db info")
tableInfo, err := info.TableByName(context.Background(), pmodel.NewCIStr("test"), pmodel.NewCIStr("\"t\""))
require.NoErrorf(t, err, "Error get table info: %s", err)
table := metautil.Table{
Info: tableInfo.Meta(),
DB: dbInfo,
}
// Get the next AutoIncID
idAlloc := autoid.NewAllocator(s.Mock.Domain, dbInfo.ID, table.Info.ID, false, autoid.RowIDAllocType)
globalAutoID, err := idAlloc.NextGlobalAutoID()
require.NoErrorf(t, err, "Error allocate next auto id")
require.Equal(t, uint64(globalAutoID), autoIncID)
// Alter AutoIncID to the next AutoIncID + 100
table.Info.AutoIncID = globalAutoID + 100
db, _, err := preallocdb.NewDB(gluetidb.New(), s.Mock.Storage, "STRICT")
require.NoErrorf(t, err, "Error create DB")
tk.MustExec("drop database if exists test;")
// Test empty collate value
table.DB.Charset = "utf8mb4"
table.DB.Collate = ""
err = db.CreateDatabase(context.Background(), table.DB, false, nil)
require.NoErrorf(t, err, "Error create empty collate db: %s %s", err, s.Mock.DSN)
tk.MustExec("drop database if exists test;")
// Test empty charset value
table.DB.Charset = ""
table.DB.Collate = "utf8mb4_bin"
err = db.CreateDatabase(context.Background(), table.DB, false, nil)
require.NoErrorf(t, err, "Error create empty charset db: %s %s", err, s.Mock.DSN)
uniqueMap := make(map[restore.UniqueTableName]bool)
err = db.CreateTable(context.Background(), &table, uniqueMap, false, nil)
require.NoErrorf(t, err, "Error create table: %s %s", err, s.Mock.DSN)
tk.MustExec("use test")
autoIncID, err = strconv.ParseUint(tk.MustQuery("admin show `\"t\"` next_row_id").Rows()[0][3].(string), 10, 64)
require.NoErrorf(t, err, "Error query auto inc id: %s", err)
// Check if AutoIncID is altered successfully.
require.Equal(t, uint64(globalAutoID+100), autoIncID)
// try again, failed due to table exists.
table.Info.AutoIncID = globalAutoID + 200
err = db.CreateTable(context.Background(), &table, uniqueMap, false, nil)
require.NoError(t, err)
// Check if AutoIncID is not altered.
autoIncID, err = strconv.ParseUint(tk.MustQuery("admin show `\"t\"` next_row_id").Rows()[0][3].(string), 10, 64)
require.NoErrorf(t, err, "Error query auto inc id: %s", err)
require.Equal(t, uint64(globalAutoID+100), autoIncID)
// try again, success because we use alter sql in unique map.
table.Info.AutoIncID = globalAutoID + 300
uniqueMap[restore.UniqueTableName{DB: "test", Table: "\"t\""}] = true
err = db.CreateTable(context.Background(), &table, uniqueMap, false, nil)
require.NoError(t, err)
// Check if AutoIncID is altered to globalAutoID + 300.
autoIncID, err = strconv.ParseUint(tk.MustQuery("admin show `\"t\"` next_row_id").Rows()[0][3].(string), 10, 64)
require.NoErrorf(t, err, "Error query auto inc id: %s", err)
require.Equal(t, uint64(globalAutoID+300), autoIncID)
}
var createTableSQLs []string = []string{
"create table `test`.`t1` (id int);",
"create table `test`.`t2` (id int, created_at TIMESTAMP) TTL = `created_at` + INTERVAL 3 MONTH;",
"create sequence `test`.`t3` start 3 increment 2 minvalue 2 maxvalue 10 cache 3;",
"create sequence `test`.`t4` start 3 increment 2 minvalue 2 maxvalue 10 cache 3 cycle;",
"create view `test`.`t5` as select * from `test`.`t1`;",
"create table `test`.`t6` (id int, store_id INT NOT NULL) PARTITION BY RANGE (store_id) (" +
"PARTITION p0 VALUES LESS THAN (6)," +
"PARTITION p1 VALUES LESS THAN (11)," +
"PARTITION p2 VALUES LESS THAN MAXVALUE);",
"create sequence `test`.`t7` start 3 increment -2 minvalue 2 maxvalue 10 cache 3 cycle;",
}
var insertTableSQLs []string = []string{
//"SELECT NEXTVAL(`test`.`t3`);",
}
var checkTableSQLs = []func(t *testing.T, tk *testkit.TestKit, prefix string) error{
func(t *testing.T, tk *testkit.TestKit, prefix string) error { // test.t1
sql := fmt.Sprintf("show create table `test`.`%s1`;", prefix)
tk.MustQuery(sql)
return nil
},
func(t *testing.T, tk *testkit.TestKit, prefix string) error { // test.t2
sql := fmt.Sprintf("show create table `test`.`%s2`;", prefix)
rows := tk.MustQuery(sql).Rows()
require.Contains(t, rows[0][1], "TTL_ENABLE='OFF'")
return nil
},
func(t *testing.T, tk *testkit.TestKit, prefix string) error { // test.t3
sql := fmt.Sprintf("SELECT NEXTVAL(`test`.`%s3`);", prefix)
rows := tk.MustQuery(sql).Rows()
require.Contains(t, rows[0][0], "3")
return nil
},
func(t *testing.T, tk *testkit.TestKit, prefix string) error { // test.t4
sql := fmt.Sprintf("SELECT NEXTVAL(`test`.`%s4`);", prefix)
rows := tk.MustQuery(sql).Rows()
require.Contains(t, rows[0][0], "4")
return nil
},
func(t *testing.T, tk *testkit.TestKit, prefix string) error { // test.t5
sql := fmt.Sprintf("show create table `test`.`%s5`;", prefix)
tk.MustQuery(sql)
return nil
},
func(t *testing.T, tk *testkit.TestKit, prefix string) error { // test.t6
sql := fmt.Sprintf("show create table `test`.`%s6`;", prefix)
tk.MustQuery(sql)
return nil
},
func(t *testing.T, tk *testkit.TestKit, prefix string) error { // test.t7
sql := fmt.Sprintf("SELECT NEXTVAL(`test`.`%s7`);", prefix)
rows := tk.MustQuery(sql).Rows()
require.Contains(t, rows[0][0], "0")
return nil
},
}
func prepareAllocTables(
ctx context.Context,
t *testing.T,
db *preallocdb.DB,
dom *domain.Domain,
) (tableInfos []*metautil.Table) {
for _, sql := range createTableSQLs {
err := db.Session().Execute(ctx, sql)
require.NoError(t, err)
}
for _, sql := range insertTableSQLs {
err := db.Session().Execute(ctx, sql)
require.NoError(t, err)
}
info, err := dom.GetSnapshotInfoSchema(math.MaxUint64)
require.NoError(t, err)
dbInfo, exists := info.SchemaByName(pmodel.NewCIStr("test"))
require.True(t, exists)
tableInfos = make([]*metautil.Table, 0, 4)
for i := 1; i <= len(createTableSQLs); i += 1 {
tableName := fmt.Sprintf("t%d", i)
tableInfo, err := info.TableByName(context.Background(), pmodel.NewCIStr("test"), pmodel.NewCIStr(tableName))
require.NoError(t, err)
tableInfos = append(tableInfos, &metautil.Table{
DB: dbInfo.Clone(),
Info: tableInfo.Meta().Clone(),
})
}
return tableInfos
}
func cloneTableInfos(
ctx context.Context,
t *testing.T,
db *preallocdb.DB,
dom *domain.Domain,
prefix string,
originTableInfos []*metautil.Table,
) (tableInfos []*metautil.Table) {
// register preallocated ids
var ids *prealloctableid.PreallocIDs
ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnBR)
tableInfos = make([]*metautil.Table, 0, len(originTableInfos))
err := kv.RunInNewTxn(ctx, dom.Store(), true, func(_ context.Context, txn kv.Transaction) error {
allocater := meta.NewMeta(txn)
id, e := allocater.GetGlobalID()
if e != nil {
return e
}
// resign the table id
for i := int64(0); i < int64(len(createTableSQLs)); i += 1 {
newTableInfo := originTableInfos[i].Info.Clone()
newTableInfo.ID = id + i + 1
newTableInfo.Name = pmodel.NewCIStr(fmt.Sprintf("%s%d", prefix, i+1))
tableInfos = append(tableInfos, &metautil.Table{
DB: originTableInfos[i].DB.Clone(),
Info: newTableInfo,
})
}
ids = prealloctableid.New(tableInfos)
return ids.Alloc(allocater)
})
require.NoError(t, err)
db.RegisterPreallocatedIDs(ids)
return tableInfos
}
func fakePolicyInfo(ident byte) *model.PolicyInfo {
id := int64(ident)
uid := uint64(ident)
str := string(ident)
cistr := pmodel.NewCIStr(str)
return &model.PolicyInfo{
PlacementSettings: &model.PlacementSettings{
Followers: uid,
},
ID: id,
Name: cistr,
State: model.StatePublic,
}
}
func TestPolicyMode(t *testing.T) {
ctx := context.Background()
s := utiltest.CreateRestoreSchemaSuite(t)
tk := testkit.NewTestKit(t, s.Mock.Storage)
tk.MustExec("use test")
tk.MustExec("set @@sql_mode=''")
tk.MustExec("drop table if exists `t`;")
// Test SQL Mode
db, supportPolicy, err := preallocdb.NewDB(gluetidb.New(), s.Mock.Storage, "STRICT")
require.NoError(t, err)
require.True(t, supportPolicy)
defer db.Close()
// Prepare the tables
oriTableInfos := prepareAllocTables(ctx, t, db, s.Mock.Domain)
tableInfos := cloneTableInfos(ctx, t, db, s.Mock.Domain, "tt", oriTableInfos)
// Prepare policy map
policyMap := &sync.Map{}
fakepolicy1 := fakePolicyInfo(1)
fakepolicy2 := fakePolicyInfo(2)
policyMap.Store(fakepolicy1.Name.L, fakepolicy1)
policyMap.Store(fakepolicy2.Name.L, fakepolicy2)
tableInfos[0].Info.PlacementPolicyRef = &model.PolicyRefInfo{
ID: fakepolicy1.ID,
Name: fakepolicy1.Name,
}
tableInfos[5].Info.Partition.Definitions[0].PlacementPolicyRef = &model.PolicyRefInfo{
ID: fakepolicy2.ID,
Name: fakepolicy2.Name,
}
err = db.CreateTables(ctx, tableInfos, nil, true, policyMap)
require.NoError(t, err)
for _, checkFn := range checkTableSQLs {
checkFn(t, tk, "tt")
}
// clone again to test db.CreateTable
tableInfos = cloneTableInfos(ctx, t, db, s.Mock.Domain, "ttt", oriTableInfos)
// Prepare policy map
policyMap = &sync.Map{}
fakepolicy1 = fakePolicyInfo(1)
fakepolicy2 = fakePolicyInfo(2)
policyMap.Store(fakepolicy1.Name.L, fakepolicy1)
policyMap.Store(fakepolicy2.Name.L, fakepolicy2)
tableInfos[0].Info.PlacementPolicyRef = &model.PolicyRefInfo{
ID: fakepolicy1.ID,
Name: fakepolicy1.Name,
}
tableInfos[5].Info.Partition.Definitions[0].PlacementPolicyRef = &model.PolicyRefInfo{
ID: fakepolicy2.ID,
Name: fakepolicy2.Name,
}
for i := 0; i < len(createTableSQLs); i += 1 {
err = db.CreateTable(ctx, tableInfos[i], nil, true, policyMap)
require.NoError(t, err)
}
// test db.CreateDatabase
// Prepare policy map
policyMap = &sync.Map{}
fakepolicy1 = fakePolicyInfo(1)
policyMap.Store(fakepolicy1.Name.L, fakepolicy1)
err = db.CreateDatabase(ctx, &model.DBInfo{
ID: 20000,
Name: pmodel.NewCIStr("test_db"),
Charset: "utf8mb4",
Collate: "utf8mb4_bin",
State: model.StatePublic,
PlacementPolicyRef: &model.PolicyRefInfo{
ID: fakepolicy1.ID,
Name: fakepolicy1.Name,
},
}, true, policyMap)
require.NoError(t, err)
}
func TestUpdateMetaVersion(t *testing.T) {
ctx := context.Background()
s := utiltest.CreateRestoreSchemaSuite(t)
tk := testkit.NewTestKit(t, s.Mock.Storage)
tk.MustExec("use test")
tk.MustExec("set @@sql_mode=''")
tk.MustExec("drop table if exists `t`;")
// Test SQL Mode
db, supportPolicy, err := preallocdb.NewDB(gluetidb.New(), s.Mock.Storage, "STRICT")
require.NoError(t, err)
require.True(t, supportPolicy)
defer db.Close()
db.Session().Execute(ctx, "create table test.t (id int);")
db.Session().Execute(ctx, "analyze table test.t;")
db.Session().Execute(ctx, "insert into test.t values (1),(2),(3);")
info, err := s.Mock.Domain.GetSnapshotInfoSchema(math.MaxUint64)
require.NoError(t, err)
tableInfo, err := info.TableByName(context.Background(), pmodel.NewCIStr("test"), pmodel.NewCIStr("t"))
require.NoError(t, err)
restoreTS := uint64(0)
ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnBR)
err = kv.RunInNewTxn(ctx, s.Mock.Domain.Store(), true, func(_ context.Context, txn kv.Transaction) error {
restoreTS = txn.StartTS()
return nil
})
require.NoError(t, err)
tableID := tableInfo.Meta().ID
err = db.UpdateStatsMeta(ctx, tableID, restoreTS, 3)
require.NoError(t, err)
rows := tk.MustQuery("select version, table_id, modify_count, count, snapshot from mysql.stats_meta;").Rows()
require.Equal(t, fmt.Sprintf("%d", restoreTS), rows[0][0])
require.Equal(t, fmt.Sprintf("%d", tableID), rows[0][1])
require.Equal(t, "0", rows[0][2])
require.Equal(t, "3", rows[0][3])
require.Equal(t, fmt.Sprintf("%d", restoreTS), rows[0][4])
}
func TestCreateTablesInDb(t *testing.T) {
s := utiltest.CreateRestoreSchemaSuite(t)
info, err := s.Mock.Domain.GetSnapshotInfoSchema(math.MaxUint64)
require.NoErrorf(t, err, "Error get snapshot info schema: %s", err)
dbSchema, isExist := info.SchemaByName(pmodel.NewCIStr("test"))
require.True(t, isExist)
tables := make([]*metautil.Table, 4)
intField := types.NewFieldType(mysql.TypeLong)
intField.SetCharset("binary")
ddlJobMap := make(map[restore.UniqueTableName]bool)
for i := len(tables) - 1; i >= 0; i-- {
tables[i] = &metautil.Table{
DB: dbSchema,
Info: &model.TableInfo{
ID: int64(i),
Name: pmodel.NewCIStr("test" + strconv.Itoa(i)),
Columns: []*model.ColumnInfo{{
ID: 1,
Name: pmodel.NewCIStr("id"),
FieldType: *intField,
State: model.StatePublic,
}},
Charset: "utf8mb4",
Collate: "utf8mb4_bin",
},
}
ddlJobMap[restore.UniqueTableName{DB: dbSchema.Name.String(), Table: tables[i].Info.Name.String()}] = false
}
db, _, err := preallocdb.NewDB(gluetidb.New(), s.Mock.Storage, "STRICT")
require.NoError(t, err)
err = db.CreateTables(context.Background(), tables, ddlJobMap, false, nil)
require.NoError(t, err)
}
func TestDDLJobMap(t *testing.T) {
ctx := context.Background()
s := utiltest.CreateRestoreSchemaSuite(t)
tk := testkit.NewTestKit(t, s.Mock.Storage)
tk.MustExec("use test")
tk.MustExec("set @@sql_mode=''")
db, supportPolicy, err := preallocdb.NewDB(gluetidb.New(), s.Mock.Storage, "STRICT")
require.NoError(t, err)
require.True(t, supportPolicy)
defer db.Close()
db.Session().Execute(ctx, "CREATE TABLE test.t1 (a BIGINT PRIMARY KEY AUTO_RANDOM, b VARCHAR(255));")
db.Session().Execute(ctx, "CREATE TABLE test.t2 (a BIGINT AUTO_RANDOM, b VARCHAR(255), PRIMARY KEY (`a`, `b`));")
db.Session().Execute(ctx, "CREATE TABLE test.t3 (a BIGINT PRIMARY KEY AUTO_INCREMENT, b VARCHAR(255));")
db.Session().Execute(ctx, "CREATE TABLE test.t4 (a BIGINT, b VARCHAR(255));")
db.Session().Execute(ctx, "CREATE TABLE test.t5 (a BIGINT PRIMARY KEY, b VARCHAR(255));")
info, err := s.Mock.Domain.GetSnapshotInfoSchema(math.MaxUint64)
require.NoError(t, err)
dbInfo, exists := info.SchemaByName(pmodel.NewCIStr("test"))
require.True(t, exists)
tableInfo1, err := info.TableByName(context.Background(), pmodel.NewCIStr("test"), pmodel.NewCIStr("t1"))
require.NoError(t, err)
tableInfo2, err := info.TableByName(context.Background(), pmodel.NewCIStr("test"), pmodel.NewCIStr("t2"))
require.NoError(t, err)
tableInfo3, err := info.TableByName(context.Background(), pmodel.NewCIStr("test"), pmodel.NewCIStr("t3"))
require.NoError(t, err)
tableInfo4, err := info.TableByName(context.Background(), pmodel.NewCIStr("test"), pmodel.NewCIStr("t4"))
require.NoError(t, err)
tableInfo5, err := info.TableByName(context.Background(), pmodel.NewCIStr("test"), pmodel.NewCIStr("t5"))
require.NoError(t, err)
toBeCorrectedTables := map[restore.UniqueTableName]bool{
{DB: "test", Table: "t1"}: true,
{DB: "test", Table: "t2"}: true,
{DB: "test", Table: "t3"}: true,
{DB: "test", Table: "t4"}: true,
{DB: "test", Table: "t5"}: true,
}
err = db.CreateTablePostRestore(ctx, &metautil.Table{DB: dbInfo.Clone(), Info: tableInfo1.Meta().Clone()}, toBeCorrectedTables)
require.NoError(t, err)
err = db.CreateTablePostRestore(ctx, &metautil.Table{DB: dbInfo.Clone(), Info: tableInfo2.Meta().Clone()}, toBeCorrectedTables)
require.NoError(t, err)
err = db.CreateTablePostRestore(ctx, &metautil.Table{DB: dbInfo.Clone(), Info: tableInfo3.Meta().Clone()}, toBeCorrectedTables)
require.NoError(t, err)
err = db.CreateTablePostRestore(ctx, &metautil.Table{DB: dbInfo.Clone(), Info: tableInfo4.Meta().Clone()}, toBeCorrectedTables)
require.NoError(t, err)
err = db.CreateTablePostRestore(ctx, &metautil.Table{DB: dbInfo.Clone(), Info: tableInfo5.Meta().Clone()}, toBeCorrectedTables)
require.NoError(t, err)
}
func TestDB_ExecDDL(t *testing.T) {
s := utiltest.CreateRestoreSchemaSuite(t)
ctx := context.Background()
ddlJobs := []*model.Job{
{
Type: model.ActionAddIndex,
Query: "CREATE DATABASE IF NOT EXISTS test_db;",
BinlogInfo: &model.HistoryInfo{},
},
{
Type: model.ActionAddIndex,
Query: "",
BinlogInfo: &model.HistoryInfo{},
},
}
db, _, err := preallocdb.NewDB(gluetidb.New(), s.Mock.Storage, "STRICT")
require.NoError(t, err)
for _, ddlJob := range ddlJobs {
err = db.ExecDDL(ctx, ddlJob)
assert.NoError(t, err)
}
}
func TestDB_ExecDDL2(t *testing.T) {
s := utiltest.CreateRestoreSchemaSuite(t)
ctx := context.Background()
fieldType := types.NewFieldType(8)
fieldType.SetFlen(20)
fieldType.SetCharset("binary")
fieldType.SetCollate("binary")
ddlJobs := []*model.Job{
{
Type: model.ActionCreateSchema,
Query: "CREATE DATABASE IF NOT EXISTS test_db;",
BinlogInfo: &model.HistoryInfo{
DBInfo: &model.DBInfo{
ID: 20000,
Name: pmodel.NewCIStr("test_db"),
Charset: "utf8mb4",
Collate: "utf8mb4_bin",
State: model.StatePublic,
},
},
},
{
SchemaName: "test_db",
Type: model.ActionCreateTable,
Query: "CREATE TABLE test_db.t1 (id BIGINT);",
BinlogInfo: &model.HistoryInfo{
TableInfo: &model.TableInfo{
ID: 20000,
Name: pmodel.NewCIStr("t1"),
Charset: "utf8mb4",
Collate: "utf8mb4_bin",
Columns: []*model.ColumnInfo{
{
ID: 1,
Name: pmodel.NewCIStr("id"),
FieldType: *fieldType,
State: model.StatePublic,
Version: 2,
},
},
},
},
},
{
SchemaName: "test_db",
Type: model.ActionAddIndex,
Query: "ALTER TABLE test_db.t1 ADD INDEX i1(id);",
BinlogInfo: &model.HistoryInfo{
TableInfo: &model.TableInfo{},
},
},
}
db, _, err := preallocdb.NewDB(gluetidb.New(), s.Mock.Storage, "STRICT")
require.NoError(t, err)
for _, ddlJob := range ddlJobs {
err = db.ExecDDL(ctx, ddlJob)
assert.NoError(t, err)
}
}
func TestCreateTableConsistent(t *testing.T) {
ctx := context.Background()
s := utiltest.CreateRestoreSchemaSuite(t)
tk := testkit.NewTestKit(t, s.Mock.Storage)
tk.MustExec("use test")
tk.MustExec("set @@sql_mode=''")
db, supportPolicy, err := preallocdb.NewDB(gluetidb.New(), s.Mock.Storage, "STRICT")
require.NoError(t, err)
require.True(t, supportPolicy)
defer db.Close()
getTableInfo := func(name string) (*model.DBInfo, *model.TableInfo) {
info, err := s.Mock.Domain.GetSnapshotInfoSchema(math.MaxUint64)
require.NoError(t, err)
dbInfo, exists := info.SchemaByName(pmodel.NewCIStr("test"))
require.True(t, exists)
tableInfo, err := info.TableByName(context.Background(), pmodel.NewCIStr("test"), pmodel.NewCIStr(name))
require.NoError(t, err)
return dbInfo, tableInfo.Meta()
}
tk.MustExec("create sequence test.s increment by 1 minvalue = 10;")
dbInfo, seqInfo := getTableInfo("s")
tk.MustExec("drop sequence test.s;")
newSeqInfo := seqInfo.Clone()
newSeqInfo.ID += 100
newTables := []*metautil.Table{
{
DB: dbInfo.Clone(),
Info: newSeqInfo,
},
}
err = db.CreateTables(ctx, newTables, nil, false, nil)
require.NoError(t, err)
r11 := tk.MustQuery("select nextval(s)").Rows()
r12 := tk.MustQuery("show create table test.s").Rows()
tk.MustExec("drop sequence test.s;")
newSeqInfo = seqInfo.Clone()
newSeqInfo.ID += 100
newTable := &metautil.Table{DB: dbInfo.Clone(), Info: newSeqInfo}
err = db.CreateTable(ctx, newTable, nil, false, nil)
require.NoError(t, err)
r21 := tk.MustQuery("select nextval(s)").Rows()
r22 := tk.MustQuery("show create table test.s").Rows()
require.Equal(t, r11, r21)
require.Equal(t, r12, r22)
tk.MustExec("drop sequence test.s;")
tk.MustExec("create table t (a int);")
tk.MustExec("create view v as select * from t;")
_, tblInfo := getTableInfo("t")
_, viewInfo := getTableInfo("v")
tk.MustExec("drop table t;")
tk.MustExec("drop view v;")
newTblInfo := tblInfo.Clone()
newTblInfo.ID += 100
newViewInfo := viewInfo.Clone()
newViewInfo.ID += 100
newTables = []*metautil.Table{
{
DB: dbInfo.Clone(),
Info: newTblInfo,
},
{
DB: dbInfo.Clone(),
Info: newViewInfo,
},
}
err = db.CreateTables(ctx, newTables, nil, false, nil)
require.NoError(t, err)
r11 = tk.MustQuery("show create table t;").Rows()
r12 = tk.MustQuery("show create view v;").Rows()
tk.MustExec("drop table t;")
tk.MustExec("drop view v;")
newTblInfo = tblInfo.Clone()
newTblInfo.ID += 200
newTable = &metautil.Table{DB: dbInfo.Clone(), Info: newTblInfo}
err = db.CreateTable(ctx, newTable, nil, false, nil)
require.NoError(t, err)
newViewInfo = viewInfo.Clone()
newViewInfo.ID += 200
newTable = &metautil.Table{DB: dbInfo.Clone(), Info: newViewInfo}
err = db.CreateTable(ctx, newTable, nil, false, nil)
require.NoError(t, err)
r21 = tk.MustQuery("show create table t;").Rows()
r22 = tk.MustQuery("show create view v;").Rows()
require.Equal(t, r11, r21)
require.Equal(t, r12, r22)
}