From 207f1ac68f71650d6289a93a8d0e2c56ed01632d Mon Sep 17 00:00:00 2001 From: Cr <631807682@qq.com> Date: Thu, 25 Apr 2024 20:22:53 +0800 Subject: [PATCH] fix: not clause with or condition (#6984) --- clause/where.go | 7 ++++++- clause/where_test.go | 16 ++++++++++++++++ tests/query_test.go | 5 +++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/clause/where.go b/clause/where.go index 9ac78578..2c3c90f1 100644 --- a/clause/where.go +++ b/clause/where.go @@ -215,7 +215,12 @@ func (not NotConditions) Build(builder Builder) { for idx, c := range not.Exprs { if idx > 0 { - builder.WriteString(AndWithSpace) + switch c.(type) { + case OrConditions: + builder.WriteString(OrWithSpace) + default: + builder.WriteString(AndWithSpace) + } } e, wrapInParentheses := c.(Expr) diff --git a/clause/where_test.go b/clause/where_test.go index 7d5aca1f..ad23a4ed 100644 --- a/clause/where_test.go +++ b/clause/where_test.go @@ -113,6 +113,22 @@ func TestWhere(t *testing.T) { "SELECT * FROM `users` WHERE NOT (`score` <= ? AND `age` <= ?)", []interface{}{100, 60}, }, + { + []clause.Interface{clause.Select{}, clause.From{}, clause.Where{ + Exprs: []clause.Expression{ + clause.Not(clause.AndConditions{ + Exprs: []clause.Expression{ + clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, + clause.Gt{Column: "age", Value: 18}, + }}, clause.OrConditions{ + Exprs: []clause.Expression{ + clause.Lt{Column: "score", Value: 100}, + }, + }), + }}}, + "SELECT * FROM `users` WHERE NOT ((`users`.`id` = ? AND `age` > ?) OR `score` < ?)", + []interface{}{"1", 18, 100}, + }, } for idx, result := range results { diff --git a/tests/query_test.go b/tests/query_test.go index c0259a14..d0ed675a 100644 --- a/tests/query_test.go +++ b/tests/query_test.go @@ -559,6 +559,11 @@ func TestNot(t *testing.T) { if !regexp.MustCompile("SELECT \\* FROM .*users.* WHERE NOT \\(manager IS NULL AND age >= .+\\) AND .users.\\..deleted_at. IS NULL").MatchString(result.Statement.SQL.String()) { t.Fatalf("Build NOT condition, but got %v", result.Statement.SQL.String()) } + + result = dryDB.Not(DB.Where("manager IS NULL").Or("age >= ?", 20)).Find(&User{}) + if !regexp.MustCompile(`SELECT \* FROM .*users.* WHERE NOT \(manager IS NULL OR age >= .+\) AND .users.\..deleted_at. IS NULL`).MatchString(result.Statement.SQL.String()) { + t.Fatalf("Build NOT condition, but got %v", result.Statement.SQL.String()) + } } func TestNotWithAllFields(t *testing.T) {