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 (d *ddl) backfillTableIndex(t table.Table, indexInfo *model.IndexInfo, handles []int64, reorgInfo *reorgInfo) error { kvX := tables.NewIndex(t.Meta(), indexInfo) for _, handle := range handles { log.Debug("[ddl] building index...", handle) err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error { if err := d.isReorgRunnable(txn); err != nil { return errors.Trace(err) } vals, err1 := fetchRowColVals(txn, t, handle, indexInfo) if terror.ErrorEqual(err1, kv.ErrNotExist) { // row doesn't exist, skip it. return nil } if err1 != nil { return errors.Trace(err1) } exist, _, err1 := kvX.Exist(txn, vals, handle) if err1 != nil { return errors.Trace(err1) } else if exist { // index already exists, skip it. return nil } rowKey := tablecodec.EncodeRecordKey(t.RecordPrefix(), handle) err1 = txn.LockKeys(rowKey) if err1 != nil { return errors.Trace(err1) } // create the index. err1 = kvX.Create(txn, vals, handle) if err1 != nil { return errors.Trace(err1) } // update reorg next handle return errors.Trace(reorgInfo.UpdateHandle(txn, handle)) }) if err != nil { return errors.Trace(err) } } 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 }
// RecordKey implements table.Table RecordKey interface. func (t *BoundedTable) RecordKey(h int64) kv.Key { return tablecodec.EncodeRecordKey(t.recordPrefix, h) }
// RecordKey implements table.Table RecordKey interface. func (t *MemoryTable) RecordKey(h int64) kv.Key { return tablecodec.EncodeRecordKey(t.recordPrefix, h) }