code: func (e *InsertValues) batchCheckAndInsert(rows [][]types.Datum, addRecord func(row []types.Datum) (int64, error)) error {
  	// all the rows will be checked, so it is safe to set BatchCheck = true
  	e.ctx.GetSessionVars().StmtCtx.BatchCheck = true
  	err := e.batchGetInsertKeys(e.ctx, e.Table, rows)
  	if err != nil {
  		return err
  	}
  	// append warnings and get no duplicated error rows
  	for i, r := range e.toBeCheckedRows {
  		if r.handleKey != nil {
  			if _, found := e.dupKVs[string(r.handleKey.newKV.key)]; found {
  				rows[i] = nil
  				e.ctx.GetSessionVars().StmtCtx.AppendWarning(r.handleKey.dupErr)
  				continue
  			}
  		}
  		for _, uk := range r.uniqueKeys {
  			if _, found := e.dupKVs[string(uk.newKV.key)]; found {
  				// If duplicate keys were found in BatchGet, mark row = nil.
  				rows[i] = nil
  				e.ctx.GetSessionVars().StmtCtx.AppendWarning(uk.dupErr)
  				break
  			}
  		}
  		// If row was checked with no duplicate keys,
  		// it should be add to values map for the further row check.
  		// There may be duplicate keys inside the insert statement.
  		if rows[i] != nil {
  			e.ctx.GetSessionVars().StmtCtx.AddCopiedRows(1)
  			_, err = addRecord(rows[i])
  			if err != nil {
  				return err
  			}
  			if r.handleKey != nil {
  				e.dupKVs[string(r.handleKey.newKV.key)] = r.handleKey.newKV.value
  			}
  			for _, uk := range r.uniqueKeys {
  				e.dupKVs[string(uk.newKV.key)] = []byte{}
  			}
  		}
  	}
  	return nil
  }
docs: // batchCheckAndInsert checks rows with duplicate errors.
  // All duplicate rows will be ignored and appended as duplicate warnings.