-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
Copy pathbool.opt
164 lines (145 loc) · 4.16 KB
/
bool.opt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# =============================================================================
# bool.opt contains normalization rules for boolean And, Or, Not, and Filters
# operators.
# =============================================================================
# NormalizeNestedAnds ensures that And expressions are normalized into a left-
# deep tree. For example, the expression:
#
# A AND (B AND (C AND D))
#
# would be normalized to:
#
# And
# / \
# And D
# / \
# And C
# / \
# A B
#
# This normalization makes conjuncts easier to traverse for other rules, such as
# the ExtractRedundantConjunct rule.
[NormalizeNestedAnds, Normalize]
(And $left:* (And $innerLeft:* $innerRight:*))
=>
(And (ConcatLeftDeepAnds $left $innerLeft) $innerRight)
# SimplifyTrueAnd simplifies the And operator by discarding a True condition on
# the left side.
[SimplifyTrueAnd, Normalize]
(And (True) $right:*)
=>
$right
# SimplifyAndTrue simplifies the And operator by discarding a True condition on
# the right side.
[SimplifyAndTrue, Normalize]
(And $left:* (True))
=>
$left
# SimplifyFalseAnd maps the And operator to False if its left input is False.
[SimplifyFalseAnd, Normalize]
(And $left:(False) *)
=>
$left
# SimplifyAndFalse maps the And operator to False if its right input is False.
[SimplifyAndFalse, Normalize]
(And * $right:(False))
=>
$right
# SimplifyTrueOr maps the Or operator to True if its left input is True.
[SimplifyTrueOr, Normalize]
(Or $left:(True) *)
=>
$left
# SimplifyOrTrue maps the Or operator to True if its righht input is True.
[SimplifyOrTrue, Normalize]
(Or * $right:(True))
=>
$right
# SimplifyFalseOr simplifies the Or operator by discarding a False condition on
# the left side.
[SimplifyFalseOr, Normalize]
(Or (False) $right:*)
=>
$right
# SimplifyOrFalse simplifies the Or operator by discarding a False condition on
# the right side.
[SimplifyOrFalse, Normalize]
(Or $left:* (False))
=>
$left
# SimplifyRange simplifies a Range operator for which the input is no longer an
# And expression, likely due to simplification of the And operator itself.
[SimplifyRange, Normalize]
(Range $input:^(And))
=>
$input
# FoldNullAndOr replaces the operator with null if both operands are null.
[FoldNullAndOr, Normalize]
(And | Or (Null) (Null))
=>
(Null (BoolType))
# FoldNotTrue replaces NOT(True) with False.
[FoldNotTrue, Normalize]
(Not (True))
=>
(False)
# FoldNotFalse replaces NOT(False) with True.
[FoldNotFalse, Normalize]
(Not (False))
=>
(True)
# FoldNotNull replaces NOT(Null) with Null.
[FoldNotNull, Normalize]
(Not (Null))
=>
(Null (BoolType))
# NegateComparison inverts eligible comparison operators when they are negated
# by the Not operator. For example, Eq maps to Ne, and Gt maps to Le. All
# comparisons can be negated except for the JSON comparisons.
[NegateComparison, Normalize]
(Not
$input:(Comparison $left:* $right:*) &
^(Contains | JsonExists | JsonSomeExists | JsonAllExists
| Overlaps
)
)
=>
(NegateComparison (OpName $input) $left $right)
# EliminateNot discards a doubled Not operator.
[EliminateNot, Normalize]
(Not (Not $input:*))
=>
$input
# NegateAnd converts the negation of a conjunction into a disjunction of
# negations.
[NegateAnd, Normalize]
(Not (And $left:* $right:*))
=>
(Or (Not $left) (Not $right))
# NegateOr converts the negation of a disjunction into a conjunction of
# negations.
[NegateOr, Normalize]
(Not (Or $left:* $right:*))
=>
(And (Not $left) (Not $right))
# ExtractRedundantConjunct matches an OR expression in which the same conjunct
# appears in both the left and right OR conditions:
#
# A OR (A AND B) => A
# (A AND B) OR (A AND C) => A AND (B OR C)
#
# In both these cases, the redundant conjunct is A.
#
# This transformation is useful for finding a conjunct that can be pushed down
# in the query tree. For example, if the redundant conjunct A is fully bound by
# one side of a join, it can be pushed through the join, even if B AND C cannot.
[ExtractRedundantConjunct, Normalize]
(Or
$left:^(Or)
$right:^(Or) &
(Succeeded
$conjunct:(FindRedundantConjunct $left $right)
)
)
=>
(ExtractRedundantConjunct $conjunct $left $right)