code: func (b *batchChecker) getOldRow(ctx sessionctx.Context, t table.Table, handle int64) ([]types.Datum, error) {
  	oldValue, ok := b.dupOldRowValues[string(t.RecordKey(handle))]
  	if !ok {
  		return nil, errors.NotFoundf("can not be duplicated row, due to old row not found. handle %d", handle)
  	}
  	cols := t.WritableCols()
  	oldRow, oldRowMap, err := tables.DecodeRawRowData(ctx, t.Meta(), handle, cols, oldValue)
  	if err != nil {
  		return nil, err
  	}
  	// Fill write-only and write-reorg columns with originDefaultValue if not found in oldValue.
  	for _, col := range cols {
  		if col.State != model.StatePublic && oldRow[col.Offset].IsNull() {
  			_, found := oldRowMap[col.ID]
  			if !found {
  				oldRow[col.Offset], err = table.GetColOriginDefaultValue(ctx, col.ToInfo())
  				if err != nil {
  					return nil, err
  				}
  			}
  		}
  	}
  	return oldRow, nil
  }
docs: // getOldRow gets the table record row from storage for batch check.
  // t could be a normal table or a partition, but it must not be a PartitionedTable.