// Do implements plan.Plan Do interface. func (r *selectIndexDefaultPlan) Do(ctx context.Context, f plan.RowIterFunc) (err error) { var x kv.Index switch ix := r.x.(type) { case *column.IndexedCol: x = ix.X default: panic("should never happen") } txn, err := ctx.GetTxn(false) if err != nil { return err } en, err := x.SeekFirst(txn) if err != nil { return types.EOFAsNil(err) } defer en.Close() var id int64 for { k, _, err := en.Next() if err != nil { return types.EOFAsNil(err) } id++ if more, err := f(id, k); !more || err != nil { return err } } }
// ScanIndexData scans the index handles and values in a limited number, according to the index information. // It returns data and the next startVals until it doesn't have data, then returns data is nil and // the next startVals is the values which can't get data. If startVals = nil and limit = -1, // it returns the index data of the whole. func ScanIndexData(txn kv.Transaction, kvIndex kv.Index, startVals []interface{}, limit int64) ( []*RecordData, []interface{}, error) { it, _, err := kvIndex.Seek(txn, startVals) if err != nil { return nil, nil, errors.Trace(err) } defer it.Close() var idxRows []*RecordData var curVals []interface{} for limit != 0 { val, h, err1 := it.Next() if terror.ErrorEqual(err1, io.EOF) { return idxRows, nextIndexVals(curVals), nil } else if err1 != nil { return nil, nil, errors.Trace(err1) } idxRows = append(idxRows, &RecordData{Handle: h, Values: val}) limit-- curVals = val } nextVals, _, err := it.Next() if terror.ErrorEqual(err, io.EOF) { return idxRows, nextIndexVals(curVals), nil } else if err != nil { return nil, nil, errors.Trace(err) } return idxRows, nextVals, nil }
// GetIndexRecordsCount returns the total number of the index records from startVals. // If startVals = nil, returns the total number of the index records. func GetIndexRecordsCount(txn kv.Transaction, kvIndex kv.Index, startVals []interface{}) (int64, error) { it, _, err := kvIndex.Seek(txn, startVals) if err != nil { return 0, errors.Trace(err) } defer it.Close() var cnt int64 for { _, _, err := it.Next() if terror.ErrorEqual(err, io.EOF) { break } else if err != nil { return 0, errors.Trace(err) } cnt++ } return cnt, nil }