func touchedMap(t table.Table) map[int]bool { touched := make(map[int]bool) for _, col := range t.Cols() { touched[col.Offset] = true } return touched }
func fetchRowColVals(txn kv.Transaction, t table.Table, handle int64, indexInfo *model.IndexInfo) ( kv.Key, []types.Datum, error) { // fetch datas cols := t.Cols() colMap := make(map[int64]*types.FieldType) for _, v := range indexInfo.Columns { col := cols[v.Offset] colMap[col.ID] = &col.FieldType } rowKey := tablecodec.EncodeRecordKey(t.RecordPrefix(), handle) rowVal, err := txn.Get(rowKey) if err != nil { return nil, nil, errors.Trace(err) } row, err := tablecodec.DecodeRow(rowVal, colMap) if err != nil { return nil, nil, errors.Trace(err) } vals := make([]types.Datum, 0, len(indexInfo.Columns)) for _, v := range indexInfo.Columns { col := cols[v.Offset] vals = append(vals, row[col.ID]) } return rowKey, vals, nil }
func (s *testColumnChangeSuite) testColumnDrop(c *C, ctx context.Context, d *ddl, tbl table.Table) { d.close() dropCol := tbl.Cols()[2] tc := &testDDLCallback{} // set up hook prevState := model.StateNone var checkErr error tc.onJobUpdated = func(job *model.Job) { if job.SchemaState == prevState { return } prevState = job.SchemaState currentTbl, err := getCurrentTable(d, s.dbInfo.ID, tbl.Meta().ID) if err != nil { checkErr = errors.Trace(err) } for _, col := range currentTbl.Cols() { if col.ID == dropCol.ID { checkErr = errors.Errorf("column is not dropped") } } } d.hook = tc d.start() testDropColumn(c, ctx, d, s.dbInfo, tbl.Meta(), dropCol.Name.L, false) }
func checkRecordAndIndex(txn kv.Transaction, t table.Table, idx table.Index) error { cols := make([]*table.Column, len(idx.Meta().Columns)) for i, col := range idx.Meta().Columns { cols[i] = t.Cols()[col.Offset] } startKey := t.RecordKey(0, nil) filterFunc := func(h1 int64, vals1 []types.Datum, cols []*table.Column) (bool, error) { isExist, h2, err := idx.Exist(txn, vals1, h1) if terror.ErrorEqual(err, kv.ErrKeyExists) { record1 := &RecordData{Handle: h1, Values: vals1} record2 := &RecordData{Handle: h2, Values: vals1} return false, errDateNotEqual.Gen("index:%v != record:%v", record2, record1) } if err != nil { return false, errors.Trace(err) } if !isExist { record := &RecordData{Handle: h1, Values: vals1} return false, errDateNotEqual.Gen("index:%v != record:%v", nil, record) } return true, nil } err := iterRecords(txn, t, startKey, cols, filterFunc) if err != nil { return errors.Trace(err) } return nil }
func checkRecordAndIndex(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error { cols := make([]*column.Col, len(idx.Columns)) for i, col := range idx.Columns { cols[i] = t.Cols()[col.Offset] } startKey := t.RecordKey(0, nil) kvIndex := kv.NewKVIndex(t.IndexPrefix(), idx.Name.L, idx.ID, idx.Unique) filterFunc := func(h1 int64, vals1 []interface{}, cols []*column.Col) (bool, error) { isExist, h2, err := kvIndex.Exist(txn, vals1, h1) if terror.ErrorEqual(err, kv.ErrKeyExists) { record1 := &RecordData{Handle: h1, Values: vals1} record2 := &RecordData{Handle: h2, Values: vals1} return false, errors.Errorf("index:%v != record:%v", record2, record1) } if err != nil { return false, errors.Trace(err) } if !isExist { record := &RecordData{Handle: h1, Values: vals1} return false, errors.Errorf("index:%v != record:%v", nil, record) } return true, nil } err := t.IterRecords(txn, startKey, cols, filterFunc) if err != nil { return errors.Trace(err) } return nil }
func (s *InsertValues) getRows(ctx context.Context, t table.Table, cols []*column.Col) (rows [][]interface{}, err error) { // process `insert|replace ... set x=y...` if err = s.fillValueList(); err != nil { return nil, errors.Trace(err) } evalMap, err := s.getColumnDefaultValues(ctx, t.Cols()) if err != nil { return nil, errors.Trace(err) } rows = make([][]interface{}, len(s.Lists)) for i, list := range s.Lists { if err = s.checkValueCount(len(s.Lists[0]), len(list), i, cols); err != nil { return nil, errors.Trace(err) } vals := make([]interface{}, len(list)) for j, expr := range list { // For "insert into t values (default)" Default Eval. evalMap[expression.ExprEvalDefaultName] = cols[j].Name.O vals[j], err = expr.Eval(ctx, evalMap) if err != nil { return nil, errors.Trace(err) } } rows[i], err = s.fillRowData(ctx, t, cols, vals) if err != nil { return nil, errors.Trace(err) } } return }
func (s *InsertValues) getRow(ctx context.Context, t table.Table, cols []*column.Col, list []expression.Expression, m map[interface{}]interface{}) ([]interface{}, error) { r := make([]interface{}, len(t.Cols())) marked := make(map[int]struct{}, len(list)) for i, expr := range list { // For "insert into t values (default)" Default Eval. m[expression.ExprEvalDefaultName] = cols[i].Name.O val, err := expr.Eval(ctx, m) if err != nil { return nil, errors.Trace(err) } r[cols[i].Offset] = val marked[cols[i].Offset] = struct{}{} } // Clear last insert id. variable.GetSessionVars(ctx).SetLastInsertID(0) err := s.initDefaultValues(ctx, t, r, marked) if err != nil { return nil, errors.Trace(err) } if err = column.CastValues(ctx, r, cols); err != nil { return nil, errors.Trace(err) } if err = column.CheckNotNull(t.Cols(), r); err != nil { return nil, errors.Trace(err) } return r, nil }
func getUpdateColumns(t table.Table, assignList []expression.Assignment, isMultipleTable bool, tblAliasMap map[string]string) ([]*column.Col, []expression.Assignment, error) { // TODO: We should check the validate if assignList in somewhere else. Maybe in building plan. // TODO: We should use field.GetFieldIndex to replace this function. tcols := make([]*column.Col, 0, len(assignList)) tAsgns := make([]expression.Assignment, 0, len(assignList)) tname := t.TableName() for _, asgn := range assignList { if isMultipleTable { if tblAliasMap != nil { if alias, ok := tblAliasMap[asgn.TableName]; ok { if !strings.EqualFold(tname.O, alias) { continue } } } else if !strings.EqualFold(tname.O, asgn.TableName) { continue } } col := column.FindCol(t.Cols(), asgn.ColName) if col == nil { if isMultipleTable { continue } return nil, nil, errors.Errorf("UPDATE: unknown column %s", asgn.ColName) } tcols = append(tcols, col) tAsgns = append(tAsgns, asgn) } return tcols, tAsgns, nil }
func (s *testIndexChangeSuite) checkAddPublic(d *ddl, ctx context.Context, writeTbl, publicTbl table.Table) error { // WriteOnlyTable: insert t values (6, 6) _, err := writeTbl.AddRecord(ctx, types.MakeDatums(6, 6)) if err != nil { return errors.Trace(err) } err = checkIndexExists(ctx, publicTbl, 6, 6, true) if err != nil { return errors.Trace(err) } // PublicTable: insert t values (7, 7) _, err = publicTbl.AddRecord(ctx, types.MakeDatums(7, 7)) if err != nil { return errors.Trace(err) } err = checkIndexExists(ctx, publicTbl, 7, 7, true) if err != nil { return errors.Trace(err) } // WriteOnlyTable: update t set c2 = 5 where c1 = 7 and c2 = 7 err = writeTbl.UpdateRecord(ctx, 7, types.MakeDatums(7, 7), types.MakeDatums(7, 5), touchedMap(writeTbl)) if err != nil { return errors.Trace(err) } err = checkIndexExists(ctx, publicTbl, 5, 7, true) if err != nil { return errors.Trace(err) } err = checkIndexExists(ctx, publicTbl, 7, 7, false) if err != nil { return errors.Trace(err) } // WriteOnlyTable: delete t where c1 = 6 err = writeTbl.RemoveRecord(ctx, 6, types.MakeDatums(6, 6)) if err != nil { return errors.Trace(err) } err = checkIndexExists(ctx, publicTbl, 6, 6, false) var rows [][]types.Datum publicTbl.IterRecords(ctx, publicTbl.FirstKey(), publicTbl.Cols(), func(h int64, data []types.Datum, cols []*table.Column) (bool, error) { rows = append(rows, data) return true, nil }) if len(rows) == 0 { return errors.New("table is empty") } for _, row := range rows { idxVal := row[1].GetInt64() handle := row[0].GetInt64() err = checkIndexExists(ctx, publicTbl, idxVal, handle, true) if err != nil { return errors.Trace(err) } } return nil }
func (s *testColumnSuite) testGetColumn(c *C, t table.Table, name string, isExist bool) { col := column.FindCol(t.Cols(), name) if isExist { c.Assert(col, NotNil) } else { c.Assert(col, IsNil) } }
// execExecSelect implements `insert table select ... from ...`. func (s *InsertValues) execSelect(t table.Table, cols []*column.Col, ctx context.Context) (rset.Recordset, error) { r, err := s.Sel.Plan(ctx) if err != nil { return nil, errors.Trace(err) } defer r.Close() if len(r.GetFields()) != len(cols) { return nil, errors.Errorf("Column count %d doesn't match value count %d", len(cols), len(r.GetFields())) } var bufRecords [][]interface{} var lastInsertIds []uint64 for { var row *plan.Row row, err = r.Next(ctx) if err != nil { return nil, errors.Trace(err) } if row == nil { break } data0 := make([]interface{}, len(t.Cols())) marked := make(map[int]struct{}, len(cols)) for i, d := range row.Data { data0[cols[i].Offset] = d marked[cols[i].Offset] = struct{}{} } if err = s.initDefaultValues(ctx, t, data0, marked); err != nil { return nil, errors.Trace(err) } if err = column.CastValues(ctx, data0, cols); err != nil { return nil, errors.Trace(err) } if err = column.CheckNotNull(t.Cols(), data0); err != nil { return nil, errors.Trace(err) } var v interface{} v, err = types.Clone(data0) if err != nil { return nil, errors.Trace(err) } bufRecords = append(bufRecords, v.([]interface{})) lastInsertIds = append(lastInsertIds, variable.GetSessionVars(ctx).LastInsertID) } for i, r := range bufRecords { variable.GetSessionVars(ctx).SetLastInsertID(lastInsertIds[i]) if _, err = t.AddRecord(ctx, r); err != nil { return nil, errors.Trace(err) } } return nil, nil }
// Add a column into table func (d *ddl) addColumn(ctx context.Context, schema model.CIStr, tbl table.Table, spec *AlterSpecification) error { // Find position cols := tbl.Cols() position := len(cols) name := spec.Column.Name // Check column name duplicate dc := column.FindCol(cols, name) if dc != nil { return errors.Errorf("Try to add a column with the same name of an already exists column.") } if spec.Position.Type == ColumnPositionFirst { position = 0 } else if spec.Position.Type == ColumnPositionAfter { // Find the mentioned column c := column.FindCol(cols, spec.Position.RelativeColumn) if c == nil { return errors.Errorf("No such column: %v", name) } // insert position is after the mentioned column position = c.Offset + 1 } // TODO: Set constraint col, _, err := d.buildColumnAndConstraint(position, spec.Column) if err != nil { return errors.Trace(err) } // insert col into the right place of the column list newCols := make([]*column.Col, 0, len(cols)+1) newCols = append(newCols, cols[:position]...) newCols = append(newCols, col) newCols = append(newCols, cols[position:]...) // adjust position if position != len(cols) { offsetChange := make(map[int]int) for i := position + 1; i < len(newCols); i++ { offsetChange[newCols[i].Offset] = i newCols[i].Offset = i } // Update index offset info for _, idx := range tbl.Indices() { for _, c := range idx.Columns { newOffset, ok := offsetChange[c.Offset] if ok { c.Offset = newOffset } } } } tb := tbl.(*tables.Table) tb.Columns = newCols // TODO: update index // TODO: update default value // update infomation schema err = d.updateInfoSchema(ctx, schema, tb.Meta()) return errors.Trace(err) }
func (d *ddl) buildIndex(ctx context.Context, t table.Table, idxInfo *model.IndexInfo, unique bool) error { firstKey := t.FirstKey() prefix := t.KeyPrefix() txn, err := ctx.GetTxn(false) if err != nil { return errors.Trace(err) } it, err := txn.Seek([]byte(firstKey)) if err != nil { return errors.Trace(err) } defer it.Close() for it.Valid() && strings.HasPrefix(it.Key(), prefix) { var err error handle, err := util.DecodeHandleFromRowKey(it.Key()) log.Info("building index...", handle) if err != nil { return errors.Trace(err) } // TODO: v is timestamp ? // fetch datas cols := t.Cols() var vals []interface{} for _, v := range idxInfo.Columns { var ( data []byte val interface{} ) col := cols[v.Offset] k := t.RecordKey(handle, col) data, err = txn.Get([]byte(k)) if err != nil { return errors.Trace(err) } val, err = t.DecodeValue(data, col) if err != nil { return errors.Trace(err) } vals = append(vals, val) } // build index kvX := kv.NewKVIndex(t.IndexPrefix(), idxInfo.Name.L, unique) err = kvX.Create(txn, vals, handle) if err != nil { return errors.Trace(err) } rk := []byte(t.RecordKey(handle, nil)) it, err = kv.NextUntil(it, util.RowKeyPrefixFilter(rk)) if err != nil { return errors.Trace(err) } } return nil }
func findColumnByName(t table.Table, tableName, colName string) (*table.Column, error) { if len(tableName) > 0 && tableName != t.Meta().Name.O { return nil, errors.Errorf("unknown field %s.%s", tableName, colName) } c := table.FindCol(t.Cols(), colName) if c == nil { return nil, errors.Errorf("unknown field %s", colName) } return c, nil }
func findColumnByName(t table.Table, name string) (*column.Col, error) { _, tableName, colName := field.SplitQualifiedName(name) if len(tableName) > 0 && tableName != t.TableName().O { return nil, errors.Errorf("unknown field %s.%s", tableName, colName) } c := column.FindCol(t.Cols(), colName) if c == nil { return nil, errors.Errorf("unknown field %s", colName) } return c, nil }
func getUpdateColumns(t table.Table, assignList []expressions.Assignment) ([]*column.Col, error) { tcols := make([]*column.Col, len(assignList)) for i, asgn := range assignList { col := column.FindCol(t.Cols(), asgn.ColName) if col == nil { return nil, errors.Errorf("UPDATE: unknown column %s", asgn.ColName) } tcols[i] = col } return tcols, nil }
func (s *testColumnSuite) testGetColumn(t table.Table, name string, isExist bool) error { col := table.FindCol(t.Cols(), name) if isExist { if col == nil { return errors.Errorf("column should not be nil") } } else { if col != nil { return errors.Errorf("column should be nil") } } return nil }
func (d *ddl) fetchRowColVals(txn kv.Transaction, t table.Table, handles []int64, indexInfo *model.IndexInfo) ( []*indexRecord, error) { // Through handles access to get all row keys. handlesLen := len(handles) rowKeys := make([]kv.Key, 0, handlesLen) for _, h := range handles { rowKey := tablecodec.EncodeRecordKey(t.RecordPrefix(), h) rowKeys = append(rowKeys, rowKey) } // Get corresponding raw values for rowKeys. ver := kv.Version{Ver: txn.StartTS()} snap, err := d.store.GetSnapshot(ver) if err != nil { return nil, errors.Trace(err) } pairMap, err := snap.BatchGet(rowKeys) if err != nil { return nil, errors.Trace(err) } // Get corresponding values for pairMap. cols := t.Cols() colMap := make(map[int64]*types.FieldType) for _, v := range indexInfo.Columns { col := cols[v.Offset] colMap[col.ID] = &col.FieldType } idxRecords := make([]*indexRecord, 0, handlesLen) for i, rowKey := range rowKeys { rawVal, ok := pairMap[string(rowKey)] if !ok { // Row doesn't exist, skip it. continue } row, err := tablecodec.DecodeRow(rawVal, colMap) if err != nil { return nil, errors.Trace(err) } rowVal := make([]types.Datum, 0, len(indexInfo.Columns)) for _, v := range indexInfo.Columns { col := cols[v.Offset] rowVal = append(rowVal, row[col.ID]) } idxRecord := &indexRecord{handle: handles[i], key: rowKey, vals: rowVal} idxRecords = append(idxRecords, idxRecord) } return idxRecords, nil }
func (s *DeleteStmt) hitWhere(ctx context.Context, t table.Table, data []interface{}) (bool, error) { if s.Where == nil { return true, nil } m := map[interface{}]interface{}{} // Set parameter for evaluating expression. for _, col := range t.Cols() { m[col.Name.L] = data[col.Offset] } ok, err := expressions.EvalBoolExpr(ctx, s.Where, m) if err != nil { return false, errors.Trace(err) } return ok, 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 }
// CompareTableRecord compares data and the corresponding table data one by one. // It returns nil if data is equal to the data that scans from table, otherwise // it returns an error with a different set of records. If exact is false, only compares handle. func CompareTableRecord(txn kv.Transaction, t table.Table, data []*RecordData, exact bool) error { m := make(map[int64][]types.Datum, len(data)) for _, r := range data { if _, ok := m[r.Handle]; ok { return errRepeatHandle.Gen("handle:%d is repeated in data", r.Handle) } m[r.Handle] = r.Values } startKey := t.RecordKey(0, nil) filterFunc := func(h int64, vals []types.Datum, cols []*table.Column) (bool, error) { vals2, ok := m[h] if !ok { record := &RecordData{Handle: h, Values: vals} return false, errDateNotEqual.Gen("data:%v != record:%v", nil, record) } if !exact { delete(m, h) return true, nil } if !reflect.DeepEqual(vals, vals2) { record1 := &RecordData{Handle: h, Values: vals2} record2 := &RecordData{Handle: h, Values: vals} return false, errDateNotEqual.Gen("data:%v != record:%v", record1, record2) } delete(m, h) return true, nil } err := iterRecords(txn, t, startKey, t.Cols(), filterFunc) if err != nil { return errors.Trace(err) } for h, vals := range m { record := &RecordData{Handle: h, Values: vals} return errDateNotEqual.Gen("data:%v != record:%v", record, nil) } return nil }
func (s *InsertValues) fillRowData(ctx context.Context, t table.Table, cols []*column.Col, vals []interface{}) ([]interface{}, error) { row := make([]interface{}, len(t.Cols())) marked := make(map[int]struct{}, len(vals)) for i, v := range vals { offset := cols[i].Offset row[offset] = v marked[offset] = struct{}{} } err := s.initDefaultValues(ctx, t, row, marked) if err != nil { return nil, errors.Trace(err) } if err = column.CastValues(ctx, row, cols); err != nil { return nil, errors.Trace(err) } if err = column.CheckNotNull(t.Cols(), row); err != nil { return nil, errors.Trace(err) } return row, nil }
func fetchRowColVals(txn kv.Transaction, t table.Table, handle int64, indexInfo *model.IndexInfo) ([]types.Datum, error) { // fetch datas cols := t.Cols() vals := make([]types.Datum, 0, len(indexInfo.Columns)) for _, v := range indexInfo.Columns { col := cols[v.Offset] k := t.RecordKey(handle, col) data, err := txn.Get(k) if err != nil { return nil, errors.Trace(err) } val, err := tables.DecodeValue(data, &col.FieldType) if err != nil { return nil, errors.Trace(err) } vals = append(vals, val) } return vals, nil }
func getUpdateColumns(t table.Table, assignList []expressions.Assignment, multipleTable bool) ([]*column.Col, error) { // TODO: We should check the validate if assignList in somewhere else. Maybe in building plan. tcols := make([]*column.Col, 0, len(assignList)) tname := t.TableName() for _, asgn := range assignList { if multipleTable { if !strings.EqualFold(tname.O, asgn.TableName) { continue } } col := column.FindCol(t.Cols(), asgn.ColName) if col == nil { if multipleTable { continue } return nil, errors.Errorf("UPDATE: unknown column %s", asgn.ColName) } tcols = append(tcols, col) } return tcols, 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 = getDefaultValue(ctx, c) 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 fetchRowColVals(txn kv.Transaction, t table.Table, handle int64, indexInfo *model.IndexInfo) ([]interface{}, error) { // fetch datas cols := t.Cols() var vals []interface{} for _, v := range indexInfo.Columns { var val interface{} col := cols[v.Offset] k := t.RecordKey(handle, col) data, err := txn.Get(k) if err != nil { return nil, errors.Trace(err) } val, err = t.DecodeValue(data, col) if err != nil { return nil, errors.Trace(err) } vals = append(vals, val) } return vals, nil }
func checkIndexAndRecord(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error { kvIndex := kv.NewKVIndex(t.IndexPrefix(), idx.Name.L, idx.ID, idx.Unique) it, err := kvIndex.SeekFirst(txn) if err != nil { return errors.Trace(err) } defer it.Close() cols := make([]*column.Col, len(idx.Columns)) for i, col := range idx.Columns { cols[i] = t.Cols()[col.Offset] } for { vals1, h, err := it.Next() if terror.ErrorEqual(err, io.EOF) { break } else if err != nil { return errors.Trace(err) } vals2, err := t.RowWithCols(txn, h, cols) if terror.ErrorEqual(err, kv.ErrNotExist) { record := &RecordData{Handle: h, Values: vals1} err = errors.Errorf("index:%v != record:%v", record, nil) } if err != nil { return errors.Trace(err) } if !reflect.DeepEqual(vals1, vals2) { record1 := &RecordData{Handle: h, Values: vals1} record2 := &RecordData{Handle: h, Values: vals2} return errors.Errorf("index:%v != record:%v", record1, record2) } } return nil }
func checkIndexAndRecord(txn kv.Transaction, t table.Table, idx table.Index) error { it, err := idx.SeekFirst(txn) if err != nil { return errors.Trace(err) } defer it.Close() cols := make([]*table.Column, len(idx.Meta().Columns)) for i, col := range idx.Meta().Columns { cols[i] = t.Cols()[col.Offset] } for { vals1, h, err := it.Next() if terror.ErrorEqual(err, io.EOF) { break } else if err != nil { return errors.Trace(err) } vals2, err := rowWithCols(txn, t, h, cols) if terror.ErrorEqual(err, kv.ErrNotExist) { record := &RecordData{Handle: h, Values: vals1} err = errDateNotEqual.Gen("index:%v != record:%v", record, nil) } if err != nil { return errors.Trace(err) } if !reflect.DeepEqual(vals1, vals2) { record1 := &RecordData{Handle: h, Values: vals1} record2 := &RecordData{Handle: h, Values: vals2} return errDateNotEqual.Gen("index:%v != record:%v", record1, record2) } } return nil }
func (s *InsertValues) initDefaultValues(ctx context.Context, t table.Table, row []interface{}, marked map[int]struct{}) (recordID int64, 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) { if recordID, err = t.AllocAutoID(); err != nil { return 0, errors.Trace(err) } row[i] = recordID } else { var value interface{} value, _, err = tables.GetColDefaultValue(ctx, &c.ColumnInfo) if err != nil { return 0, errors.Trace(err) } row[i] = value } defaultValueCols = append(defaultValueCols, c) } if err = column.CastValues(ctx, row, defaultValueCols); err != nil { return 0, errors.Trace(err) } return }
func fetchRowColVals(txn kv.Transaction, t table.Table, handle int64, indexInfo *model.IndexInfo) ([]types.Datum, error) { // fetch datas cols := t.Cols() vals := make([]types.Datum, 0, len(indexInfo.Columns)) for _, v := range indexInfo.Columns { col := cols[v.Offset] k := t.RecordKey(handle, col) data, err := txn.Get(k) if err != nil { if terror.ErrorEqual(err, kv.ErrNotExist) && !mysql.HasNotNullFlag(col.Flag) { vals = append(vals, types.Datum{}) continue } return nil, errors.Trace(err) } val, err := tables.DecodeValue(data, &col.FieldType) if err != nil { return nil, errors.Trace(err) } vals = append(vals, val) } return vals, nil }