From b2b4d2306ac07bf1107512e7bb3fa05a30e6cd84 Mon Sep 17 00:00:00 2001 From: Hangjie Mo Date: Mon, 6 Jun 2022 16:22:29 +0800 Subject: [PATCH] cherry pick #35072 to release-5.3 Signed-off-by: ti-srebot --- ddl/db_integration_test.go | 67 ++++++++++++++++++++++++++++++++++++-- ddl/ddl_api.go | 3 +- executor/insert_common.go | 14 ++++++++ table/column.go | 25 +++++++++++++- 4 files changed, 105 insertions(+), 4 deletions(-) diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go index 7898707fa56fd..93fe6282f51ce 100644 --- a/ddl/db_integration_test.go +++ b/ddl/db_integration_test.go @@ -1653,8 +1653,8 @@ func (s *testIntegrationSuite3) TestAlterColumn(c *C) { // TODO: After fix issue 2606. // tk.MustExec( "alter table test_alter_column alter column d set default null") tk.MustExec("alter table test_alter_column alter column a drop default") - tk.MustExec("insert into test_alter_column set b = 'd', c = 'dd'") - tk.MustQuery("select a from test_alter_column").Check(testkit.Rows("111", "222", "222", "123", "")) + tk.MustGetErrCode("insert into test_alter_column set b = 'd', c = 'dd'", errno.ErrNoDefaultForField) + tk.MustQuery("select a from test_alter_column").Check(testkit.Rows("111", "222", "222", "123")) // for failing tests sql := "alter table db_not_exist.test_alter_column alter column b set default 'c'" @@ -1739,7 +1739,70 @@ func (s *testIntegrationSuite3) TestAlterColumn(c *C) { updateTime3 := rows[0][1].(string) c.Assert(updateTime3[len(updateTime3)-3:], Not(Equals), "000") updateTime6 := rows[0][2].(string) +<<<<<<< HEAD c.Assert(updateTime6[len(updateTime6)-6:], Not(Equals), "000000") +======= + require.NotEqual(t, "000000", updateTime6[len(updateTime6)-6:]) + + tk.MustExec("set sql_mode=default") + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE `t` (`a` int auto_increment, b int, key i(a))") + tk.MustExec("alter table t alter column a drop default") + tk.MustGetErrCode("insert into t values ()", errno.ErrNoDefaultForField) + tk.MustExec("insert into t values (1, a + 1)") + + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE `t` (`a` int)") + tk.MustExec("alter table t alter column a drop default") + tk.MustGetErrCode("insert into t values ()", errno.ErrNoDefaultForField) + + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE `t` (`a` enum('a', 'b'))") + tk.MustExec("alter table t alter column a drop default") + tk.MustExec("insert into t values ()") + tk.MustQuery("select * from t").Check(testkit.Rows("")) + + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE `t` (`a` enum('a', 'b') not null)") + tk.MustExec("alter table t alter column a drop default") + tk.MustExec("insert into t values ()") + tk.MustQuery("select * from t").Check(testkit.Rows("a")) + + tk.MustExec("set sql_mode=''") + + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE `t` (`a` int auto_increment, key i(a))") + tk.MustExec("alter table t alter column a drop default") + tk.MustExec("insert into t values ()") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1364 Field 'a' doesn't have a default value")) + tk.MustQuery("select * from t").Check(testkit.Rows("1")) + + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE `t` (`a` int)") + tk.MustExec("alter table t alter column a drop default") + tk.MustExec("insert into t values ()") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1364 Field 'a' doesn't have a default value")) + tk.MustQuery("select * from t").Check(testkit.Rows("")) + + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE `t` (`a` int not null)") + tk.MustExec("alter table t alter column a drop default") + tk.MustExec("insert into t values ()") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1364 Field 'a' doesn't have a default value")) + tk.MustQuery("select * from t").Check(testkit.Rows("0")) + + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE `t` (`a` enum('a', 'b'))") + tk.MustExec("alter table t alter column a drop default") + tk.MustExec("insert into t values ()") + tk.MustQuery("select * from t").Check(testkit.Rows("")) + + tk.MustExec("drop table if exists t") + tk.MustExec("CREATE TABLE `t` (`a` enum('a', 'b') not null)") + tk.MustExec("alter table t alter column a drop default") + tk.MustExec("insert into t values ()") + tk.MustQuery("select * from t").Check(testkit.Rows("a")) +>>>>>>> cc46266e4... ddl: fix `alter column drop default` (#35072) } func (s *testIntegrationSuite) assertWarningExec(tk *testkit.TestKit, c *C, sql string, expectedWarn *terror.Error) { diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 508e0148b38d1..0806e2372b716 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -4570,11 +4570,12 @@ func (d *ddl) AlterColumn(ctx sessionctx.Context, ident ast.Ident, spec *ast.Alt // Clean the NoDefaultValueFlag value. col.Flag &= ^mysql.NoDefaultValueFlag if len(specNewColumn.Options) == 0 { + col.DefaultIsExpr = false err = col.SetDefaultValue(nil) if err != nil { return errors.Trace(err) } - setNoDefaultValueFlag(col, false) + col.AddFlag(mysql.NoDefaultValueFlag) } else { if IsAutoRandomColumnID(t.Meta(), col.ID) { return ErrInvalidAutoRandom.GenWithStackByArgs(autoid.AutoRandomIncompatibleWithDefaultValueErrMsg) diff --git a/executor/insert_common.go b/executor/insert_common.go index e16253a7756bc..b181f48cfe842 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -556,7 +556,21 @@ func (e *InsertValues) getColDefaultValue(idx int, col *table.Column) (d types.D // fillColValue fills the column value if it is not set in the insert statement. func (e *InsertValues) fillColValue(ctx context.Context, datum types.Datum, idx int, column *table.Column, hasValue bool) (types.Datum, error) { +<<<<<<< HEAD if mysql.HasAutoIncrementFlag(column.Flag) { +======= + if mysql.HasAutoIncrementFlag(column.GetFlag()) { + if !hasValue && mysql.HasNoDefaultValueFlag(column.ToInfo().GetFlag()) { + vars := e.ctx.GetSessionVars() + sc := vars.StmtCtx + if !vars.StrictSQLMode { + sc.AppendWarning(table.ErrNoDefaultValue.FastGenByArgs(column.ToInfo().Name)) + } else { + return datum, table.ErrNoDefaultValue.FastGenByArgs(column.ToInfo().Name) + } + } + +>>>>>>> cc46266e4... ddl: fix `alter column drop default` (#35072) if e.lazyFillAutoID { // Handle hasValue info in autoIncrement column previously for lazy handle. if !hasValue { diff --git a/table/column.go b/table/column.go index 827087ad1acf2..c663fdcab9d47 100644 --- a/table/column.go +++ b/table/column.go @@ -616,12 +616,17 @@ func getColDefaultValue(ctx sessionctx.Context, col *model.ColumnInfo, defaultVa } func getColDefaultValueFromNil(ctx sessionctx.Context, col *model.ColumnInfo) (types.Datum, error) { +<<<<<<< HEAD if !mysql.HasNotNullFlag(col.Flag) { +======= + if !mysql.HasNotNullFlag(col.GetFlag()) && !mysql.HasNoDefaultValueFlag(col.GetFlag()) { +>>>>>>> cc46266e4... ddl: fix `alter column drop default` (#35072) return types.Datum{}, nil } if col.Tp == mysql.TypeEnum { // For enum type, if no default value and not null is set, // the default value is the first element of the enum list +<<<<<<< HEAD defEnum, err := types.ParseEnumValue(col.FieldType.Elems, 1) if err != nil { return types.Datum{}, err @@ -630,13 +635,31 @@ func getColDefaultValueFromNil(ctx sessionctx.Context, col *model.ColumnInfo) (t } if mysql.HasAutoIncrementFlag(col.Flag) { // Auto increment column doesn't has default value and we should not return error. +======= + if mysql.HasNotNullFlag(col.GetFlag()) { + defEnum, err := types.ParseEnumValue(col.FieldType.GetElems(), 1) + if err != nil { + return types.Datum{}, err + } + return types.NewCollateMysqlEnumDatum(defEnum, col.GetCollate()), nil + } + return types.Datum{}, nil + } + if mysql.HasAutoIncrementFlag(col.GetFlag()) && !mysql.HasNoDefaultValueFlag(col.GetFlag()) { + // Auto increment column doesn't have default value and we should not return error. +>>>>>>> cc46266e4... ddl: fix `alter column drop default` (#35072) return GetZeroValue(col), nil } vars := ctx.GetSessionVars() sc := vars.StmtCtx if !vars.StrictSQLMode { sc.AppendWarning(ErrNoDefaultValue.FastGenByArgs(col.Name)) - return GetZeroValue(col), nil + if mysql.HasNotNullFlag(col.GetFlag()) { + return GetZeroValue(col), nil + } + if mysql.HasNoDefaultValueFlag(col.GetFlag()) { + return types.Datum{}, nil + } } if sc.BadNullAsWarning { sc.AppendWarning(ErrColumnCantNull.FastGenByArgs(col.Name))