From ad0067d5d2722771bde021b02fd8c2c4facad836 Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Fri, 19 Nov 2021 20:09:47 +0800 Subject: [PATCH] executor: fix a bug that can not insert null into a not null column in the empty SQL mode (#21237) (#27832) --- executor/executor.go | 4 ++-- executor/executor_test.go | 6 +++--- executor/insert_common.go | 4 ---- executor/write_test.go | 4 ++-- expression/integration_test.go | 11 +++++++++++ table/column.go | 8 ++++---- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/executor/executor.go b/executor/executor.go index b7ec69138e2c1..b8ec7068db298 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -1686,9 +1686,9 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) { sc.InInsertStmt = true // For insert statement (not for update statement), disabling the StrictSQLMode // should make TruncateAsWarning and DividedByZeroAsWarning, - // but should not make DupKeyAsWarning or BadNullAsWarning, + // but should not make DupKeyAsWarning. sc.DupKeyAsWarning = stmt.IgnoreErr - sc.BadNullAsWarning = stmt.IgnoreErr + sc.BadNullAsWarning = !vars.StrictSQLMode || stmt.IgnoreErr sc.IgnoreNoPartition = stmt.IgnoreErr sc.TruncateAsWarning = !vars.StrictSQLMode || stmt.IgnoreErr sc.DividedByZeroAsWarning = !vars.StrictSQLMode || stmt.IgnoreErr diff --git a/executor/executor_test.go b/executor/executor_test.go index 0ed65eeea26c3..55ed2636bd4c2 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -2120,14 +2120,14 @@ func (s *testSuiteP2) TestSQLMode(c *C) { tk.MustExec("set sql_mode = ''") tk.MustExec("insert t values ()") tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1364 Field 'a' doesn't have a default value")) - _, err = tk.Exec("insert t values (null)") - c.Check(err, NotNil) + tk.MustExec("insert t values (null)") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1048 Column 'a' cannot be null")) tk.MustExec("insert ignore t values (null)") tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1048 Column 'a' cannot be null")) tk.MustExec("insert t select null") tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1048 Column 'a' cannot be null")) tk.MustExec("insert t values (1000)") - tk.MustQuery("select * from t order by a").Check(testkit.Rows("0", "0", "0", "127")) + tk.MustQuery("select * from t order by a").Check(testkit.Rows("0", "0", "0", "0", "127")) tk.MustExec("insert tdouble values (10.23)") tk.MustQuery("select * from tdouble").Check(testkit.Rows("9.99")) diff --git a/executor/insert_common.go b/executor/insert_common.go index d6fbcfa74b353..b9cfc43749321 100644 --- a/executor/insert_common.go +++ b/executor/insert_common.go @@ -417,10 +417,6 @@ func insertRowsFromSelect(ctx context.Context, base insertCommon) error { rows := make([][]types.Datum, 0, chk.Capacity()) sessVars := e.ctx.GetSessionVars() - if !sessVars.StrictSQLMode { - // If StrictSQLMode is disabled and it is a insert-select statement, it also handle BadNullAsWarning. - sessVars.StmtCtx.BadNullAsWarning = true - } batchInsert := sessVars.BatchInsert && !sessVars.InTxn() && config.GetGlobalConfig().EnableBatchDML batchSize := sessVars.DMLBatchSize memUsageOfRows := int64(0) diff --git a/executor/write_test.go b/executor/write_test.go index f9f60eaa9889d..29472a8b2e98f 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -735,8 +735,8 @@ commit;` tk.MustQuery(`SELECT * FROM t1 order by f1;`).Check(testkit.Rows("1 0", "2 2")) tk.MustExec(`SET sql_mode='';`) - _, err = tk.Exec(`INSERT t1 VALUES (1, 1) ON DUPLICATE KEY UPDATE f2 = null;`) - c.Assert(err, NotNil) + tk.MustExec(`INSERT t1 VALUES (1, 1) ON DUPLICATE KEY UPDATE f2 = null;`) + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1048 Column 'f2' cannot be null")) tk.MustQuery(`SELECT * FROM t1 order by f1;`).Check(testkit.Rows("1 0", "2 2")) } diff --git a/expression/integration_test.go b/expression/integration_test.go index 17a5ff4a10ee3..4819eb523b95a 100755 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -3106,6 +3106,17 @@ func (s *testIntegrationSuite2) TestBuiltin(c *C) { result.Check(testkit.Rows("0")) } +func (s *testIntegrationSuite2) TestIssue11648(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t (id int NOT NULL DEFAULT 8);") + tk.MustExec("SET sql_mode = '';") + tk.MustExec("insert into t values (1), (NULL), (2);") + tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1048 Column 'id' cannot be null")) + tk.MustQuery("select * from t").Check(testkit.Rows("1", "0", "2")) +} + func (s *testIntegrationSuite) TestInfoBuiltin(c *C) { defer s.cleanEnv(c) tk := testkit.NewTestKit(c, s.store) diff --git a/table/column.go b/table/column.go index 2e78678056000..a20b7567578fc 100644 --- a/table/column.go +++ b/table/column.go @@ -568,14 +568,14 @@ func getColDefaultValueFromNil(ctx sessionctx.Context, col *model.ColumnInfo) (t } vars := ctx.GetSessionVars() sc := vars.StmtCtx - if sc.BadNullAsWarning { - sc.AppendWarning(ErrColumnCantNull.FastGenByArgs(col.Name)) - return GetZeroValue(col), nil - } if !vars.StrictSQLMode { sc.AppendWarning(ErrNoDefaultValue.FastGenByArgs(col.Name)) return GetZeroValue(col), nil } + if sc.BadNullAsWarning { + sc.AppendWarning(ErrColumnCantNull.FastGenByArgs(col.Name)) + return GetZeroValue(col), nil + } return types.Datum{}, ErrNoDefaultValue.FastGenByArgs(col.Name) }