Skip to content

Commit

Permalink
fix: mssql cursor pagination (#589)
Browse files Browse the repository at this point in the history
* fix: mssql cursor pagination
  • Loading branch information
lstrihic authored Jun 22, 2022
1 parent e5d8fe8 commit b34ec97
Show file tree
Hide file tree
Showing 24 changed files with 56 additions and 3 deletions.
1 change: 1 addition & 0 deletions internal/dbtest/orm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func testAuthorRelations(t *testing.T, db *bun.DB) {
Relation("Books.Translations", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.OrderExpr("tr.id ASC")
}).
OrderExpr("author.id ASC").
Limit(1).
Scan(ctx)
require.NoError(t, err)
Expand Down
19 changes: 19 additions & 0 deletions internal/dbtest/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,25 @@ func TestQuery(t *testing.T) {
Value("updated_at", "NOW()").
Returning("*")
},
func(db *bun.DB) schema.QueryAppender {
return db.NewSelect().
Model((*Model)(nil)).
Order("id DESC").
Limit(20)
},
func(db *bun.DB) schema.QueryAppender {
return db.NewSelect().
Model((*Model)(nil)).
Order("id DESC").
Offset(20).
Limit(20)
},
func(db *bun.DB) schema.QueryAppender {
return db.NewSelect().
Model((*Model)(nil)).
Order("id DESC").
Offset(20)
},
}

timeRE := regexp.MustCompile(`'2\d{3}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d+)?(\+\d{2}:\d{2})?'`)
Expand Down
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mariadb-131
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mariadb-132
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20 OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mariadb-133
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mssql2019-131
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mssql2019-132
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 20 ROWS FETCH NEXT 20 ROWS ONLY
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mssql2019-133
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 20 ROWS
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mysql5-131
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mysql5-132
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20 OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mysql5-133
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mysql8-131
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mysql8-132
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20 OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mysql8-133
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-pg-131
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-pg-132
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20 OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-pg-133
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-pgx-131
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-pgx-132
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20 OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-pgx-133
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-sqlite-131
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-sqlite-132
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20 OFFSET 20
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-sqlite-133
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 20
18 changes: 15 additions & 3 deletions query_select.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ func NewSelectQuery(db *DB) *SelectQuery {
conn: db.DB,
},
},
offset: -1,
limit: -1,
}
}

Expand Down Expand Up @@ -505,21 +507,31 @@ func (q *SelectQuery) appendQuery(
}

if fmter.Dialect().Features().Has(feature.OffsetFetch) {
if q.offset != 0 {
if q.limit >= 0 && q.offset >= 0 {
b = append(b, " OFFSET "...)
b = strconv.AppendInt(b, int64(q.offset), 10)
b = append(b, " ROWS"...)

b = append(b, " FETCH NEXT "...)
b = strconv.AppendInt(b, int64(q.limit), 10)
b = append(b, " ROWS ONLY"...)
} else if q.limit >= 0 {
b = append(b, " OFFSET 0 ROWS"...)

b = append(b, " FETCH NEXT "...)
b = strconv.AppendInt(b, int64(q.limit), 10)
b = append(b, " ROWS ONLY"...)
} else if q.offset >= 0 {
b = append(b, " OFFSET "...)
b = strconv.AppendInt(b, int64(q.offset), 10)
b = append(b, " ROWS"...)
}
} else {
if q.limit != 0 {
if q.limit >= 0 {
b = append(b, " LIMIT "...)
b = strconv.AppendInt(b, int64(q.limit), 10)
}
if q.offset != 0 {
if q.offset >= 0 {
b = append(b, " OFFSET "...)
b = strconv.AppendInt(b, int64(q.offset), 10)
}
Expand Down

0 comments on commit b34ec97

Please sign in to comment.