Skip to content

Commit 2acd313

Browse files
authored
Merge pull request #201 from erizocosmico/perf/not-query-if-no-more-rows
do not query again if result is less than limit
2 parents 55ff0a4 + 1ea3474 commit 2acd313

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

batcher.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func newBatchQueryRunner(schema Schema, db squirrel.DBProxy, q Query) *batchQuer
5252
}
5353

5454
func (r *batchQueryRunner) next() (Record, error) {
55-
if r.eof {
55+
if r.eof && len(r.records) == 0 {
5656
return nil, errNoMoreRows
5757
}
5858

@@ -63,7 +63,7 @@ func (r *batchQueryRunner) next() (Record, error) {
6363
)
6464

6565
limit := r.q.GetLimit()
66-
if limit <= 0 || limit > uint64(r.total) {
66+
if limit == 0 || limit > uint64(r.total) {
6767
records, err = r.loadNextBatch()
6868
if err != nil {
6969
return nil, err
@@ -75,6 +75,17 @@ func (r *batchQueryRunner) next() (Record, error) {
7575
return nil, errNoMoreRows
7676
}
7777

78+
batchSize := r.q.GetBatchSize()
79+
if batchSize > 0 && batchSize < limit {
80+
if uint64(len(records)) < batchSize {
81+
r.eof = true
82+
}
83+
} else if limit > 0 {
84+
if uint64(len(records)) < limit {
85+
r.eof = true
86+
}
87+
}
88+
7889
r.total += len(records)
7990
r.records = records[1:]
8091
return records[0], nil

batcher_test.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func TestBatcherLimit(t *testing.T) {
5454
q.BatchSize(2)
5555
q.Limit(5)
5656
r.NoError(q.AddRelation(RelSchema, "rels", OneToMany, Eq(f("foo"), "1")))
57-
runner := newBatchQueryRunner(ModelSchema, squirrel.NewStmtCacher(db), q)
57+
runner := newBatchQueryRunner(ModelSchema, store.proxy, q)
5858
rs := NewBatchingResultSet(runner)
5959

6060
var count int
@@ -66,3 +66,42 @@ func TestBatcherLimit(t *testing.T) {
6666
r.NoError(err)
6767
r.Equal(5, count)
6868
}
69+
70+
func TestBatcherNoExtraQueryIfLessThanLimit(t *testing.T) {
71+
r := require.New(t)
72+
db, err := openTestDB()
73+
r.NoError(err)
74+
setupTables(t, db)
75+
defer db.Close()
76+
defer teardownTables(t, db)
77+
78+
store := NewStore(db)
79+
for i := 0; i < 4; i++ {
80+
m := newModel("foo", "bar", 1)
81+
r.NoError(store.Insert(ModelSchema, m))
82+
83+
for i := 0; i < 4; i++ {
84+
r.NoError(store.Insert(RelSchema, newRel(m.GetID(), fmt.Sprint(i))))
85+
}
86+
}
87+
88+
q := NewBaseQuery(ModelSchema)
89+
q.Limit(6)
90+
r.NoError(q.AddRelation(RelSchema, "rels", OneToMany, Eq(f("foo"), "1")))
91+
var queries int
92+
proxy := store.DebugWith(func(_ string, _ ...interface{}) {
93+
queries++
94+
}).proxy
95+
runner := newBatchQueryRunner(ModelSchema, proxy, q)
96+
rs := NewBatchingResultSet(runner)
97+
98+
var count int
99+
for rs.Next() {
100+
_, err := rs.Get(nil)
101+
r.NoError(err)
102+
count++
103+
}
104+
r.NoError(err)
105+
r.Equal(4, count)
106+
r.Equal(2, queries)
107+
}

0 commit comments

Comments
 (0)