Repository: go-gorm/gorm
Pull request #3101 (2020-07-02 08:20:07)

fix no limit no offset.
<!--
Make sure these boxes checked before submitting your pull request.

For significant changes, please open an issue to make an agreement on an implementation design/plan first before starting it.
-->

- [x] Do only one thing
- [x] Non breaking API changes
- [x] Tested

### What did this pull request do?

修复当 `limit` 为非正整数时，`offset` 的设置将无效的问题。

### User Case Description

<!-- Your use case -->
1. 仅设置 `offset`，能正常追加到 `SQL`
1. 多次设置  `offset`，将使用最后设置的值
1. 设置 `offset` 后可再次设置 `limit`，互不干涉


Patch:
diff --git a/clause/limit.go b/clause/limit.go
index ba5cf6c..1946820 100644
--- a/clause/limit.go
+++ b/clause/limit.go
@@ -18,11 +18,13 @@ func (limit Limit) Build(builder Builder) {
 	if limit.Limit > 0 {
 		builder.WriteString("LIMIT ")
 		builder.WriteString(strconv.Itoa(limit.Limit))
-
-		if limit.Offset > 0 {
-			builder.WriteString(" OFFSET ")
-			builder.WriteString(strconv.Itoa(limit.Offset))
+	}
+	if limit.Offset > 0 {
+		if limit.Limit > 0 {
+			builder.WriteString(" ")
 		}
+		builder.WriteString("OFFSET ")
+		builder.WriteString(strconv.Itoa(limit.Offset))
 	}
 }
 


Test patch:
diff --git a/clause/limit_test.go b/clause/limit_test.go
index 80317dc..c26294a 100644
--- a/clause/limit_test.go
+++ b/clause/limit_test.go
@@ -20,6 +20,18 @@ func TestLimit(t *testing.T) {
 			}},
 			"SELECT * FROM `users` LIMIT 10 OFFSET 20", nil,
 		},
+		{
+			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Offset: 20}},
+			"SELECT * FROM `users` OFFSET 20", nil,
+		},
+		{
+			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Offset: 20}, clause.Limit{Offset: 30}},
+			"SELECT * FROM `users` OFFSET 30", nil,
+		},
+		{
+			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Offset: 20}, clause.Limit{Limit: 10}},
+			"SELECT * FROM `users` LIMIT 10 OFFSET 20", nil,
+		},
 		{
 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: 10, Offset: 20}, clause.Limit{Offset: 30}},
 			"SELECT * FROM `users` LIMIT 10 OFFSET 30", nil,
@@ -30,7 +42,7 @@ func TestLimit(t *testing.T) {
 		},
 		{
 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: 10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Limit: -10}},
-			"SELECT * FROM `users`", nil,
+			"SELECT * FROM `users` OFFSET 30", nil,
 		},
 		{
 			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: 10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Limit: 50}},
diff --git a/tests/query_test.go b/tests/query_test.go
index 7973fd5..594fc26 100644
--- a/tests/query_test.go
+++ b/tests/query_test.go
@@ -381,6 +381,12 @@ func TestOffset(t *testing.T) {
 	if (len(users1) != len(users4)) || (len(users1)-len(users2) != 3) || (len(users1)-len(users3) != 5) {
 		t.Errorf("Offset should work")
 	}
+	DB.Where("name like ?", "OffsetUser%").Order("age desc").Find(&users1).Offset(3).Find(&users2).Offset(5).Find(&users3).Offset(-1).Find(&users4)
+
+	if (len(users1) != len(users4)) || (len(users1)-len(users2) != 3) || (len(users1)-len(users3) != 5) {
+		t.Errorf("Offset should work without limit.")
+	}
+
 }
 
 func TestSearchWithMap(t *testing.T) {