make NotConditions obey De Morgan's laws

This commit is contained in:
molon 2025-02-16 23:38:01 +08:00
parent 9f273777f5
commit 1cf491c2f3
2 changed files with 20 additions and 15 deletions

View File

@ -181,7 +181,7 @@ func (not NotConditions) Build(builder Builder) {
for idx, c := range not.Exprs { for idx, c := range not.Exprs {
if idx > 0 { if idx > 0 {
builder.WriteString(AndWithSpace) builder.WriteString(OrWithSpace)
} }
if negationBuilder, ok := c.(NegationExpressionBuilder); ok { if negationBuilder, ok := c.(NegationExpressionBuilder); ok {

View File

@ -56,7 +56,7 @@ func TestWhere(t *testing.T) {
}, clause.Where{ }, clause.Where{
Exprs: []clause.Expression{clause.Or(clause.Not(clause.Gt{Column: "score", Value: 100}), clause.Like{Column: "name", Value: "%linus%"})}, Exprs: []clause.Expression{clause.Or(clause.Not(clause.Gt{Column: "score", Value: 100}), clause.Like{Column: "name", Value: "%linus%"})},
}}, }},
"SELECT * FROM `users` WHERE (`users`.`id` <> ? AND `age` <= ?) OR `name` <> ? AND (`score` <= ? OR `name` LIKE ?)", "SELECT * FROM `users` WHERE (`users`.`id` <> ? OR `age` <= ?) OR `name` <> ? AND (`score` <= ? OR `name` LIKE ?)",
[]interface{}{"1", 18, "jinzhu", 100, "%linus%"}, []interface{}{"1", 18, "jinzhu", 100, "%linus%"},
}, },
{ {
@ -70,21 +70,21 @@ 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.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}), clause.And(clause.Expr{SQL: "`score` <= ?", Vars: []interface{}{100}, WithoutParentheses: false})}, Exprs: []clause.Expression{clause.Not(clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}), clause.And(clause.Expr{SQL: "`score` <= ?", Vars: []interface{}{100}, WithoutParentheses: false})},
}}, }},
"SELECT * FROM `users` WHERE (`users`.`id` <> ? AND `age` <= ?) AND `score` <= ?", "SELECT * FROM `users` WHERE (`users`.`id` <> ? OR `age` <= ?) AND `score` <= ?",
[]interface{}{"1", 18, 100}, []interface{}{"1", 18, 100},
}, },
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{ []clause.Interface{clause.Select{}, clause.From{}, clause.Where{
Exprs: []clause.Expression{clause.Not(clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}), clause.Expr{SQL: "`score` <= ?", Vars: []interface{}{100}, WithoutParentheses: false}}, Exprs: []clause.Expression{clause.Not(clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}), clause.Expr{SQL: "`score` <= ?", Vars: []interface{}{100}, WithoutParentheses: false}},
}}, }},
"SELECT * FROM `users` WHERE (`users`.`id` <> ? AND `age` <= ?) AND `score` <= ?", "SELECT * FROM `users` WHERE (`users`.`id` <> ? OR `age` <= ?) AND `score` <= ?",
[]interface{}{"1", 18, 100}, []interface{}{"1", 18, 100},
}, },
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{ []clause.Interface{clause.Select{}, clause.From{}, clause.Where{
Exprs: []clause.Expression{clause.Not(clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}), clause.Or(clause.Expr{SQL: "`score` <= ?", Vars: []interface{}{100}, WithoutParentheses: false})}, Exprs: []clause.Expression{clause.Not(clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}), clause.Or(clause.Expr{SQL: "`score` <= ?", Vars: []interface{}{100}, WithoutParentheses: false})},
}}, }},
"SELECT * FROM `users` WHERE (`users`.`id` <> ? AND `age` <= ?) OR `score` <= ?", "SELECT * FROM `users` WHERE (`users`.`id` <> ? OR `age` <= ?) OR `score` <= ?",
[]interface{}{"1", 18, 100}, []interface{}{"1", 18, 100},
}, },
{ {
@ -102,7 +102,7 @@ func TestWhere(t *testing.T) {
Exprs: []clause.Expression{clause.Not(clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, Exprs: []clause.Expression{clause.Not(clause.Eq{Column: clause.PrimaryColumn, Value: "1"},
clause.And(clause.Expr{SQL: "`score` <= ?", Vars: []interface{}{100}, WithoutParentheses: false}))}, clause.And(clause.Expr{SQL: "`score` <= ?", Vars: []interface{}{100}, WithoutParentheses: false}))},
}}, }},
"SELECT * FROM `users` WHERE (`users`.`id` <> ? AND NOT `score` <= ?)", "SELECT * FROM `users` WHERE (`users`.`id` <> ? OR NOT `score` <= ?)",
[]interface{}{"1", 100}, []interface{}{"1", 100},
}, },
{ {
@ -116,16 +116,21 @@ func TestWhere(t *testing.T) {
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{ []clause.Interface{clause.Select{}, clause.From{}, clause.Where{
Exprs: []clause.Expression{ Exprs: []clause.Expression{
clause.Not(clause.AndConditions{ clause.Not(
Exprs: []clause.Expression{ clause.AndConditions{
clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, Exprs: []clause.Expression{
clause.Gt{Column: "age", Value: 18}, clause.Eq{Column: clause.PrimaryColumn, Value: "1"},
}}, clause.OrConditions{ clause.Gt{Column: "age", Value: 18},
Exprs: []clause.Expression{ },
clause.Lt{Column: "score", Value: 100},
}, },
}), clause.OrConditions{
}}}, Exprs: []clause.Expression{
clause.Lt{Column: "score", Value: 100},
},
},
),
},
}},
"SELECT * FROM `users` WHERE NOT ((`users`.`id` = ? AND `age` > ?) OR `score` < ?)", "SELECT * FROM `users` WHERE NOT ((`users`.`id` = ? AND `age` > ?) OR `score` < ?)",
[]interface{}{"1", 18, 100}, []interface{}{"1", 18, 100},
}, },