From 9014ceee698a9976110bf2f3195d8da21612e4af Mon Sep 17 00:00:00 2001 From: Maxwell Date: Fri, 15 May 2020 14:38:19 +0800 Subject: [PATCH] ddl: fix bug when add expression index (#17151) --- ddl/db_integration_test.go | 6 ++++++ ddl/ddl_api.go | 16 ++++++++++++++++ ddl/index.go | 8 ++++++++ 3 files changed, 30 insertions(+) diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go index fc46f3fbc8..c9dfb1d1f6 100644 --- a/ddl/db_integration_test.go +++ b/ddl/db_integration_test.go @@ -2094,6 +2094,12 @@ func (s *testIntegrationSuite7) TestAddExpressionIndex(c *C) { tk.MustQuery("select * from t;").Check(testkit.Rows("1 2.1")) + // Issue #17111 + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1 (a varchar(10), b varchar(10));") + tk.MustExec("alter table t1 add unique index ei_ab ((concat(a, b)));") + tk.MustExec("alter table t1 alter index ei_ab invisible;") + // Test experiment switch. config.GetGlobalConfig().Experimental.AllowsExpressionIndex = false tk.MustGetErrMsg("create index d on t((a+1))", "[ddl:8200]Unsupported creating expression index without allow-expression-index in config") diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index e25ddba05d..be3d7f33b8 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1133,16 +1133,32 @@ func getPrimaryKey(tblInfo *model.TableInfo) *model.IndexInfo { // table has explicit primary key return key } + // The case index without any columns should never happen, but still do a check here + if len(key.Columns) == 0 { + continue + } // find the first unique key with NOT NULL columns if implicitPK == nil && key.Unique { // ensure all columns in unique key have NOT NULL flag allColNotNull := true + skip := false for _, idxCol := range key.Columns { col := model.FindColumnInfo(tblInfo.Cols(), idxCol.Name.L) + // This index has a column in DeleteOnly state, + // or it is expression index (it defined on a hidden column), + // it can not be implicit PK, go to next index iterator + if col == nil || col.Hidden { + skip = true + break + } if !mysql.HasNotNullFlag(col.Flag) { allColNotNull = false + break } } + if skip { + continue + } if allColNotNull { implicitPK = key } diff --git a/ddl/index.go b/ddl/index.go index 1fa3c1c5f1..aa36b220ec 100755 --- a/ddl/index.go +++ b/ddl/index.go @@ -483,6 +483,14 @@ func (w *worker) onCreateIndex(d *ddlCtx, t *meta.Meta, job *model.Job, isPK boo indexInfo.Unique = unique indexInfo.ID = allocateIndexID(tblInfo) tblInfo.Indices = append(tblInfo.Indices, indexInfo) + + // Here we need do this check before set state to `DeleteOnly`, + // because if hidden columns has been set to `DeleteOnly`, + // the `DeleteOnly` columns are missing when we do this check. + if err := checkInvisibleIndexOnPK(tblInfo); err != nil { + job.State = model.JobStateCancelled + return ver, err + } logutil.BgLogger().Info("[ddl] run add index job", zap.String("job", job.String()), zap.Reflect("indexInfo", indexInfo)) } originalState := indexInfo.State