From 2d13d7ad33d232e5cd58d93d5f1b030de7e771da Mon Sep 17 00:00:00 2001 From: zyguan Date: Sun, 11 Jun 2023 19:41:05 +0800 Subject: [PATCH] This is an automated cherry-pick of #44566 Signed-off-by: ti-chi-bot --- executor/write.go | 8 ++++ executor/write_test.go | 84 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/executor/write.go b/executor/write.go index 9b690d1141382..5897077876a5a 100644 --- a/executor/write.go +++ b/executor/write.go @@ -162,6 +162,14 @@ func updateRecord(ctx context.Context, sctx sessionctx.Context, h kv.Handle, old if v, err := expression.GetTimeValue(sctx, strings.ToUpper(ast.CurrentTimestamp), col.Tp, int8(col.Decimal)); err == nil { newData[i] = v modified[i] = true + // Only TIMESTAMP and DATETIME columns can be automatically updated, so it cannot be PKIsHandle. + // Ref: https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html + if col.IsPKHandleColumn(t.Meta()) { + return false, errors.Errorf("on-update-now column should never be pk-is-handle") + } + if col.IsCommonHandleColumn(t.Meta()) { + handleChanged = true + } } else { return false, err } diff --git a/executor/write_test.go b/executor/write_test.go index 717813104d151..edfb9e3654e19 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -4237,3 +4237,87 @@ func TestIssueInsertPrefixIndexForNonUTF8Collation(t *testing.T) { tk.MustExec("insert into t3 select 'abc '") tk.MustGetErrCode("insert into t3 select 'abc d'", 1062) } +<<<<<<< HEAD:executor/write_test.go +======= + +func TestIssue40066(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("create database test_40066") + defer tk.MustExec("drop database test_40066") + tk.MustExec("use test_40066") + tk.MustExec("set @orig_sql_mode = @@sql_mode;") + defer tk.MustExec("set @@sql_mode = @orig_sql_mode;") + + tk.MustExec(`create table t_int(column1 int, column2 int unsigned generated always as(column1-100));`) + tk.MustExec("set @@sql_mode = DEFAULT;") + tk.MustGetErrMsg("insert into t_int(column1) values (99);", "[types:1264]Out of range value for column 'column2' at row 1") + tk.MustExec("set @@sql_mode = '';") + tk.MustExec("insert into t_int(column1) values (99);") + tk.MustQuery("show warnings;").Check(testkit.Rows("Warning 1264 Out of range value for column 'column2' at row 1")) + tk.MustQuery("select * from t_int;").Check(testkit.Rows("99 0")) + + tk.MustExec(`create table t_float(column1 float, column2 int unsigned generated always as(column1-100));`) + tk.MustExec("set @@sql_mode = DEFAULT;") + tk.MustGetErrMsg("insert into t_float(column1) values (12.95);", "[types:1264]Out of range value for column 'column2' at row 1") + tk.MustExec("set @@sql_mode = '';") + tk.MustExec("insert into t_float(column1) values (12.95);") + tk.MustQuery("show warnings;").Check(testkit.Rows("Warning 1264 Out of range value for column 'column2' at row 1")) + tk.MustQuery("select * from t_float;").Check(testkit.Rows("12.95 0")) + + tk.MustExec(`create table t_decimal(column1 decimal(20,10), column2 int unsigned generated always as(column1-100));`) + tk.MustExec("set @@sql_mode = DEFAULT;") + tk.MustGetErrMsg("insert into t_decimal(column1) values (123.456e-2);", "[types:1264]Out of range value for column 'column2' at row 1") + tk.MustExec("set @@sql_mode = '';") + tk.MustExec("insert into t_decimal(column1) values (123.456e-2);") + tk.MustQuery("show warnings;").Check(testkit.Rows("Warning 1264 Out of range value for column 'column2' at row 1")) + tk.MustQuery("select * from t_decimal;").Check(testkit.Rows("1.2345600000 0")) + + tk.MustExec(`create table t_varchar(column1 varchar(10), column2 int unsigned generated always as(column1-100));`) + tk.MustExec("set @@sql_mode = DEFAULT;") + tk.MustGetErrMsg("insert into t_varchar(column1) values ('87.12');", "[types:1264]Out of range value for column 'column2' at row 1") + tk.MustExec("set @@sql_mode = '';") + tk.MustExec("insert into t_varchar(column1) values ('87.12');") + tk.MustQuery("show warnings;").Check(testkit.Rows("Warning 1264 Out of range value for column 'column2' at row 1")) + tk.MustQuery("select * from t_varchar;").Check(testkit.Rows("87.12 0")) + + tk.MustExec(`create table t_union(column1 float, column2 int unsigned generated always as(column1-100), column3 float unsigned generated always as(column1-100));`) + tk.MustExec("set @@sql_mode = DEFAULT;") + tk.MustGetErrMsg("insert into t_union(column1) values (12.95);", "[types:1264]Out of range value for column 'column2' at row 1") + tk.MustExec("set @@sql_mode = '';") + tk.MustExec("insert into t_union(column1) values (12.95);") + tk.MustQuery("show warnings;").Check(testkit.Rows("Warning 1264 Out of range value for column 'column2' at row 1", "Warning 1264 Out of range value for column 'column3' at row 1")) + tk.MustQuery("select * from t_union;").Check(testkit.Rows("12.95 0 0")) +} + +func TestMutipleReplaceAndInsertInOneSession(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t_securities(id bigint not null auto_increment primary key, security_id varchar(8), market_id smallint, security_type int, unique key uu(security_id, market_id))") + tk.MustExec(`insert into t_securities (security_id, market_id, security_type) values ("1", 2, 7), ("7", 1, 7) ON DUPLICATE KEY UPDATE security_type = VALUES(security_type)`) + tk.MustExec(`replace into t_securities (security_id, market_id, security_type) select security_id+1, 1, security_type from t_securities where security_id="7";`) + tk.MustExec(`INSERT INTO t_securities (security_id, market_id, security_type) values ("1", 2, 7), ("7", 1, 7) ON DUPLICATE KEY UPDATE security_type = VALUES(security_type)`) + + tk.MustQuery("select * from t_securities").Sort().Check(testkit.Rows("1 1 2 7", "2 7 1 7", "3 8 1 7")) + + tk2 := testkit.NewTestKit(t, store) + tk2.MustExec("use test") + tk2.MustExec(`insert into t_securities (security_id, market_id, security_type) values ("1", 2, 7), ("7", 1, 7) ON DUPLICATE KEY UPDATE security_type = VALUES(security_type)`) + tk2.MustExec(`insert into t_securities (security_id, market_id, security_type) select security_id+2, 1, security_type from t_securities where security_id="7";`) + tk2.MustExec(`INSERT INTO t_securities (security_id, market_id, security_type) values ("1", 2, 7), ("7", 1, 7) ON DUPLICATE KEY UPDATE security_type = VALUES(security_type)`) + + tk2.MustQuery("select * from t_securities").Sort().Check(testkit.Rows("1 1 2 7", "2 7 1 7", "3 8 1 7", "8 9 1 7")) +} + +func TestHandleColumnWithOnUpdateCurrentTimestamp(t *testing.T) { + // Test https://github.com/pingcap/tidb/issues/44565 + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("create table t (a timestamp on update current_timestamp(0), b int, primary key (a) clustered, key idx (a))") + tk.MustExec("insert into t values ('2023-06-11 10:00:00', 1)") + tk.MustExec("update t force index(primary) set b = 10 where a = '2023-06-11 10:00:00'") + tk.MustExec("admin check table t") +} +>>>>>>> 068933b0c27 (executor: set handle changed when col gets auto-updated (#44566)):executor/test/writetest/write_test.go