diff --git a/plan/plans/from.go b/plan/plans/from.go index 2b7031507c..f8d2260a75 100644 --- a/plan/plans/from.go +++ b/plan/plans/from.go @@ -43,7 +43,8 @@ var ( // TableNilPlan iterates rows but does nothing, e.g. SELECT 1 FROM t; type TableNilPlan struct { - T table.Table + T table.Table + iter kv.Iterator } // Explain implements the plan.Plan interface. @@ -97,14 +98,42 @@ func (r *TableNilPlan) Do(ctx context.Context, f plan.RowIterFunc) error { // Next implements plan.Plan Next interface. func (r *TableNilPlan) Next(ctx context.Context) (row *plan.Row, err error) { + if r.iter == nil { + var txn kv.Transaction + txn, err = ctx.GetTxn(false) + if err != nil { + return nil, errors.Trace(err) + } + r.iter, err = txn.Seek([]byte(r.T.FirstKey()), nil) + if err != nil { + return nil, errors.Trace(err) + } + } + if !r.iter.Valid() || !strings.HasPrefix(r.iter.Key(), r.T.KeyPrefix()) { + return + } + id, err := util.DecodeHandleFromRowKey(r.iter.Key()) + if err != nil { + return nil, errors.Trace(err) + } + rk := r.T.RecordKey(id, nil) + row = &plan.Row{} + r.iter, err = kv.NextUntil(r.iter, util.RowKeyPrefixFilter(rk)) return } // Close implements plan.Plan Close interface. func (r *TableNilPlan) Close() error { + r.iter.Close() return nil } +// UseNext implements NextPlan interface +func (r *TableNilPlan) UseNext() bool { + log.Warn("use next") + return true +} + // TableDefaultPlan iterates rows from a table, in general case // it performs a full table scan, but using Filter function, // it will return a new IndexPlan if an index is found in Filter function. diff --git a/plan/plans/from_test.go b/plan/plans/from_test.go index 7347901522..f7c175473c 100644 --- a/plan/plans/from_test.go +++ b/plan/plans/from_test.go @@ -109,8 +109,14 @@ func (p *testFromSuit) TestTableNilPlan(c *C) { T: p.tbl, } var ids []int64 - nilPlan.Do(p, func(id interface{}, data []interface{}) (bool, error) { - ids = append(ids, id.(int64)) + rset := rsets.Recordset{ + Plan: nilPlan, + Ctx: p, + } + var id int64 + rset.Do(func(data []interface{}) (bool, error) { + id++ + ids = append(ids, id) return true, nil }) c.Assert(reflect.DeepEqual(ids, []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), Equals, true)