Skip to content

Commit

Permalink
cherry pick pingcap#36304 to release-6.0
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
zyguan authored and ti-srebot committed Aug 5, 2022
1 parent 36a9810 commit f4927e2
Show file tree
Hide file tree
Showing 7 changed files with 1,134 additions and 33 deletions.
22 changes: 21 additions & 1 deletion executor/insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,11 @@ func (e *InsertExec) updateDupRow(ctx context.Context, idxInBatch int, txn kv.Tr
oldRow = append(oldRow, extraCols...)
}

<<<<<<< HEAD
err = e.doDupRowUpdate(ctx, handle, oldRow, row.row, e.OnDuplicate)
=======
err = e.doDupRowUpdate(ctx, handle, oldRow, row.row, extraCols, e.OnDuplicate, idxInBatch)
>>>>>>> 6418350e9... executor,expression: avoid to append nil to warnings (#36304)
if e.ctx.GetSessionVars().StmtCtx.DupKeyAsWarning && kv.ErrKeyExists.Equal(err) {
e.ctx.GetSessionVars().StmtCtx.AppendWarning(err)
return nil
Expand Down Expand Up @@ -375,7 +379,11 @@ func (e *InsertExec) initEvalBuffer4Dup() {

// doDupRowUpdate updates the duplicate row.
func (e *InsertExec) doDupRowUpdate(ctx context.Context, handle kv.Handle, oldRow []types.Datum, newRow []types.Datum,
<<<<<<< HEAD
cols []*expression.Assignment) error {
=======
extraCols []types.Datum, cols []*expression.Assignment, idxInBatch int) error {
>>>>>>> 6418350e9... executor,expression: avoid to append nil to warnings (#36304)
assignFlag := make([]bool, len(e.Table.WritableCols()))
// See http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
e.curInsertVals.SetDatums(newRow...)
Expand All @@ -389,6 +397,8 @@ func (e *InsertExec) doDupRowUpdate(ctx context.Context, handle kv.Handle, oldRo

// Update old row when the key is duplicated.
e.evalBuffer4Dup.SetDatums(e.row4Update...)
sc := e.ctx.GetSessionVars().StmtCtx
warnCnt := int(sc.WarningCount())
for _, col := range cols {
if col.LazyErr != nil {
return col.LazyErr
Expand All @@ -397,10 +407,20 @@ func (e *InsertExec) doDupRowUpdate(ctx context.Context, handle kv.Handle, oldRo
if err1 != nil {
return err1
}
e.row4Update[col.Col.Index], err1 = table.CastValue(e.ctx, val, col.Col.ToInfo(), false, false)
c := col.Col.ToInfo()
c.Name = col.ColName
e.row4Update[col.Col.Index], err1 = table.CastValue(e.ctx, val, c, false, false)
if err1 != nil {
return err1
}
if newWarnings := sc.TruncateWarnings(warnCnt); len(newWarnings) > 0 {
for k := range newWarnings {
// Use `idxInBatch` here for simplicity, since the offset of the batch is unknown under the current context.
newWarnings[k].Err = completeInsertErr(c, &val, idxInBatch, newWarnings[k].Err)
}
sc.AppendWarnings(newWarnings)
warnCnt += len(newWarnings)
}
e.evalBuffer4Dup.SetDatum(col.Col.Index, e.row4Update[col.Col.Index])
assignFlag[col.Col.Index] = true
}
Expand Down
39 changes: 33 additions & 6 deletions executor/insert_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,7 @@ func insertRows(ctx context.Context, base insertCommon) (err error) {
return nil
}

func (e *InsertValues) handleErr(col *table.Column, val *types.Datum, rowIdx int, err error) error {
if err == nil {
return nil
}

// Convert the error with full messages.
func completeInsertErr(col *model.ColumnInfo, val *types.Datum, rowIdx int, err error) error {
var (
colTp byte
colName string
Expand Down Expand Up @@ -322,6 +317,20 @@ func (e *InsertValues) handleErr(col *table.Column, val *types.Datum, rowIdx int
} else if types.ErrWarnDataOutOfRange.Equal(err) {
err = types.ErrWarnDataOutOfRange.GenWithStackByArgs(colName, rowIdx+1)
}
return err
}

func (e *InsertValues) handleErr(col *table.Column, val *types.Datum, rowIdx int, err error) error {
if err == nil {
return nil
}

// Convert the error with full messages.
var c *model.ColumnInfo
if col != nil {
c = col.ColumnInfo
}
err = completeInsertErr(c, val, rowIdx, err)

if !e.ctx.GetSessionVars().StmtCtx.DupKeyAsWarning {
return err
Expand Down Expand Up @@ -349,6 +358,8 @@ func (e *InsertValues) evalRow(ctx context.Context, list []expression.Expression
}

e.evalBuffer.SetDatums(row...)
sc := e.ctx.GetSessionVars().StmtCtx
warnCnt := int(sc.WarningCount())
for i, expr := range list {
val, err := expr.Eval(e.evalBuffer.ToRow())
if err != nil {
Expand All @@ -358,6 +369,13 @@ func (e *InsertValues) evalRow(ctx context.Context, list []expression.Expression
if err = e.handleErr(e.insertColumns[i], &val, rowIdx, err); err != nil {
return nil, err
}
if newWarnings := sc.TruncateWarnings(warnCnt); len(newWarnings) > 0 {
for k := range newWarnings {
newWarnings[k].Err = completeInsertErr(e.insertColumns[i].ColumnInfo, &val, rowIdx, newWarnings[k].Err)
}
sc.AppendWarnings(newWarnings)
warnCnt += len(newWarnings)
}

offset := e.insertColumns[i].Offset
val1.Copy(&row[offset])
Expand All @@ -377,6 +395,8 @@ func (e *InsertValues) fastEvalRow(ctx context.Context, list []expression.Expres
}
row := make([]types.Datum, rowLen)
hasValue := make([]bool, rowLen)
sc := e.ctx.GetSessionVars().StmtCtx
warnCnt := int(sc.WarningCount())
for i, expr := range list {
con := expr.(*expression.Constant)
val, err := con.Eval(emptyRow)
Expand All @@ -387,6 +407,13 @@ func (e *InsertValues) fastEvalRow(ctx context.Context, list []expression.Expres
if err = e.handleErr(e.insertColumns[i], &val, rowIdx, err); err != nil {
return nil, err
}
if newWarnings := sc.TruncateWarnings(warnCnt); len(newWarnings) > 0 {
for k := range newWarnings {
newWarnings[k].Err = completeInsertErr(e.insertColumns[i].ColumnInfo, &val, rowIdx, newWarnings[k].Err)
}
sc.AppendWarnings(newWarnings)
warnCnt += len(newWarnings)
}
offset := e.insertColumns[i].Offset
row[offset], hasValue[offset] = val1, true
}
Expand Down
9 changes: 5 additions & 4 deletions executor/insert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func TestInsertWrongValueForField(t *testing.T) {
tk.MustExec(`CREATE TABLE ts (id int DEFAULT NULL, time1 TIMESTAMP NULL DEFAULT NULL)`)
tk.MustExec(`SET @@sql_mode=''`)
tk.MustExec(`INSERT INTO ts (id, time1) VALUES (1, TIMESTAMP '1018-12-23 00:00:00')`)
tk.MustQuery(`SHOW WARNINGS`).Check(testkit.Rows(`Warning 1292 Incorrect timestamp value: '1018-12-23 00:00:00'`))
tk.MustQuery(`SHOW WARNINGS`).Check(testkit.Rows(`Warning 1292 Incorrect timestamp value: '1018-12-23 00:00:00' for column 'time1' at row 1`))
tk.MustQuery(`SELECT * FROM ts ORDER BY id`).Check(testkit.Rows(`1 0000-00-00 00:00:00`))

tk.MustExec(`SET @@sql_mode='STRICT_TRANS_TABLES'`)
Expand Down Expand Up @@ -1633,7 +1633,7 @@ func TestIssue10402(t *testing.T) {
tk.MustExec("insert into vctt values ('ab\\n\\n\\n', 'ab\\n\\n\\n'), ('ab\\t\\t\\t', 'ab\\t\\t\\t'), ('ab ', 'ab '), ('ab\\r\\r\\r', 'ab\\r\\r\\r')")
require.Equal(t, uint16(4), tk.Session().GetSessionVars().StmtCtx.WarningCount())
warns := tk.Session().GetSessionVars().StmtCtx.GetWarnings()
require.Equal(t, "[{Warning [types:1265]Data truncated, field len 4, data len 5} {Warning [types:1265]Data truncated, field len 4, data len 5} {Warning [types:1265]Data truncated, field len 4, data len 6} {Warning [types:1265]Data truncated, field len 4, data len 5}]",
require.Equal(t, "[{Warning [types:1265]Data truncated for column 'v' at row 1} {Warning [types:1265]Data truncated for column 'v' at row 2} {Warning [types:1265]Data truncated for column 'v' at row 3} {Warning [types:1265]Data truncated for column 'v' at row 4}]",
fmt.Sprintf("%v", warns))
tk.MustQuery("select * from vctt").Check(testkit.Rows("ab\n\n ab\n\n", "ab\t\t ab\t\t", "ab ab", "ab\r\r ab\r\r"))
tk.MustQuery("select length(v), length(c) from vctt").Check(testkit.Rows("4 4", "4 4", "4 2", "4 4"))
Expand Down Expand Up @@ -1851,7 +1851,8 @@ func TestStringtoDecimal(t *testing.T) {
tk.MustGetErrCode("insert into t values('1.2.')", errno.ErrTruncatedWrongValueForField)
tk.MustGetErrCode("insert into t values('1,999.00')", errno.ErrTruncatedWrongValueForField)
tk.MustExec("insert into t values('12e-3')")
tk.MustQuery("show warnings;").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '0.012'"))
// TODO: MySQL8.0 reports Note 1265 Data truncated for column 'id' at row 1
tk.MustQuery("show warnings;").Check(testkit.RowsWithSep("|", "Warning|1366|Incorrect decimal value: '12e-3' for column 'id' at row 1"))
tk.MustQuery("select id from t").Check(testkit.Rows("0"))
tk.MustExec("drop table if exists t")
}
Expand All @@ -1866,7 +1867,7 @@ func TestIssue17745(t *testing.T) {
tk.MustGetErrCode("insert into tt1 values(89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)", errno.ErrWarnDataOutOfRange)
tk.MustGetErrCode("insert into tt1 values(89123456789012345678901234567890123456789012345678901234567890123456789012345678900000000)", errno.ErrWarnDataOutOfRange)
tk.MustExec("insert ignore into tt1 values(89123456789012345678901234567890123456789012345678901234567890123456789012345678900000000)")
tk.MustQuery("show warnings;").Check(testkit.Rows(`Warning 1690 DECIMAL value is out of range in '(64, 0)'`, `Warning 1292 Truncated incorrect DECIMAL value: '789012345678901234567890123456789012345678901234567890123456789012345678900000000'`))
tk.MustQuery("show warnings;").Check(testkit.Rows(`Warning 1264 Out of range value for column 'c1' at row 1`, `Warning 1292 Truncated incorrect DECIMAL value: '789012345678901234567890123456789012345678901234567890123456789012345678900000000'`))
tk.MustQuery("select c1 from tt1").Check(testkit.Rows("9999999999999999999999999999999999999999999999999999999999999999"))
tk.MustGetErrCode("update tt1 set c1 = 89123456789012345678901234567890123456789012345678901234567890123456789012345678900000000", errno.ErrWarnDataOutOfRange)
tk.MustExec("drop table if exists tt1")
Expand Down
Loading

0 comments on commit f4927e2

Please sign in to comment.