Skip to content

Commit

Permalink
Check index (pingcap#19)
Browse files Browse the repository at this point in the history
* check index

* ddl, parser: support check addIndex and dropIndex
  • Loading branch information
Defined2014 committed Mar 11, 2022
1 parent 4bc1a96 commit fcfaca6
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 10 deletions.
14 changes: 14 additions & 0 deletions ddl/ddl_api.go
Expand Up @@ -5679,6 +5679,14 @@ func (d *ddl) CreateIndex(ctx sessionctx.Context, ti ast.Ident, keyType ast.Inde
Priority: ctx.GetSessionVars().DDLReorgPriority,
}

if info := ctx.GetSessionVars().StmtCtx.MultiSchemaInfo; info != nil {
info.AddIndexes = append(info.AddIndexes, &model.IndexInfo{
Name: indexName,
Columns: indexColumns,
State: model.StateNone,
})
}

err = d.doDDLJob(ctx, job)
// key exists, but if_not_exists flags is true, so we ignore this error.
if ErrDupKeyName.Equal(err) && ifNotExists {
Expand Down Expand Up @@ -5880,6 +5888,9 @@ func (d *ddl) DropIndex(ctx sessionctx.Context, ti ast.Ident, indexName model.CI
Args: []interface{}{indexName},
}

if info := ctx.GetSessionVars().StmtCtx.MultiSchemaInfo; info != nil {
info.DropIndexes = append(info.DropIndexes, indexInfo)
}
err = d.doDDLJob(ctx, job)
// index not exists, but if_exists flags is true, so we ignore this error.
if ErrCantDropFieldOrKey.Equal(err) && ifExists {
Expand Down Expand Up @@ -5922,6 +5933,9 @@ func (d *ddl) DropIndexes(ctx sessionctx.Context, ti ast.Ident, specs []*ast.Alt

indexNames = append(indexNames, indexName)
ifExists = append(ifExists, spec.IfExists)
if info := ctx.GetSessionVars().StmtCtx.MultiSchemaInfo; info != nil {
info.DropIndexes = append(info.DropIndexes, indexInfo)
}
}

job := &model.Job{
Expand Down
1 change: 1 addition & 0 deletions ddl/error.go
Expand Up @@ -32,6 +32,7 @@ var (
errCancelledDDLJob = dbterror.ClassDDL.NewStd(mysql.ErrCancelledDDLJob)
errRunMultiSchemaChanges = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message(fmt.Sprintf(mysql.MySQLErrName[mysql.ErrUnsupportedDDLOperation].Raw, "multi schema change"), nil))
errOperateSameColumn = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message(fmt.Sprintf(mysql.MySQLErrName[mysql.ErrUnsupportedDDLOperation].Raw, "operate same column '%s'"), nil))
errOperateSameIndex = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message(fmt.Sprintf(mysql.MySQLErrName[mysql.ErrUnsupportedDDLOperation].Raw, "operate same column '%s'"), nil))
errWaitReorgTimeout = dbterror.ClassDDL.NewStdErr(mysql.ErrLockWaitTimeout, mysql.MySQLErrName[mysql.ErrWaitReorgTimeout])
errInvalidStoreVer = dbterror.ClassDDL.NewStd(mysql.ErrInvalidStoreVersion)
// ErrRepairTableFail is used to repair tableInfo in repair mode.
Expand Down
21 changes: 21 additions & 0 deletions ddl/multi_schema_change.go
Expand Up @@ -147,6 +147,7 @@ func handleRevertibleException(job *model.Job, res model.JobState, idx int) {

func checkOperateSameColumn(info *model.MultiSchemaInfo) error {
modifyCols := make(map[string]struct{})
modifyIdx := make(map[string]struct{})
for _, col := range info.AddColumns {
name := col.Name.L
if _, ok := modifyCols[name]; ok {
Expand All @@ -161,6 +162,26 @@ func checkOperateSameColumn(info *model.MultiSchemaInfo) error {
}
modifyCols[name] = struct{}{}
}
for _, index := range info.AddIndexes {
idxName := index.Name.L
if _, ok := modifyIdx[idxName]; ok {
return errOperateSameIndex.GenWithStackByArgs(idxName)
}
modifyIdx[idxName] = struct{}{}
for _, col := range index.Columns {
colName := col.Name.L
if _, ok := modifyCols[colName]; ok {
return errOperateSameColumn.GenWithStackByArgs(colName)
}
}
}
for _, index := range info.DropIndexes {
idxName := index.Name.L
if _, ok := modifyIdx[idxName]; ok {
return errOperateSameIndex.GenWithStackByArgs(idxName)
}
modifyIdx[idxName] = struct{}{}
}
return nil
}

Expand Down
84 changes: 74 additions & 10 deletions ddl/multi_schema_change_test.go
Expand Up @@ -19,7 +19,6 @@ import (

"github.com/pingcap/tidb/errno"
"github.com/pingcap/tidb/testkit"
"github.com/stretchr/testify/require"
)

func TestMultiSchemaChangeAddColumns(t *testing.T) {
Expand All @@ -36,20 +35,20 @@ func TestMultiSchemaChangeAddColumns(t *testing.T) {
tk.MustQuery("select * from t;").Check(testkit.Rows("1 2 3"))

// Test add multiple columns in one spec.
tk.MustExec("drop table t;")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (a int);")
tk.MustExec("insert into t values (1);")
tk.MustExec("alter table t add column (b int default 2, c int default 3);")
tk.MustQuery("select * from t;").Check(testkit.Rows("1 2 3"))

// Test referencing previous column in multi-schema change is not supported.
tk.MustExec("drop table t;")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (a int);")
tk.MustGetErrCode("alter table t add column b int after a, add column c int after b", errno.ErrBadField)
tk.MustGetErrCode("alter table t add column c int after b, add column b int", errno.ErrBadField)

// Test add multiple columns with different position.
tk.MustExec("drop table t;")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (a int, b int, c int);")
tk.MustExec("insert into t values (1, 2, 3);")
tk.MustExec(`alter table t
Expand All @@ -65,6 +64,11 @@ func TestMultiSchemaChangeAddColumns(t *testing.T) {
tk.MustExec("alter table t add column b int default 2, add column if not exists a int;")
tk.MustQuery("show warnings;").Check(testkit.Rows("Note 1060 Duplicate column name 'a'"))
tk.MustQuery("select * from t;").Check(testkit.Rows("1 2"))

// Test add columns with same name
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (a int default 1, c int default 4);")
tk.MustGetErrCode("alter table t add column b int default 2, add column b int default 3", errno.ErrUnsupportedDDLOperation)
}

func TestMultiSchemaChangeDropColumns(t *testing.T) {
Expand All @@ -74,14 +78,21 @@ func TestMultiSchemaChangeDropColumns(t *testing.T) {
tk.MustExec("use test;")
tk.MustExec("set @@global.tidb_enable_change_multi_schema = 1;")

// Test drop all columns
tk.MustExec("create table t (a int, b int);")
tk.MustGetErrCode("alter table t drop column a, drop column b;", errno.ErrCantRemoveAllFields)

// Test drop multiple columns in multiple specs
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (a int, b int, c int, d int, e int);")
tk.MustExec("insert into t values (1, 2, 3, 4, 5);")
tk.MustExec("alter table t drop column a, drop column d, drop column b;")
tk.MustQuery("select * from t;").Check(testkit.Rows("3 5"))

// Test drop same column
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (a int default 1, c int default 4);")
tk.MustGetErrCode("alter table t drop column a, drop column a", errno.ErrUnsupportedDDLOperation)
}

func TestMultiSchemaChangeAddDropColumns(t *testing.T) {
Expand Down Expand Up @@ -115,16 +126,69 @@ func TestMultiSchemaChangeAddDropColumns(t *testing.T) {
tk.MustQuery("select * from t;").Check(testkit.Rows("4 3"))
}

func TestMultiSchemaChangeOperateSameColumn(t *testing.T) {
func TestMultiSchemaChangeAddIndexes(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@global.tidb_enable_change_multi_schema = 1")

// Test add multiple indexes with same column.
/*
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a int, b int, c int)")
tk.MustExec("alter table t add index t(a, b), add index t1(a)")
tk.MustExec("alter table t add index t2(a), add index t3(a, b)")
*/

// Test add multiple indexes with same name.
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a int, b int, c int)")
tk.MustGetErrCode("alter table t add index t(a), add index t(b)", errno.ErrUnsupportedDDLOperation)

// Test add indexes with drop column.
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a int, b int, c int)")
tk.MustGetErrCode("alter table t add index t(a), drop column a", errno.ErrUnsupportedDDLOperation)
tk.MustGetErrCode("alter table t add index t(a, b), drop column a", errno.ErrUnsupportedDDLOperation)
}

func TestMultiSchemaChangeDropIndexes(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@global.tidb_enable_change_multi_schema = 1")

// Test drop same index.
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a int, b int, c int, index t(a))")
tk.MustGetErrCode("alter table t drop index t, drop index t", errno.ErrUnsupportedDDLOperation)

// Test drop index with drop column.
/*
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a int default 1, b int default 2, c int default 3, index t(a))")
tk.MustExec("insert into t values ();")
tk.MustExec("alter table t drop index t, drop column a")
tk.MustGetErrCode("select * from t force index(t)", errno.ErrKeyDoesNotExist)
*/
}

func TestMultiSchemaChangeAddDropIndexes(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@global.tidb_enable_change_multi_schema = 1")

tk.MustExec("create table t (a int, c int)")
_, err := tk.Exec("alter table t add column b int default 2, add column b int default 3")
require.Equal(t, err.Error(), "[ddl:8200]Unsupported operate same column 'b'")
_, err = tk.Exec("alter table t drop column a, drop column a")
require.Equal(t, err.Error(), "[ddl:8200]Unsupported operate same column 'a'")
// Test add and drop same index.
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a int, b int, c int, index t(a))")
tk.MustGetErrCode("alter table t drop index t, add index t(b)", errno.ErrUnsupportedDDLOperation)

// Test add and drop same index.
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a int, b int, c int, index t(a))")
tk.MustGetErrCode("alter table t add index t1(b), drop index t1", errno.ErrUnsupportedDDLOperation)
}
2 changes: 2 additions & 0 deletions parser/model/ddl.go
Expand Up @@ -263,6 +263,8 @@ type MultiSchemaInfo struct {

AddColumns []*ColumnInfo `json:"add_columns"`
DropColumns []*ColumnInfo `json:"drop_columns"`
AddIndexes []*IndexInfo `json:"add_indexes"`
DropIndexes []*IndexInfo `json:"drop_indexes"`
}

func NewMultiSchemaInfo() *MultiSchemaInfo {
Expand Down

0 comments on commit fcfaca6

Please sign in to comment.