Skip to content

Commit

Permalink
ddl: check duplicated cols when execute alter table add index (pingca…
Browse files Browse the repository at this point in the history
  • Loading branch information
XuHuaiyu authored Nov 28, 2016
1 parent 633a66e commit 2c34a75
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 2 deletions.
18 changes: 18 additions & 0 deletions ddl/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,10 @@ func getAnonymousIndex(t table.Table, colName model.CIStr) model.CIStr {
}

func (d *ddl) CreateIndex(ctx context.Context, ti ast.Ident, unique bool, indexName model.CIStr, idxColNames []*ast.IndexColName) error {
err := checkDuplicateColumnName(idxColNames)
if err != nil {
return errors.Trace(err)
}
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
Expand Down Expand Up @@ -1429,6 +1433,20 @@ func findCol(cols []*model.ColumnInfo, name string) *model.ColumnInfo {
return nil
}

// checkDuplicateColumnName checks if index exists duplicated columns.
func checkDuplicateColumnName(indexColNames []*ast.IndexColName) error {
for i := 0; i < len(indexColNames); i++ {
name1 := indexColNames[i].Column.Name
for j := i + 1; j < len(indexColNames); j++ {
name2 := indexColNames[j].Column.Name
if name1.L == name2.L {
return infoschema.ErrColumnExists.GenByArgs(name2)
}
}
}
return nil
}

// DDL error codes.
const (
codeInvalidWorker terror.ErrCode = 1
Expand Down
22 changes: 22 additions & 0 deletions ddl/ddl_db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/pingcap/tidb"
_ "github.com/pingcap/tidb"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/model"
Expand Down Expand Up @@ -148,6 +149,7 @@ func (s *testDBSuite) TestIndex(c *C) {
s.testAddAnonymousIndex(c)
s.testDropIndex(c)
s.testAddUniqueIndexRollback(c)
s.testAddIndexWithDupCols(c)
}

func (s *testDBSuite) testGetTable(c *C, name string) table.Table {
Expand Down Expand Up @@ -470,6 +472,26 @@ LOOP:
c.Assert(handles, HasLen, 0)
}

func (s *testDBSuite) testAddIndexWithDupCols(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("use " + s.schemaName)
err1 := infoschema.ErrColumnExists.GenByArgs("b")
err2 := infoschema.ErrColumnExists.GenByArgs("B")

s.tk.MustExec("create table t (a int, b int)")
_, err := s.tk.Exec("create index c on t(b, a, b)")
c.Check(err1.Equal(err), Equals, true)

_, err = s.tk.Exec("create index c on t(b, a, B)")
c.Check(err2.Equal(err), Equals, true)

_, err = s.tk.Exec("alter table t add index c (b, a, b)")
c.Check(err1.Equal(err), Equals, true)

_, err = s.tk.Exec("alter table t add index c (b, a, B)")
c.Check(err2.Equal(err), Equals, true)
}

func (s *testDBSuite) showColumns(c *C, tableName string) [][]interface{} {
return s.mustQuery(c, fmt.Sprintf("show columns from %s", tableName))
}
Expand Down
3 changes: 2 additions & 1 deletion plan/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/juju/errors"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/parser"
"github.com/pingcap/tidb/util/types"
Expand Down Expand Up @@ -212,7 +213,7 @@ func (v *validator) checkCreateIndexGrammar(stmt *ast.CreateIndexStmt) {
for j := i + 1; j < len(stmt.IndexColNames); j++ {
name2 := stmt.IndexColNames[j].Column.Name
if name1.L == name2.L {
v.err = errors.Errorf("Duplicate column name '%s'", name1.O)
v.err = infoschema.ErrColumnExists.GenByArgs(name2)
return
}
}
Expand Down
2 changes: 1 addition & 1 deletion plan/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (s *testValidatorSuite) TestValidator(c *C) {
{"create table t(id float auto_increment, key (id))", true, nil},
{"create table t(id int auto_increment) ENGINE=MYISAM", true, nil},
{"create table t(a int primary key, b int, c varchar(10), d char(256));", true, errors.New("Column length too big for column 'd' (max = 255); use BLOB or TEXT instead")},
{"create index ib on t(b,a,b);", true, errors.New("Duplicate column name 'b'")},
{"create index ib on t(b,a,b);", true, errors.New("[schema:1060]Duplicate column name 'b'")},
{"create table t(c1 int not null primary key, c2 int not null primary key)", true, errors.New("Multiple primary key defined")},
}
store, err := tidb.NewStore(tidb.EngineGoLevelDBMemory)
Expand Down

0 comments on commit 2c34a75

Please sign in to comment.