Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check index #19

Merged
merged 2 commits into from
Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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