MCPcopy
hub / github.com/pingcap/tidb / batchUpdateDupRows

Method batchUpdateDupRows

pkg/executor/insert.go:226–322  ·  view source on GitHub ↗

batchUpdateDupRows updates multi-rows in batch if they are duplicate with rows in table.

(ctx context.Context, newRows [][]types.Datum)

Source from the content-addressed store, hash-verified

224
225// batchUpdateDupRows updates multi-rows in batch if they are duplicate with rows in table.
226func (e *InsertExec) batchUpdateDupRows(ctx context.Context, newRows [][]types.Datum) error {
227 // Get keys need to be checked.
228 start := time.Now()
229 toBeCheckedRows, err := getKeysNeedCheck(e.Ctx(), e.Table, newRows)
230 if err != nil {
231 return err
232 }
233
234 txn, err := e.Ctx().Txn(true)
235 if err != nil {
236 return err
237 }
238
239 prefetchStart := time.Now()
240 // Use BatchGet to fill cache.
241 // It's an optimization and could be removed without affecting correctness.
242 if err = e.prefetchDataCache(ctx, txn, toBeCheckedRows); err != nil {
243 return err
244 }
245 if e.stats != nil {
246 e.stats.Prefetch += time.Since(prefetchStart)
247 }
248
249 // Use `optimizeDupKeyCheckForUpdate` to determine the update operation when the row meets the conflict in
250 // `INSERT ... ON DUPLICATE KEY UPDATE` statement.
251 // Though it is in an insert statement, `ON DUP KEY UPDATE` follows the dup-key check behavior of update.
252 // For example, it will ignore variable `tidb_constraint_check_in_place`, see the test case:
253 // https://github.com/pingcap/tidb/blob/3117d3fae50bbb5dabcde7b9589f92bfbbda5dc6/pkg/executor/test/writetest/write_test.go#L419-L426
254 updateDupKeyCheck := optimizeDupKeyCheckForUpdate(txn, e.ignoreErr)
255 // Do not use `updateDupKeyCheck` for `AddRecord` because it is not optimized for insert.
256 // It seems that we can just use `DupKeyCheckSkip` here because all constraints are checked.
257 // But we still use `optimizeDupKeyCheckForNormalInsert` to make the refactor same behavior with the original code.
258 // TODO: just use `DupKeyCheckSkip` here.
259 addRecordDupKeyCheck := optimizeDupKeyCheckForNormalInsert(e.Ctx().GetSessionVars(), txn)
260
261 _, autoColIdx, found := findAutoIncrementColumn(e.Table)
262 if !found {
263 autoColIdx = -1
264 }
265
266 for i, r := range toBeCheckedRows {
267 if r.handleKey != nil {
268 handle, err := tablecodec.DecodeRowKey(r.handleKey.newKey)
269 if err != nil {
270 return err
271 }
272
273 err = e.updateDupRow(ctx, i, txn, r, handle, e.OnDuplicate, updateDupKeyCheck, autoColIdx)
274 if err == nil {
275 continue
276 }
277 if !kv.IsErrNotFound(err) {
278 return err
279 }
280 }
281
282 for _, uk := range r.uniqueKeys {
283 _, handle, err := tables.FetchDuplicatedHandle(ctx, uk.newKey, true, txn)

Callers 1

execMethod · 0.95

Calls 15

updateDupRowMethod · 0.95
DecodeRowKeyFunction · 0.92
IsErrNotFoundFunction · 0.92
FetchDuplicatedHandleFunction · 0.92
BgLoggerFunction · 0.92
DatumsToStrNoErrFunction · 0.92
getKeysNeedCheckFunction · 0.85
findAutoIncrementColumnFunction · 0.85
prefetchDataCacheMethod · 0.80
NowMethod · 0.65

Tested by

no test coverage detected