fix: limit=0 results (#5735)
This commit is contained in:
		
							parent
							
								
									0b7113b618
								
							
						
					
					
						commit
						50f6934033
					
				@ -244,7 +244,7 @@ func (db *DB) Order(value interface{}) (tx *DB) {
 | 
				
			|||||||
// Limit specify the number of records to be retrieved
 | 
					// Limit specify the number of records to be retrieved
 | 
				
			||||||
func (db *DB) Limit(limit int) (tx *DB) {
 | 
					func (db *DB) Limit(limit int) (tx *DB) {
 | 
				
			||||||
	tx = db.getInstance()
 | 
						tx = db.getInstance()
 | 
				
			||||||
	tx.Statement.AddClause(clause.Limit{Limit: limit})
 | 
						tx.Statement.AddClause(clause.Limit{Limit: &limit})
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -29,6 +29,7 @@ func BenchmarkSelect(b *testing.B) {
 | 
				
			|||||||
func BenchmarkComplexSelect(b *testing.B) {
 | 
					func BenchmarkComplexSelect(b *testing.B) {
 | 
				
			||||||
	user, _ := schema.Parse(&tests.User{}, &sync.Map{}, db.NamingStrategy)
 | 
						user, _ := schema.Parse(&tests.User{}, &sync.Map{}, db.NamingStrategy)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						limit10 := 10
 | 
				
			||||||
	for i := 0; i < b.N; i++ {
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
		stmt := gorm.Statement{DB: db, Table: user.Table, Schema: user, Clauses: map[string]clause.Clause{}}
 | 
							stmt := gorm.Statement{DB: db, Table: user.Table, Schema: user, Clauses: map[string]clause.Clause{}}
 | 
				
			||||||
		clauses := []clause.Interface{
 | 
							clauses := []clause.Interface{
 | 
				
			||||||
@ -43,7 +44,7 @@ func BenchmarkComplexSelect(b *testing.B) {
 | 
				
			|||||||
				clause.Or(clause.Gt{Column: "score", Value: 100}, clause.Like{Column: "name", Value: "%linus%"}),
 | 
									clause.Or(clause.Gt{Column: "score", Value: 100}, clause.Like{Column: "name", Value: "%linus%"}),
 | 
				
			||||||
			}},
 | 
								}},
 | 
				
			||||||
			clause.GroupBy{Columns: []clause.Column{{Name: "role"}}, Having: []clause.Expression{clause.Eq{"role", "admin"}}},
 | 
								clause.GroupBy{Columns: []clause.Column{{Name: "role"}}, Having: []clause.Expression{clause.Eq{"role", "admin"}}},
 | 
				
			||||||
			clause.Limit{Limit: 10, Offset: 20},
 | 
								clause.Limit{Limit: &limit10, Offset: 20},
 | 
				
			||||||
			clause.OrderBy{Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}},
 | 
								clause.OrderBy{Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}},
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import "strconv"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Limit limit clause
 | 
					// Limit limit clause
 | 
				
			||||||
type Limit struct {
 | 
					type Limit struct {
 | 
				
			||||||
	Limit  int
 | 
						Limit  *int
 | 
				
			||||||
	Offset int
 | 
						Offset int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -15,12 +15,12 @@ func (limit Limit) Name() string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Build build where clause
 | 
					// Build build where clause
 | 
				
			||||||
func (limit Limit) Build(builder Builder) {
 | 
					func (limit Limit) Build(builder Builder) {
 | 
				
			||||||
	if limit.Limit > 0 {
 | 
						if limit.Limit != nil && *limit.Limit >= 0 {
 | 
				
			||||||
		builder.WriteString("LIMIT ")
 | 
							builder.WriteString("LIMIT ")
 | 
				
			||||||
		builder.WriteString(strconv.Itoa(limit.Limit))
 | 
							builder.WriteString(strconv.Itoa(*limit.Limit))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if limit.Offset > 0 {
 | 
						if limit.Offset > 0 {
 | 
				
			||||||
		if limit.Limit > 0 {
 | 
							if limit.Limit != nil && *limit.Limit >= 0 {
 | 
				
			||||||
			builder.WriteByte(' ')
 | 
								builder.WriteByte(' ')
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		builder.WriteString("OFFSET ")
 | 
							builder.WriteString("OFFSET ")
 | 
				
			||||||
@ -33,7 +33,7 @@ func (limit Limit) MergeClause(clause *Clause) {
 | 
				
			|||||||
	clause.Name = ""
 | 
						clause.Name = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if v, ok := clause.Expression.(Limit); ok {
 | 
						if v, ok := clause.Expression.(Limit); ok {
 | 
				
			||||||
		if limit.Limit == 0 && v.Limit != 0 {
 | 
							if (limit.Limit == nil || *limit.Limit == 0) && (v.Limit != nil && *v.Limit != 0) {
 | 
				
			||||||
			limit.Limit = v.Limit
 | 
								limit.Limit = v.Limit
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,10 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestLimit(t *testing.T) {
 | 
					func TestLimit(t *testing.T) {
 | 
				
			||||||
 | 
						limit0 := 0
 | 
				
			||||||
 | 
						limit10 := 10
 | 
				
			||||||
 | 
						limit50 := 50
 | 
				
			||||||
 | 
						limitNeg10 := -10
 | 
				
			||||||
	results := []struct {
 | 
						results := []struct {
 | 
				
			||||||
		Clauses []clause.Interface
 | 
							Clauses []clause.Interface
 | 
				
			||||||
		Result  string
 | 
							Result  string
 | 
				
			||||||
@ -15,11 +19,15 @@ func TestLimit(t *testing.T) {
 | 
				
			|||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{
 | 
								[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{
 | 
				
			||||||
				Limit:  10,
 | 
									Limit:  &limit10,
 | 
				
			||||||
				Offset: 20,
 | 
									Offset: 20,
 | 
				
			||||||
			}},
 | 
								}},
 | 
				
			||||||
			"SELECT * FROM `users` LIMIT 10 OFFSET 20", nil,
 | 
								"SELECT * FROM `users` LIMIT 10 OFFSET 20", nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: &limit0}},
 | 
				
			||||||
 | 
								"SELECT * FROM `users` LIMIT 0", nil,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Offset: 20}},
 | 
								[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Offset: 20}},
 | 
				
			||||||
			"SELECT * FROM `users` OFFSET 20", nil,
 | 
								"SELECT * FROM `users` OFFSET 20", nil,
 | 
				
			||||||
@ -29,23 +37,23 @@ func TestLimit(t *testing.T) {
 | 
				
			|||||||
			"SELECT * FROM `users` OFFSET 30", nil,
 | 
								"SELECT * FROM `users` OFFSET 30", nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Offset: 20}, clause.Limit{Limit: 10}},
 | 
								[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Offset: 20}, clause.Limit{Limit: &limit10}},
 | 
				
			||||||
			"SELECT * FROM `users` LIMIT 10 OFFSET 20", nil,
 | 
								"SELECT * FROM `users` LIMIT 10 OFFSET 20", nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: 10, Offset: 20}, clause.Limit{Offset: 30}},
 | 
								[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: &limit10, Offset: 20}, clause.Limit{Offset: 30}},
 | 
				
			||||||
			"SELECT * FROM `users` LIMIT 10 OFFSET 30", nil,
 | 
								"SELECT * FROM `users` LIMIT 10 OFFSET 30", nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: 10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Offset: -10}},
 | 
								[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: &limit10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Offset: -10}},
 | 
				
			||||||
			"SELECT * FROM `users` LIMIT 10", nil,
 | 
								"SELECT * FROM `users` LIMIT 10", nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: 10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Limit: -10}},
 | 
								[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: &limit10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Limit: &limitNeg10}},
 | 
				
			||||||
			"SELECT * FROM `users` OFFSET 30", 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}},
 | 
								[]clause.Interface{clause.Select{}, clause.From{}, clause.Limit{Limit: &limit10, Offset: 20}, clause.Limit{Offset: 30}, clause.Limit{Limit: &limit50}},
 | 
				
			||||||
			"SELECT * FROM `users` LIMIT 50 OFFSET 30", nil,
 | 
								"SELECT * FROM `users` LIMIT 50 OFFSET 30", nil,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -185,7 +185,9 @@ func (db *DB) FindInBatches(dest interface{}, batchSize int, fc func(tx *DB, bat
 | 
				
			|||||||
	var totalSize int
 | 
						var totalSize int
 | 
				
			||||||
	if c, ok := tx.Statement.Clauses["LIMIT"]; ok {
 | 
						if c, ok := tx.Statement.Clauses["LIMIT"]; ok {
 | 
				
			||||||
		if limit, ok := c.Expression.(clause.Limit); ok {
 | 
							if limit, ok := c.Expression.(clause.Limit); ok {
 | 
				
			||||||
			totalSize = limit.Limit
 | 
								if limit.Limit != nil {
 | 
				
			||||||
 | 
									totalSize = *limit.Limit
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if totalSize > 0 && batchSize > totalSize {
 | 
								if totalSize > 0 && batchSize > totalSize {
 | 
				
			||||||
				batchSize = totalSize
 | 
									batchSize = totalSize
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user