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

*: support IF EXISTS/IF NOT EXISTS for some DDLs #10723

Merged
merged 13 commits into from
Jun 24, 2019
Merged
45 changes: 45 additions & 0 deletions ddl/db_change_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,51 @@ func (s *testStateChangeSuite) TestCreateDBIfNotExists(c *C) {
s.testParallelExecSQL(c, "create database if not exists test_not_exists;")
}

// TestDDLIfNotExists parallel exec some DDLs with `if not exists` clause. No error returns is expected.
func (s *testStateChangeSuite) TestDDLIfNotExists(c *C) {
defer s.se.Execute(context.Background(), "drop table test_not_exists")
_, err := s.se.Execute(context.Background(), "create table if not exists test_not_exists(a int)")
c.Assert(err, IsNil)

// ADD COLUMN
s.testParallelExecSQL(c, "alter table test_not_exists add column if not exists b int")

// ADD INDEX
s.testParallelExecSQL(c, "alter table test_not_exists add index if not exists idx_b (b)")
tiancaiamao marked this conversation as resolved.
Show resolved Hide resolved

// CREATE INDEX
s.testParallelExecSQL(c, "create index if not exists idx_b on test_not_exists (b)")
}

// TestDDLIfExists parallel exec some DDLs with `if exists` clause. No error returns is expected.
func (s *testStateChangeSuite) TestDDLIfExists(c *C) {
defer func() {
s.se.Execute(context.Background(), "drop table test_exists")
s.se.Execute(context.Background(), "drop table test_exists_2")
}()
_, err := s.se.Execute(context.Background(), "create table if not exists test_exists (a int key, b int)")
c.Assert(err, IsNil)

// DROP COLUMN
s.testParallelExecSQL(c, "alter table test_exists drop column if exists b") // only `a` exists now

// CHANGE COLUMN
s.testParallelExecSQL(c, "alter table test_exists change column if exists a c int") // only, `c` exists now

// MODIFY COLUMN
s.testParallelExecSQL(c, "alter table test_exists modify column if exists a bigint")

// DROP INDEX
_, err = s.se.Execute(context.Background(), "alter table test_exists add index idx_c (c)")
c.Assert(err, IsNil)
s.testParallelExecSQL(c, "alter table test_exists drop index if exists idx_c")

// DROP PARTITION (ADD PARTITION tested in TestParallelAlterAddPartition)
_, err = s.se.Execute(context.Background(), "create table test_exists_2 (a int key) partition by range(a) (partition p0 values less than (10), partition p1 values less than (20))")
c.Assert(err, IsNil)
s.testParallelExecSQL(c, "alter table test_exists_2 drop partition if exists p1")
}

// TestParallelDDLBeforeRunDDLJob tests a session to execute DDL with an outdated information schema.
// This test is used to simulate the following conditions:
// In a cluster, TiDB "a" executes the DDL.
Expand Down
72 changes: 72 additions & 0 deletions ddl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2641,6 +2641,78 @@ func (s *testDBSuite4) TestAddColumn2(c *C) {
s.tk.MustQuery("select a,b,_tidb_rowid from t2").Check(testkit.Rows("1 3 2"))
}

func (s *testDBSuite4) TestIfNotExists(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("use test_db")
s.mustExec(c, "drop table if exists t1")
s.mustExec(c, "create table t1 (a int key);")

// ADD COLUMN
sql := "alter table t1 add column b int"
s.mustExec(c, sql)
assertErrorCode(c, s.tk, sql, tmysql.ErrDupFieldName)
s.mustExec(c, "alter table t1 add column if not exists b int")

// ADD INDEX
sql = "alter table t1 add index idx_b (b)"
s.mustExec(c, sql)
assertErrorCode(c, s.tk, sql, tmysql.ErrDupKeyName)
s.mustExec(c, "alter table t1 add index if not exists idx_b (b)")

// CREATE INDEX
sql = "create index idx_b on t1 (b)"
assertErrorCode(c, s.tk, sql, tmysql.ErrDupKeyName)
s.mustExec(c, "create index if not exists idx_b on t1 (b)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the result of show warnings?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 2769cf1.


// ADD PARTITION
s.mustExec(c, "drop table if exists t2")
s.mustExec(c, "create table t2 (a int key) partition by range(a) (partition p0 values less than (10), partition p1 values less than (20))")
sql = "alter table t2 add partition (partition p2 values less than (30))"
s.mustExec(c, sql)
assertErrorCode(c, s.tk, sql, tmysql.ErrSameNamePartition)
s.mustExec(c, "alter table t2 add partition if not exists (partition p2 values less than (30))")
}

func (s *testDBSuite4) TestIfExists(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("use test_db")
s.mustExec(c, "drop table if exists t1")
s.mustExec(c, "create table t1 (a int key, b int);")

// DROP COLUMN
sql := "alter table t1 drop column b"
s.mustExec(c, sql)
assertErrorCode(c, s.tk, sql, tmysql.ErrCantDropFieldOrKey)
s.mustExec(c, "alter table t1 drop column if exists b") // only `a` exists now

// CHANGE COLUMN
sql = "alter table t1 change column b c int"
assertErrorCode(c, s.tk, sql, tmysql.ErrBadField)
s.mustExec(c, "alter table t1 change column if exists b c int")
s.mustExec(c, "alter table t1 change column if exists a c int") // only `c` exists now

// MODIFY COLUMN
sql = "alter table t1 modify column a bigint"
assertErrorCode(c, s.tk, sql, tmysql.ErrBadField)
s.mustExec(c, "alter table t1 modify column if exists a bigint")
s.mustExec(c, "alter table t1 modify column if exists c bigint") // only `c` exists now

// DROP INDEX
s.mustExec(c, "alter table t1 add index idx_c (c)")
sql = "alter table t1 drop index idx_c"
s.mustExec(c, sql)
assertErrorCode(c, s.tk, sql, tmysql.ErrCantDropFieldOrKey)
s.mustExec(c, "alter table t1 drop index if exists idx_c")

// DROP PARTITION
s.mustExec(c, "drop table if exists t2")
s.mustExec(c, "create table t2 (a int key) partition by range(a) (partition p0 values less than (10), partition p1 values less than (20))")
sql = "alter table t2 drop partition p1"
s.mustExec(c, sql)
assertErrorCode(c, s.tk, sql, tmysql.ErrDropPartitionNonExistent)
tiancaiamao marked this conversation as resolved.
Show resolved Hide resolved
s.mustExec(c, "alter table t2 drop partition if exists p1")
}

func (s *testDBSuite5) TestAddIndexForGeneratedColumn(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("use test_db")
Expand Down
4 changes: 2 additions & 2 deletions ddl/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,8 @@ type DDL interface {
RecoverTable(ctx sessionctx.Context, tbInfo *model.TableInfo, schemaID, autoID, dropJobID int64, snapshotTS uint64) (err error)
DropView(ctx sessionctx.Context, tableIdent ast.Ident) (err error)
CreateIndex(ctx sessionctx.Context, tableIdent ast.Ident, unique bool, indexName model.CIStr,
columnNames []*ast.IndexColName, indexOption *ast.IndexOption) error
DropIndex(ctx sessionctx.Context, tableIdent ast.Ident, indexName model.CIStr) error
columnNames []*ast.IndexColName, indexOption *ast.IndexOption, ifNotExists bool) error
tiancaiamao marked this conversation as resolved.
Show resolved Hide resolved
DropIndex(ctx sessionctx.Context, tableIdent ast.Ident, indexName model.CIStr, ifExists bool) error
AlterTable(ctx sessionctx.Context, tableIdent ast.Ident, spec []*ast.AlterTableSpec) error
TruncateTable(ctx sessionctx.Context, tableIdent ast.Ident) error
RenameTable(ctx sessionctx.Context, oldTableIdent, newTableIdent ast.Ident, isAlterTable bool) error
Expand Down
Loading