spanner/spannertest: implement LIMIT as a rowIter
This further simplifies the implementation of the query executor.
Change-Id: I323f00bc168616530f1021afd3865fbd5a6962f3
Reviewed-on: https://code-review.googlesource.com/c/gocloud/+/52732
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Shanika Kuruppu <skuruppu@google.com>
diff --git a/spanner/spannertest/db_query.go b/spanner/spannertest/db_query.go
index 3ca4537..4e0029d 100644
--- a/spanner/spannertest/db_query.go
+++ b/spanner/spannertest/db_query.go
@@ -208,6 +208,25 @@
}
}
+// limitIter applies a LIMIT clause.
+type limitIter struct {
+ ri rowIter
+ rem int64
+}
+
+func (li *limitIter) Cols() []colInfo { return li.ri.Cols() }
+func (li *limitIter) Next() (row, error) {
+ if li.rem <= 0 {
+ return nil, io.EOF
+ }
+ row, err := li.ri.Next()
+ if err != nil {
+ return nil, err
+ }
+ li.rem--
+ return row, nil
+}
+
type queryParams map[string]interface{}
func (d *database) Query(q spansql.Query, params queryParams) (rowIter, error) {
@@ -258,20 +277,12 @@
// TODO: OFFSET
// Apply LIMIT.
- // TODO: this can be an iter too.
if q.Limit != nil {
lim, err := evalLimit(q.Limit, params)
if err != nil {
return nil, err
}
- raw, err := toRawIter(ri)
- if err != nil {
- return nil, err
- }
- if n := int(lim); n < len(raw.rows) {
- raw.rows = raw.rows[:n]
- }
- ri = raw
+ ri = &limitIter{ri: ri, rem: lim}
}
return ri, nil