Skip to content

Commit

Permalink
table: fix NO_ZERO_DATE not work for insert into select statement (pi…
Browse files Browse the repository at this point in the history
  • Loading branch information
jackysp authored Apr 26, 2022
1 parent 6b3b73b commit b119f26
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 17 deletions.
20 changes: 4 additions & 16 deletions executor/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,27 +72,15 @@ func updateRecord(ctx context.Context, sctx sessionctx.Context, h kv.Handle, old
// because all of them are sorted by their `Offset`, which
// causes all writable columns are after public columns.

// 1. Cast modified values.
for i, col := range t.Cols() {
if modified[i] {
// Cast changed fields with respective columns.
v, err := table.CastValue(sctx, newData[i], col.ToInfo(), false, false)
if err != nil {
return false, err
}
newData[i] = v
}
}

// 2. Handle the bad null error.
// Handle the bad null error.
for i, col := range t.Cols() {
var err error
if err = col.HandleBadNull(&newData[i], sc); err != nil {
return false, err
}
}

// 3. Compare datum, then handle some flags.
// Compare datum, then handle some flags.
for i, col := range t.Cols() {
// We should use binary collation to compare datum, otherwise the result will be incorrect.
cmp, err := newData[i].Compare(sc, &oldData[i], collate.GetBinaryCollator())
Expand Down Expand Up @@ -156,7 +144,7 @@ func updateRecord(ctx context.Context, sctx sessionctx.Context, h kv.Handle, old
return false, nil
}

// 4. Fill values into on-update-now fields, only if they are really changed.
// Fill values into on-update-now fields, only if they are really changed.
for i, col := range t.Cols() {
if mysql.HasOnUpdateNowFlag(col.Flag) && !modified[i] && !onUpdateSpecified[i] {
if v, err := expression.GetTimeValue(sctx, strings.ToUpper(ast.CurrentTimestamp), col.Tp, col.Decimal); err == nil {
Expand All @@ -168,7 +156,7 @@ func updateRecord(ctx context.Context, sctx sessionctx.Context, h kv.Handle, old
}
}

// 5. If handle changed, remove the old then add the new record, otherwise update the record.
// If handle changed, remove the old then add the new record, otherwise update the record.
if handleChanged {
// For `UPDATE IGNORE`/`INSERT IGNORE ON DUPLICATE KEY UPDATE`
// we use the staging buffer so that we don't need to precheck the existence of handle or unique keys by sending
Expand Down
10 changes: 10 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5404,6 +5404,16 @@ func TestIssue19892(t *testing.T) {
tk.MustQuery("SHOW WARNINGS").Check(testkit.Rows("Warning 1292 Incorrect timestamp value: '2000-01-00 00:00:00'"))
tk.MustQuery("SELECT c FROM dd").Check(testkit.Rows("0000-00-00 00:00:00"))
}
tk.MustExec("drop table if exists table_20220419;")
tk.MustExec(`CREATE TABLE table_20220419 (
id bigint(20) NOT NULL AUTO_INCREMENT,
lastLoginDate datetime NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;`)
tk.MustExec("set sql_mode='';")
tk.MustExec("insert into table_20220419 values(1,'0000-00-00 00:00:00');")
tk.MustExec("set sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';")
tk.MustGetErrMsg("insert into table_20220419(lastLoginDate) select lastLoginDate from table_20220419;", "[types:1292]Incorrect datetime value: '0000-00-00 00:00:00'")
}

// The actual results do not agree with the test results, It should be modified after the test suite is updated
Expand Down
1 change: 0 additions & 1 deletion table/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ func CastValue(ctx sessionctx.Context, val types.Datum, col *model.ColumnInfo, r
}
err = types.ErrTruncatedWrongVal.GenWithStackByArgs(col.FieldType.CompactStr(), str)
} else if (sc.InInsertStmt || sc.InUpdateStmt) && !casted.IsNull() &&
(val.Kind() != types.KindMysqlTime || !val.GetMysqlTime().IsZero()) &&
(col.Tp == mysql.TypeDate || col.Tp == mysql.TypeDatetime || col.Tp == mysql.TypeTimestamp) {
str, err1 := val.ToString()
if err1 != nil {
Expand Down

0 comments on commit b119f26

Please sign in to comment.