diff --git a/ddl/db_test.go b/ddl/db_test.go index e8abf7cdaf3d6..35e5749d363b2 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -4021,3 +4021,25 @@ func (s *testDBSuite) TestAddColumn2(c *C) { re.Check(testkit.Rows("1 2")) s.tk.MustQuery("select a,b,_tidb_rowid from t2").Check(testkit.Rows("1 3 2")) } + +func (s *testDBSuite) TestAddIndexForGeneratedColumn(c *C) { + s.tk = testkit.NewTestKit(c, s.store) + s.tk.MustExec("use test_db") + s.tk.MustExec("create table t(y year NOT NULL DEFAULT '2155')") + defer s.mustExec(c, "drop table t;") + for i := 0; i < 50; i++ { + s.mustExec(c, "insert into t values (?)", i) + } + s.tk.MustExec("insert into t values()") + s.tk.MustExec("ALTER TABLE t ADD COLUMN y1 year as (y + 2)") + _, err := s.tk.Exec("ALTER TABLE t ADD INDEX idx_y(y1)") + c.Assert(err.Error(), Equals, "[ddl:15]cannot decode index value, because cannot convert datum from unsigned bigint to type year.") + + t := s.testGetTable(c, "t") + for _, idx := range t.Indices() { + c.Assert(strings.EqualFold(idx.Meta().Name.L, "idx_c2"), IsFalse) + } + s.mustExec(c, "delete from t where y = 2155") + s.mustExec(c, "alter table t add index idx_y(y1)") + s.mustExec(c, "alter table t drop index idx_y") +} diff --git a/ddl/ddl.go b/ddl/ddl.go index c8241301b1cd1..1bfe021308984 100644 --- a/ddl/ddl.go +++ b/ddl/ddl.go @@ -76,6 +76,7 @@ var ( errInvalidWorker = terror.ClassDDL.New(codeInvalidWorker, "invalid worker") // errNotOwner means we are not owner and can't handle DDL jobs. errNotOwner = terror.ClassDDL.New(codeNotOwner, "not Owner") + errCantDecodeIndex = terror.ClassDDL.New(codeCantDecodeIndex, "cannot decode index value, because %s") errInvalidDDLJob = terror.ClassDDL.New(codeInvalidDDLJob, "invalid DDL job") errCancelledDDLJob = terror.ClassDDL.New(codeCancelledDDLJob, "cancelled DDL job") errInvalidJobFlag = terror.ClassDDL.New(codeInvalidJobFlag, "invalid job flag") @@ -559,6 +560,7 @@ const ( codeCancelledDDLJob = 12 codeInvalidRanges = 13 codeReorgWorkerPanic = 14 + codeCantDecodeIndex = 15 codeInvalidDBState = 100 codeInvalidTableState = 101 diff --git a/ddl/index.go b/ddl/index.go index ccaf5a9412d62..6da9d079f0411 100644 --- a/ddl/index.go +++ b/ddl/index.go @@ -332,7 +332,7 @@ func (w *worker) onCreateIndex(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int // if timeout, we should return, check for the owner and re-wait job done. return ver, nil } - if kv.ErrKeyExists.Equal(err) || errCancelledDDLJob.Equal(err) { + if kv.ErrKeyExists.Equal(err) || errCancelledDDLJob.Equal(err) || errCantDecodeIndex.Equal(err) { log.Warnf("[ddl] run DDL job %v err %v, convert job to rollback job", job, err) ver, err = convertAddIdxJob2RollbackJob(t, job, tblInfo, indexInfo, err) } @@ -530,7 +530,7 @@ func (w *addIndexWorker) getIndexRecord(handle int64, recordKey []byte, rawRecor sysZone := timeutil.SystemLocation() _, err := w.rowDecoder.DecodeAndEvalRowWithMap(w.sessCtx, rawRecord, time.UTC, sysZone, w.rowMap) if err != nil { - return nil, errors.Trace(err) + return nil, errors.Trace(errCantDecodeIndex.GenWithStackByArgs(err)) } idxVal := make([]types.Datum, len(idxInfo.Columns)) for j, v := range idxInfo.Columns {