func (d *ddl) backfillColumnData(t table.Table, columnInfo *model.ColumnInfo, handles []int64, reorgInfo *reorgInfo) error { for _, handle := range handles { log.Info("[ddl] backfill column...", handle) err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error { if err := d.isReorgRunnable(txn); err != nil { return errors.Trace(err) } // First check if row exists. exist, err := checkRowExist(txn, t, handle) if err != nil { return errors.Trace(err) } else if !exist { // If row doesn't exist, skip it. return nil } backfillKey := t.RecordKey(handle, &column.Col{ColumnInfo: *columnInfo}) backfillValue, err := txn.Get(backfillKey) if err != nil && !kv.IsErrNotFound(err) { return errors.Trace(err) } if backfillValue != nil { return nil } value, _, err := tables.GetColDefaultValue(nil, columnInfo) if err != nil { return errors.Trace(err) } // must convert to the column field type. v, err := types.Convert(value, &columnInfo.FieldType) if err != nil { return errors.Trace(err) } err = lockRow(txn, t, handle) if err != nil { return errors.Trace(err) } err = t.SetColValue(txn, backfillKey, v) if err != nil { return errors.Trace(err) } return errors.Trace(reorgInfo.UpdateHandle(txn, handle)) }) if err != nil { return errors.Trace(err) } } return nil }
func (s *InsertValues) getColumnDefaultValues(ctx context.Context, cols []*column.Col) (map[interface{}]interface{}, error) { defaultValMap := map[interface{}]interface{}{} for _, col := range cols { if value, ok, err := tables.GetColDefaultValue(ctx, &col.ColumnInfo); ok { if err != nil { return nil, errors.Trace(err) } defaultValMap[col.Name.L] = value } } return defaultValMap, nil }
func (s *InsertValues) initDefaultValues(ctx context.Context, t table.Table, row []interface{}, marked map[int]struct{}) error { var defaultValueCols []*column.Col for i, c := range t.Cols() { if row[i] != nil { // Column value is not nil, continue. continue } // If the nil value is evaluated in insert list, we will use nil except auto increment column. if _, ok := marked[i]; ok && !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) { continue } if mysql.HasAutoIncrementFlag(c.Flag) { recordID, err := t.AllocAutoID() if err != nil { return errors.Trace(err) } row[i] = recordID if c.IsPKHandleColumn(t.Meta()) { // Notes: incompatible with mysql // MySQL will set last insert id to the first row, as follows: // `t(id int AUTO_INCREMENT, c1 int, PRIMARY KEY (id))` // `insert t (c1) values(1),(2),(3);` // Last insert id will be 1, not 3. variable.GetSessionVars(ctx).SetLastInsertID(uint64(recordID)) } } else { var value interface{} value, _, err := tables.GetColDefaultValue(ctx, &c.ColumnInfo) if err != nil { return errors.Trace(err) } row[i] = value } defaultValueCols = append(defaultValueCols, c) } if err := column.CastValues(ctx, row, defaultValueCols); err != nil { return errors.Trace(err) } return nil }
func (s *InsertValues) initDefaultValues(ctx context.Context, t table.Table, row []interface{}, marked map[int]struct{}) error { var err error var defaultValueCols []*column.Col for i, c := range t.Cols() { if row[i] != nil { // Column value is not nil, continue. continue } // If the nil value is evaluated in insert list, we will use nil except auto increment column. if _, ok := marked[i]; ok && !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) { continue } if mysql.HasAutoIncrementFlag(c.Flag) { var id int64 if id, err = t.AllocAutoID(); err != nil { return errors.Trace(err) } row[i] = id variable.GetSessionVars(ctx).SetLastInsertID(uint64(id)) } else { var value interface{} value, _, err = tables.GetColDefaultValue(ctx, &c.ColumnInfo) if err != nil { return errors.Trace(err) } row[i] = value } defaultValueCols = append(defaultValueCols, c) } if err = column.CastValues(ctx, row, defaultValueCols); err != nil { return errors.Trace(err) } return nil }