diff --git a/clause/where.go b/clause/where.go index 9ac78578ea..2c3c90f18f 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 7d5aca1ffc..ad23a4ed53 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 c0259a14a3..d0ed675a98 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) {