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 scanTableData(retriever kv.Retriever, t table.Table, cols []*column.Col, startHandle, limit int64) ( []*RecordData, int64, error) { var records []*RecordData startKey := t.RecordKey(startHandle, nil) filterFunc := func(h int64, d []interface{}, cols []*column.Col) (bool, error) { if limit != 0 { r := &RecordData{ Handle: h, Values: d, } records = append(records, r) limit-- return true, nil } return false, nil } err := t.IterRecords(retriever, startKey, cols, filterFunc) if err != nil { return nil, 0, errors.Trace(err) } if len(records) == 0 { return records, startHandle, nil } nextHandle := records[len(records)-1].Handle + 1 return records, nextHandle, 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 checkResult(ctx context.Context, t table.Table, rows [][]interface{}) error { var gotRows [][]interface{} t.IterRecords(ctx, t.FirstKey(), t.WritableCols(), func(h int64, data []types.Datum, cols []*table.Column) (bool, error) { gotRows = append(gotRows, datumsToInterfaces(data)) return true, nil }) got := fmt.Sprintf("%v", gotRows) expect := fmt.Sprintf("%v", rows) if got != expect { return errors.Errorf("expect %v, got %v", expect, got) } 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][]interface{}, len(data)) for _, r := range data { if _, ok := m[r.Handle]; ok { return errors.Errorf("handle:%d is repeated in data", r.Handle) } m[r.Handle] = r.Values } startKey := t.RecordKey(0, nil) filterFunc := func(h int64, vals []interface{}, cols []*column.Col) (bool, error) { vals2, ok := m[h] if !ok { record := &RecordData{Handle: h, Values: vals} return false, errors.Errorf("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, errors.Errorf("data:%v != record:%v", record1, record2) } delete(m, h) return true, nil } err := t.IterRecords(txn, startKey, t.Cols(), filterFunc) if err != nil { return errors.Trace(err) } for h, vals := range m { record := &RecordData{Handle: h, Values: vals} return errors.Errorf("data:%v != record:%v", record, nil) } return nil }