@@ -194,7 +194,7 @@ func (e *InsertValues) prefetchDataCache(ctx context.Context, txn kv.Transaction
194
194
}
195
195
196
196
// updateDupRow updates a duplicate row to a new row.
197
- func (e * InsertExec ) updateDupRow (ctx context.Context , idxInBatch int , txn kv.Transaction , row toBeCheckedRow , handle kv.Handle , _ []* expression.Assignment , dupKeyCheck table.DupKeyCheckMode ) error {
197
+ func (e * InsertExec ) updateDupRow (ctx context.Context , idxInBatch int , txn kv.Transaction , row toBeCheckedRow , handle kv.Handle , _ []* expression.Assignment , dupKeyCheck table.DupKeyCheckMode , autoColIdx int ) error {
198
198
oldRow , err := getOldRow (ctx , e .Ctx (), txn , row .t , handle , e .GenExprs )
199
199
if err != nil {
200
200
return err
@@ -205,7 +205,7 @@ func (e *InsertExec) updateDupRow(ctx context.Context, idxInBatch int, txn kv.Tr
205
205
extraCols = e .Ctx ().GetSessionVars ().CurrInsertBatchExtraCols [idxInBatch ]
206
206
}
207
207
208
- err = e .doDupRowUpdate (ctx , handle , oldRow , row .row , extraCols , e .OnDuplicate , idxInBatch , dupKeyCheck )
208
+ err = e .doDupRowUpdate (ctx , handle , oldRow , row .row , extraCols , e .OnDuplicate , idxInBatch , dupKeyCheck , autoColIdx )
209
209
if kv .ErrKeyExists .Equal (err ) || table .ErrCheckConstraintViolated .Equal (err ) {
210
210
ec := e .Ctx ().GetSessionVars ().StmtCtx .ErrCtx ()
211
211
return ec .HandleErrorWithAlias (kv .ErrKeyExists , err , err )
@@ -249,14 +249,19 @@ func (e *InsertExec) batchUpdateDupRows(ctx context.Context, newRows [][]types.D
249
249
// TODO: just use `DupKeyCheckSkip` here.
250
250
addRecordDupKeyCheck := optimizeDupKeyCheckForNormalInsert (e .Ctx ().GetSessionVars (), txn )
251
251
252
+ _ , autoColIdx , found := findAutoIncrementColumn (e .Table )
253
+ if ! found {
254
+ autoColIdx = - 1
255
+ }
256
+
252
257
for i , r := range toBeCheckedRows {
253
258
if r .handleKey != nil {
254
259
handle , err := tablecodec .DecodeRowKey (r .handleKey .newKey )
255
260
if err != nil {
256
261
return err
257
262
}
258
263
259
- err = e .updateDupRow (ctx , i , txn , r , handle , e .OnDuplicate , updateDupKeyCheck )
264
+ err = e .updateDupRow (ctx , i , txn , r , handle , e .OnDuplicate , updateDupKeyCheck , autoColIdx )
260
265
if err == nil {
261
266
continue
262
267
}
@@ -273,7 +278,7 @@ func (e *InsertExec) batchUpdateDupRows(ctx context.Context, newRows [][]types.D
273
278
if handle == nil {
274
279
continue
275
280
}
276
- err = e .updateDupRow (ctx , i , txn , r , handle , e .OnDuplicate , updateDupKeyCheck )
281
+ err = e .updateDupRow (ctx , i , txn , r , handle , e .OnDuplicate , updateDupKeyCheck , autoColIdx )
277
282
if err != nil {
278
283
if kv .IsErrNotFound (err ) {
279
284
// Data index inconsistent? A unique key provide the handle information, but the
@@ -427,7 +432,7 @@ func (e *InsertExec) initEvalBuffer4Dup() {
427
432
428
433
// doDupRowUpdate updates the duplicate row.
429
434
func (e * InsertExec ) doDupRowUpdate (ctx context.Context , handle kv.Handle , oldRow []types.Datum , newRow []types.Datum ,
430
- extraCols []types.Datum , cols []* expression.Assignment , idxInBatch int , dupKeyMode table.DupKeyCheckMode ) error {
435
+ extraCols []types.Datum , cols []* expression.Assignment , idxInBatch int , dupKeyMode table.DupKeyCheckMode , autoColIdx int ) error {
431
436
assignFlag := make ([]bool , len (e .Table .WritableCols ()))
432
437
// See http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
433
438
e .curInsertVals .SetDatums (newRow ... )
@@ -478,6 +483,17 @@ func (e *InsertExec) doDupRowUpdate(ctx context.Context, handle kv.Handle, oldRo
478
483
if err != nil {
479
484
return err
480
485
}
486
+
487
+ if autoColIdx >= 0 {
488
+ if e .Ctx ().GetSessionVars ().StmtCtx .AffectedRows () > 0 {
489
+ // If "INSERT ... ON DUPLICATE KEY UPDATE" duplicate and update a row,
490
+ // auto increment value should be set correctly for mysql_insert_id()
491
+ // See https://github.com/pingcap/tidb/issues/55965
492
+ e .Ctx ().GetSessionVars ().StmtCtx .InsertID = newData [autoColIdx ].GetUint64 ()
493
+ } else {
494
+ e .Ctx ().GetSessionVars ().StmtCtx .InsertID = 0
495
+ }
496
+ }
481
497
return nil
482
498
}
483
499
0 commit comments