Skip to content

Commit

Permalink
executor: fix issue that update ignore stmt return error when meet in…
Browse files Browse the repository at this point in the history
…correct timestamp value error (pingcap#54878)

close pingcap#50308
  • Loading branch information
crazycs520 authored Jul 30, 2024
1 parent 3fd284b commit af9c839
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
16 changes: 16 additions & 0 deletions pkg/executor/test/executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2986,3 +2986,19 @@ func TestIssue48756(t *testing.T) {
"Warning 1105 ",
))
}

func TestIssue50308(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table t(a timestamp);")
tk.MustExec("insert ignore into t values(cast('2099-01-01' as date));")
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning 1292 Incorrect timestamp value: '2099-01-01' for column 'a' at row 1"))
tk.MustQuery("select * from t;").Check(testkit.Rows("0000-00-00 00:00:00"))
tk.MustExec("delete from t")
tk.MustExec("insert into t values('2000-01-01');")
tk.MustGetErrMsg("update t set a=cast('2099-01-01' as date)", "[types:1292]Incorrect timestamp value: '2099-01-01'")
tk.MustExec("update ignore t set a=cast('2099-01-01' as date);")
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning 1292 Incorrect timestamp value: '2099-01-01'"))
tk.MustQuery("select * from t;").Check(testkit.Rows("0000-00-00 00:00:00"))
}
17 changes: 10 additions & 7 deletions pkg/executor/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ func (e *UpdateExec) updateRows(ctx context.Context) (int, error) {
return totalNumRows, nil
}

func (*UpdateExec) handleErr(colName model.CIStr, rowIdx int, err error) error {
func (e *UpdateExec) handleErr(colName model.CIStr, col *table.Column, rowIdx int, err error) error {
if err == nil {
return nil
}
Expand All @@ -351,7 +351,10 @@ func (*UpdateExec) handleErr(colName model.CIStr, rowIdx int, err error) error {
if types.ErrOverflow.Equal(err) {
return types.ErrWarnDataOutOfRange.GenWithStackByArgs(colName.O, rowIdx+1)
}

if types.ErrTruncatedWrongVal.Equal(err) && col != nil && col.ColumnInfo != nil && col.ColumnInfo.GetType() == mysql.TypeTimestamp {
ec := e.Ctx().GetSessionVars().StmtCtx.ErrCtx()
return errors.AddStack(ec.HandleErrorWithAlias(kv.ErrKeyExists, err, err))
}
return err
}

Expand All @@ -364,15 +367,15 @@ func (e *UpdateExec) fastComposeNewRow(rowIdx int, oldRow []types.Datum, cols []
}
con := assign.Expr.(*expression.Constant)
val, err := con.Eval(e.Ctx().GetExprCtx().GetEvalCtx(), emptyRow)
if err = e.handleErr(assign.ColName, rowIdx, err); err != nil {
if err = e.handleErr(assign.ColName, cols[assign.Col.Index], rowIdx, err); err != nil {
return nil, err
}

// info of `_tidb_rowid` column is nil.
// No need to cast `_tidb_rowid` column value.
if cols[assign.Col.Index] != nil {
val, err = table.CastValue(e.Ctx(), val, cols[assign.Col.Index].ColumnInfo, false, false)
if err = e.handleErr(assign.ColName, rowIdx, err); err != nil {
if err = e.handleErr(assign.ColName, cols[assign.Col.Index], rowIdx, err); err != nil {
return nil, err
}
}
Expand All @@ -399,7 +402,7 @@ func (e *UpdateExec) composeNewRow(rowIdx int, oldRow []types.Datum, cols []*tab
// No need to cast `_tidb_rowid` column value.
if cols[assign.Col.Index] != nil {
val, err = table.CastValue(e.Ctx(), val, cols[assign.Col.Index].ColumnInfo, false, false)
if err = e.handleErr(assign.ColName, rowIdx, err); err != nil {
if err = e.handleErr(assign.ColName, cols[assign.Col.Index], rowIdx, err); err != nil {
return nil, err
}
}
Expand All @@ -420,15 +423,15 @@ func (e *UpdateExec) composeGeneratedColumns(rowIdx int, newRowData []types.Datu
continue
}
val, err := assign.Expr.Eval(e.Ctx().GetExprCtx().GetEvalCtx(), e.evalBuffer.ToRow())
if err = e.handleErr(assign.ColName, rowIdx, err); err != nil {
if err = e.handleErr(assign.ColName, cols[assign.Col.Index], rowIdx, err); err != nil {
return nil, err
}

// info of `_tidb_rowid` column is nil.
// No need to cast `_tidb_rowid` column value.
if cols[assign.Col.Index] != nil {
val, err = table.CastValue(e.Ctx(), val, cols[assign.Col.Index].ColumnInfo, false, false)
if err = e.handleErr(assign.ColName, rowIdx, err); err != nil {
if err = e.handleErr(assign.ColName, cols[assign.Col.Index], rowIdx, err); err != nil {
return nil, err
}
}
Expand Down

0 comments on commit af9c839

Please sign in to comment.