@@ -186,7 +186,7 @@ func (e *InsertValues) prefetchDataCache(ctx context.Context, txn kv.Transaction
186
186
}
187
187
188
188
// updateDupRow updates a duplicate row to a new row.
189
- func (e * InsertExec ) updateDupRow (ctx context.Context , idxInBatch int , txn kv.Transaction , row toBeCheckedRow , handle kv.Handle , onDuplicate []* expression.Assignment ) error {
189
+ func (e * InsertExec ) updateDupRow (ctx context.Context , idxInBatch int , txn kv.Transaction , row toBeCheckedRow , handle kv.Handle , onDuplicate []* expression.Assignment , autoColIdx int ) error {
190
190
oldRow , err := getOldRow (ctx , e .ctx , txn , row .t , handle , e .GenExprs )
191
191
if err != nil {
192
192
return err
@@ -197,7 +197,7 @@ func (e *InsertExec) updateDupRow(ctx context.Context, idxInBatch int, txn kv.Tr
197
197
extraCols = e .ctx .GetSessionVars ().CurrInsertBatchExtraCols [idxInBatch ]
198
198
}
199
199
200
- err = e .doDupRowUpdate (ctx , handle , oldRow , row .row , extraCols , e .OnDuplicate , idxInBatch )
200
+ err = e .doDupRowUpdate (ctx , handle , oldRow , row .row , extraCols , e .OnDuplicate , idxInBatch , autoColIdx )
201
201
if e .ctx .GetSessionVars ().StmtCtx .DupKeyAsWarning && kv .ErrKeyExists .Equal (err ) {
202
202
e .ctx .GetSessionVars ().StmtCtx .AppendWarning (err )
203
203
return nil
@@ -235,14 +235,19 @@ func (e *InsertExec) batchUpdateDupRows(ctx context.Context, newRows [][]types.D
235
235
e .stats .Prefetch += time .Since (prefetchStart )
236
236
}
237
237
238
+ _ , autoColIdx , found := findAutoIncrementColumn (e .Table )
239
+ if ! found {
240
+ autoColIdx = - 1
241
+ }
242
+
238
243
for i , r := range toBeCheckedRows {
239
244
if r .handleKey != nil {
240
245
handle , err := tablecodec .DecodeRowKey (r .handleKey .newKey )
241
246
if err != nil {
242
247
return err
243
248
}
244
249
245
- err = e .updateDupRow (ctx , i , txn , r , handle , e .OnDuplicate )
250
+ err = e .updateDupRow (ctx , i , txn , r , handle , e .OnDuplicate , autoColIdx )
246
251
if err == nil {
247
252
continue
248
253
}
@@ -259,7 +264,7 @@ func (e *InsertExec) batchUpdateDupRows(ctx context.Context, newRows [][]types.D
259
264
if handle == nil {
260
265
continue
261
266
}
262
- err = e .updateDupRow (ctx , i , txn , r , handle , e .OnDuplicate )
267
+ err = e .updateDupRow (ctx , i , txn , r , handle , e .OnDuplicate , autoColIdx )
263
268
if err != nil {
264
269
if kv .IsErrNotFound (err ) {
265
270
// Data index inconsistent? A unique key provide the handle information, but the
@@ -380,7 +385,7 @@ func (e *InsertExec) initEvalBuffer4Dup() {
380
385
381
386
// doDupRowUpdate updates the duplicate row.
382
387
func (e * InsertExec ) doDupRowUpdate (ctx context.Context , handle kv.Handle , oldRow []types.Datum , newRow []types.Datum ,
383
- extraCols []types.Datum , cols []* expression.Assignment , idxInBatch int ) error {
388
+ extraCols []types.Datum , cols []* expression.Assignment , idxInBatch int , autoColIdx int ) error {
384
389
assignFlag := make ([]bool , len (e .Table .WritableCols ()))
385
390
// See http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
386
391
e .curInsertVals .SetDatums (newRow ... )
@@ -429,6 +434,17 @@ func (e *InsertExec) doDupRowUpdate(ctx context.Context, handle kv.Handle, oldRo
429
434
if err != nil {
430
435
return err
431
436
}
437
+
438
+ if autoColIdx >= 0 {
439
+ if e .ctx .GetSessionVars ().StmtCtx .AffectedRows () > 0 {
440
+ // If "INSERT ... ON DUPLICATE KEY UPDATE" duplicate and update a row,
441
+ // auto increment value should be set correctly for mysql_insert_id()
442
+ // See https://github.com/pingcap/tidb/issues/55965
443
+ e .ctx .GetSessionVars ().StmtCtx .InsertID = newData [autoColIdx ].GetUint64 ()
444
+ } else {
445
+ e .ctx .GetSessionVars ().StmtCtx .InsertID = 0
446
+ }
447
+ }
432
448
return nil
433
449
}
434
450
0 commit comments