diff --git a/internal/dbtest/orm_test.go b/internal/dbtest/orm_test.go index a5e46006e..fdcfb5037 100644 --- a/internal/dbtest/orm_test.go +++ b/internal/dbtest/orm_test.go @@ -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) diff --git a/internal/dbtest/query_test.go b/internal/dbtest/query_test.go index b5a6c79fb..3d513b582 100644 --- a/internal/dbtest/query_test.go +++ b/internal/dbtest/query_test.go @@ -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})?'`) diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mariadb-131 b/internal/dbtest/testdata/snapshots/TestQuery-mariadb-131 new file mode 100644 index 000000000..e8a0866c9 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mariadb-131 @@ -0,0 +1 @@ +SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mariadb-132 b/internal/dbtest/testdata/snapshots/TestQuery-mariadb-132 new file mode 100644 index 000000000..b435f87a4 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mariadb-132 @@ -0,0 +1 @@ +SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20 OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mariadb-133 b/internal/dbtest/testdata/snapshots/TestQuery-mariadb-133 new file mode 100644 index 000000000..4a1801b5a --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mariadb-133 @@ -0,0 +1 @@ +SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-131 b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-131 new file mode 100644 index 000000000..b593164f8 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-131 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-132 b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-132 new file mode 100644 index 000000000..ba49a5349 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-132 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 20 ROWS FETCH NEXT 20 ROWS ONLY diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-133 b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-133 new file mode 100644 index 000000000..9e9331264 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-133 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 20 ROWS diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mysql5-131 b/internal/dbtest/testdata/snapshots/TestQuery-mysql5-131 new file mode 100644 index 000000000..e8a0866c9 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mysql5-131 @@ -0,0 +1 @@ +SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mysql5-132 b/internal/dbtest/testdata/snapshots/TestQuery-mysql5-132 new file mode 100644 index 000000000..b435f87a4 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mysql5-132 @@ -0,0 +1 @@ +SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20 OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mysql5-133 b/internal/dbtest/testdata/snapshots/TestQuery-mysql5-133 new file mode 100644 index 000000000..4a1801b5a --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mysql5-133 @@ -0,0 +1 @@ +SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mysql8-131 b/internal/dbtest/testdata/snapshots/TestQuery-mysql8-131 new file mode 100644 index 000000000..e8a0866c9 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mysql8-131 @@ -0,0 +1 @@ +SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mysql8-132 b/internal/dbtest/testdata/snapshots/TestQuery-mysql8-132 new file mode 100644 index 000000000..b435f87a4 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mysql8-132 @@ -0,0 +1 @@ +SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC LIMIT 20 OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mysql8-133 b/internal/dbtest/testdata/snapshots/TestQuery-mysql8-133 new file mode 100644 index 000000000..4a1801b5a --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-mysql8-133 @@ -0,0 +1 @@ +SELECT `model`.`id`, `model`.`str` FROM `models` AS `model` ORDER BY `id` DESC OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pg-131 b/internal/dbtest/testdata/snapshots/TestQuery-pg-131 new file mode 100644 index 000000000..d4b0e6b95 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-pg-131 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pg-132 b/internal/dbtest/testdata/snapshots/TestQuery-pg-132 new file mode 100644 index 000000000..cf6f3dd67 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-pg-132 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20 OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pg-133 b/internal/dbtest/testdata/snapshots/TestQuery-pg-133 new file mode 100644 index 000000000..bd1f35781 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-pg-133 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pgx-131 b/internal/dbtest/testdata/snapshots/TestQuery-pgx-131 new file mode 100644 index 000000000..d4b0e6b95 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-pgx-131 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pgx-132 b/internal/dbtest/testdata/snapshots/TestQuery-pgx-132 new file mode 100644 index 000000000..cf6f3dd67 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-pgx-132 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20 OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pgx-133 b/internal/dbtest/testdata/snapshots/TestQuery-pgx-133 new file mode 100644 index 000000000..bd1f35781 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-pgx-133 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-131 b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-131 new file mode 100644 index 000000000..d4b0e6b95 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-131 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-132 b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-132 new file mode 100644 index 000000000..cf6f3dd67 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-132 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC LIMIT 20 OFFSET 20 diff --git a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-133 b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-133 new file mode 100644 index 000000000..bd1f35781 --- /dev/null +++ b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-133 @@ -0,0 +1 @@ +SELECT "model"."id", "model"."str" FROM "models" AS "model" ORDER BY "id" DESC OFFSET 20 diff --git a/query_select.go b/query_select.go index e993280d8..e4e68b211 100644 --- a/query_select.go +++ b/query_select.go @@ -45,6 +45,8 @@ func NewSelectQuery(db *DB) *SelectQuery { conn: db.DB, }, }, + offset: -1, + limit: -1, } } @@ -505,7 +507,7 @@ 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"...) @@ -513,13 +515,23 @@ func (q *SelectQuery) appendQuery( 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) }