func makeOr(left parser.TypedExpr, right parser.TypedExpr) parser.TypedExpr { if left == parser.DBoolTrue || right == parser.DBoolTrue { return parser.DBoolTrue } if left == parser.DBoolFalse { return right } if right == parser.DBoolFalse { return left } return parser.NewTypedOrExpr(left, right) }
// joinOrExprs performs the inverse operation of splitOrExpr, joining // together the individual expressions using OrExpr nodes. func joinOrExprs(exprs parser.TypedExprs) parser.TypedExpr { return joinExprs(exprs, func(left, right parser.TypedExpr) parser.TypedExpr { return parser.NewTypedOrExpr(left, right) }) }
func simplifyNotExpr(n *parser.NotExpr) (parser.TypedExpr, bool) { if n.Expr == parser.DNull { return parser.DNull, true } switch t := n.Expr.(type) { case *parser.ComparisonExpr: op := t.Operator switch op { case parser.EQ: op = parser.NE case parser.NE: op = parser.EQ case parser.GT: op = parser.LE case parser.GE: op = parser.LT case parser.LT: op = parser.GE case parser.LE: op = parser.GT case parser.In: op = parser.NotIn case parser.NotIn: op = parser.In case parser.Like: op = parser.NotLike case parser.NotLike: op = parser.Like case parser.ILike: op = parser.NotILike case parser.NotILike: op = parser.ILike case parser.SimilarTo: op = parser.NotSimilarTo case parser.NotSimilarTo: op = parser.SimilarTo case parser.RegMatch: op = parser.NotRegMatch case parser.RegIMatch: op = parser.NotRegIMatch default: return parser.MakeDBool(true), false } return simplifyExpr(parser.NewTypedComparisonExpr( op, t.TypedLeft(), t.TypedRight(), )) case *parser.AndExpr: // De Morgan's Law: NOT (a AND b) -> (NOT a) OR (NOT b) return simplifyExpr(parser.NewTypedOrExpr( parser.NewTypedNotExpr(t.TypedLeft()), parser.NewTypedNotExpr(t.TypedRight()), )) case *parser.OrExpr: // De Morgan's Law: NOT (a OR b) -> (NOT a) AND (NOT b) return simplifyExpr(parser.NewTypedAndExpr( parser.NewTypedNotExpr(t.TypedLeft()), parser.NewTypedNotExpr(t.TypedRight()), )) } return parser.MakeDBool(true), false }