Fix
This commit is contained in:
parent
72a2252049
commit
27d6d27441
@ -153,6 +153,11 @@ func Not(exprs ...Expression) Expression {
|
|||||||
if len(exprs) == 0 {
|
if len(exprs) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if len(exprs) == 1 {
|
||||||
|
if andCondition, ok := exprs[0].(AndConditions); ok {
|
||||||
|
exprs = andCondition.Exprs
|
||||||
|
}
|
||||||
|
}
|
||||||
return NotConditions{Exprs: exprs}
|
return NotConditions{Exprs: exprs}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,19 +166,58 @@ type NotConditions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (not NotConditions) Build(builder Builder) {
|
func (not NotConditions) Build(builder Builder) {
|
||||||
if len(not.Exprs) > 1 {
|
anyNegationBuilder := false
|
||||||
builder.WriteByte('(')
|
for _, c := range not.Exprs {
|
||||||
|
if _, ok := c.(NegationExpressionBuilder); ok {
|
||||||
|
anyNegationBuilder = true
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for idx, c := range not.Exprs {
|
if anyNegationBuilder {
|
||||||
if idx > 0 {
|
if len(not.Exprs) > 1 {
|
||||||
builder.WriteString(AndWithSpace)
|
builder.WriteByte('(')
|
||||||
}
|
}
|
||||||
|
|
||||||
if negationBuilder, ok := c.(NegationExpressionBuilder); ok {
|
for idx, c := range not.Exprs {
|
||||||
negationBuilder.NegationBuild(builder)
|
if idx > 0 {
|
||||||
} else {
|
builder.WriteString(AndWithSpace)
|
||||||
builder.WriteString("NOT ")
|
}
|
||||||
|
|
||||||
|
if negationBuilder, ok := c.(NegationExpressionBuilder); ok {
|
||||||
|
negationBuilder.NegationBuild(builder)
|
||||||
|
} else {
|
||||||
|
builder.WriteString("NOT ")
|
||||||
|
e, wrapInParentheses := c.(Expr)
|
||||||
|
if wrapInParentheses {
|
||||||
|
sql := strings.ToUpper(e.SQL)
|
||||||
|
if wrapInParentheses = strings.Contains(sql, AndWithSpace) || strings.Contains(sql, OrWithSpace); wrapInParentheses {
|
||||||
|
builder.WriteByte('(')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Build(builder)
|
||||||
|
|
||||||
|
if wrapInParentheses {
|
||||||
|
builder.WriteByte(')')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(not.Exprs) > 1 {
|
||||||
|
builder.WriteByte(')')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.WriteString("NOT ")
|
||||||
|
if len(not.Exprs) > 1 {
|
||||||
|
builder.WriteByte('(')
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx, c := range not.Exprs {
|
||||||
|
if idx > 0 {
|
||||||
|
builder.WriteString(AndWithSpace)
|
||||||
|
}
|
||||||
|
|
||||||
e, wrapInParentheses := c.(Expr)
|
e, wrapInParentheses := c.(Expr)
|
||||||
if wrapInParentheses {
|
if wrapInParentheses {
|
||||||
sql := strings.ToUpper(e.SQL)
|
sql := strings.ToUpper(e.SQL)
|
||||||
@ -188,9 +232,9 @@ func (not NotConditions) Build(builder Builder) {
|
|||||||
builder.WriteByte(')')
|
builder.WriteByte(')')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if len(not.Exprs) > 1 {
|
if len(not.Exprs) > 1 {
|
||||||
builder.WriteByte(')')
|
builder.WriteByte(')')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,10 +107,11 @@ func TestWhere(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{
|
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{
|
||||||
Exprs: []clause.Expression{clause.Not(clause.And(clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Expr{SQL: "`score` <= ?", Vars: []interface{}{100}, WithoutParentheses: false}))},
|
Exprs: []clause.Expression{clause.Not(clause.Expr{SQL: "`score` <= ?", Vars: []interface{}{100}},
|
||||||
|
clause.Expr{SQL: "`age` <= ?", Vars: []interface{}{60}})},
|
||||||
}},
|
}},
|
||||||
"SELECT * FROM `users` WHERE NOT (`users`.`id` = ? AND `score` <= ?)",
|
"SELECT * FROM `users` WHERE NOT (`score` <= ? AND `age` <= ?)",
|
||||||
[]interface{}{"1", 100},
|
[]interface{}{100, 60},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,6 +554,11 @@ func TestNot(t *testing.T) {
|
|||||||
if !regexp.MustCompile("SELECT \\* FROM .*users.* WHERE .*users.*..*name.* <> .+ AND .*users.*..*age.* <> .+").MatchString(result.Statement.SQL.String()) {
|
if !regexp.MustCompile("SELECT \\* FROM .*users.* WHERE .*users.*..*name.* <> .+ AND .*users.*..*age.* <> .+").MatchString(result.Statement.SQL.String()) {
|
||||||
t.Fatalf("Build NOT condition, but got %v", result.Statement.SQL.String())
|
t.Fatalf("Build NOT condition, but got %v", result.Statement.SQL.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = dryDB.Not(DB.Where("manager IS NULL").Where("age >= ?", 20)).Find(&User{})
|
||||||
|
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())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNotWithAllFields(t *testing.T) {
|
func TestNotWithAllFields(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user