github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/norm/rules/comp.opt (about) 1 # ============================================================================= 2 # comp.opt contains normalization rules for comparison operators. 3 # ============================================================================= 4 5 # CommuteVarInequality is similar to CommuteVar (in scalar.opt), except it 6 # handles inequality comparison operators that need special handling to commute 7 # operands. 8 [CommuteVarInequality, Normalize] 9 (Le | Lt | Ge | Gt $left:^(Variable) $right:(Variable)) 10 => 11 (CommuteInequality (OpName) $left $right) 12 13 # CommuteConstInequality is similar to CommuteConst (in scalar.opt), except 14 # that it handles inequality comparison operators that need special handling to 15 # commute operands. 16 [CommuteConstInequality, Normalize] 17 (Le | Lt | Ge | Gt $left:(ConstValue) $right:^(ConstValue)) 18 => 19 (CommuteInequality (OpName) $left $right) 20 21 # NormalizeCmpPlusConst builds up constant expression trees on one side of the 22 # comparison, in cases like this: 23 # cmp cmp 24 # / \ / \ 25 # [+] 2 -> a [-] 26 # / \ / \ 27 # a 1 2 1 28 # 29 # See the NormalizeConstEqNe pattern for the definition of constant expression 30 # tree. Also, the NormalizePlusMult pattern ensures that constant expression 31 # trees are on the right side of the expression, so no "flipped" pattern is 32 # necessary. Other patterns will fold new constant expressions further. 33 # 34 # NOTE: Ne is not part of the operator choices because it wasn't handled in 35 # normalize.go either. We can add once we've proved it's OK to do so. 36 [NormalizeCmpPlusConst, Normalize] 37 (Eq | Ge | Gt | Le | Lt 38 (Plus $leftLeft:^(ConstValue) $leftRight:(ConstValue)) 39 $right:(ConstValue) & 40 (CanConstructBinary Minus $right $leftRight) 41 ) 42 => 43 ((OpName) $leftLeft (Minus $right $leftRight)) 44 45 # NormalizeCmpMinusConst builds up constant expression trees on one side of the 46 # comparison, in cases like this: 47 # cmp cmp 48 # / \ / \ 49 # [-] 2 -> a [+] 50 # / \ / \ 51 # a 1 2 1 52 # 53 # See the NormalizeConstEqNe pattern for the definition of constant expression 54 # tree. Other patterns will fold new constant expressions further. 55 [NormalizeCmpMinusConst, Normalize] 56 (Eq | Ge | Gt | Le | Lt 57 (Minus $leftLeft:^(ConstValue) $leftRight:(ConstValue)) 58 $right:(ConstValue) & 59 (CanConstructBinary Plus $right $leftRight) 60 ) 61 => 62 ((OpName) $leftLeft (Plus $right $leftRight)) 63 64 # NormalizeCmpConstMinus builds up constant expression trees on one side of the 65 # comparison, in cases like this: 66 # cmp cmp 67 # / \ / \ 68 # [-] 2 -> [-] a 69 # / \ / \ 70 # 1 a 1 2 71 # 72 # See the NormalizeConstEqNe pattern for the definition of constant expression 73 # tree. Other patterns will switch the constant to the right side and fold the 74 # constant expression if possible. 75 [NormalizeCmpConstMinus, Normalize] 76 (Eq | Ge | Gt | Le | Lt 77 (Minus $leftLeft:(ConstValue) $leftRight:^(ConstValue)) 78 $right:(ConstValue) & 79 (CanConstructBinary Minus $leftLeft $right) 80 ) 81 => 82 ((OpName) (Minus $leftLeft $right) $leftRight) 83 84 # NormalizeTupleEquality breaks up expressions like: 85 # (a, b, c) = (x, y, z) 86 # into 87 # (a = x) AND (b = y) AND (c = z) 88 # 89 # This rule makes it easier to extract constraints from boolean expressions, 90 # so that recognition code doesn't have to handle the tuple case separately. 91 [NormalizeTupleEquality, Normalize] 92 (Eq (Tuple $left:*) (Tuple $right:*)) 93 => 94 (NormalizeTupleEquality $left $right) 95 96 # FoldNullComparisonLeft replaces the comparison operator with null if its 97 # left input is null. 98 [FoldNullComparisonLeft, Normalize] 99 (Eq | Ne | Ge | Gt | Le | Lt | Like | NotLike | ILike | NotILike 100 | SimilarTo | NotSimilarTo | RegMatch | NotRegMatch 101 | RegIMatch | NotRegIMatch | Contains | Overlaps 102 | JsonExists | JsonSomeExists | JsonAllExists 103 $left:(Null) 104 * 105 ) 106 => 107 (Null (BoolType)) 108 109 # FoldNullComparisonRight replaces the comparison operator with null if its 110 # right input is null. 111 [FoldNullComparisonRight, Normalize] 112 (Eq | Ne | Ge | Gt | Le | Lt | Like | NotLike | ILike | NotILike 113 | SimilarTo | NotSimilarTo | RegMatch | NotRegMatch 114 | RegIMatch | NotRegIMatch | Contains | Overlaps 115 | JsonExists | JsonSomeExists | JsonAllExists 116 * 117 $right:(Null) 118 ) 119 => 120 (Null (BoolType)) 121 122 # FoldIsNull replaces NULL IS NULL with True. 123 [FoldIsNull, Normalize] 124 (Is (Null) (Null)) 125 => 126 (True) 127 128 # FoldNonNullIsNull replaces x IS NULL with False where x is a non-Null constant. 129 [FoldNonNullIsNull, Normalize] 130 (Is $left:^(Null) & (IsConstValueOrTuple $left) (Null)) 131 => 132 (False) 133 134 # FoldNullTupleIsTupleNull replaces x IS NULL with True if x is a tuple with 135 # only constant, null elements. 136 [FoldNullTupleIsTupleNull, Normalize] 137 (IsTupleNull $input:(Tuple) & (HasAllNullElements $input)) 138 => 139 (True) 140 141 # FoldNonNullTupleIsTupleNull replaces x IS NULL with False if x is a tuple 142 # with at least one constant, non-null element. 143 [FoldNonNullTupleIsTupleNull, Normalize] 144 (IsTupleNull $input:(Tuple) & (HasNonNullElement $input)) 145 => 146 (False) 147 148 # FoldIsNotNull replaces NULL IS NOT NULL with False. 149 [FoldIsNotNull, Normalize] 150 (IsNot (Null) (Null)) 151 => 152 (False) 153 154 # FoldNonNullIsNotNull replaces x IS NOT NULL with True where x is a non-Null constant. 155 [FoldNonNullIsNotNull, Normalize] 156 (IsNot $left:^(Null) & (IsConstValueOrTuple $left) (Null)) 157 => 158 (True) 159 160 # FoldNonNullTupleIsTupleNotNull replaces x IS NOT NULL with True if x is a 161 # tuple with only constant, non-null elements. 162 [FoldNonNullTupleIsTupleNotNull, Normalize] 163 (IsTupleNotNull $input:(Tuple) & (HasAllNonNullElements $input)) 164 => 165 (True) 166 167 # FoldNullTupleIsTupleNotNull replaces x IS NOT NULL with False if x is a tuple 168 # with at least one constant, null element. 169 [FoldNullTupleIsTupleNotNull, Normalize] 170 (IsTupleNotNull $input:(Tuple) & (HasNullElement $input)) 171 => 172 (False) 173 174 # CommuteNullIs moves a NULL onto the right side of an IS/IS NOT comparison. 175 [CommuteNullIs, Normalize] 176 (Is | IsNot $left:(Null) $right:^(Null)) 177 => 178 ((OpName) $right $left) 179 180 # NormalizeCmpTimeZoneFunction normalizes timezone functions within 181 # comparison operators. It only matches expressions when: 182 # 183 # 1. The left side of the comparison is a timezone() function. 184 # 2. The second argument to timezone() is a variable of type TIMESTAMP. 185 # 3. The right side of the comparison is a constant value TIMESTAMPTZ. 186 # 187 # Here's an example: 188 # 189 # timezone('America/Denver', ts) = '2020-06-01 12:35:55-07' 190 # => 191 # ts = timezone('America/Denver', '2020-06-01 12:35:55-07') 192 # 193 # This normalization is valid because the overloaded function timezone(zone, 194 # TIMESTAMP) is the inverse of timezone(zone, TIMESTAMPTZ). 195 [NormalizeCmpTimeZoneFunction, Normalize] 196 (Eq | Ge | Gt | Le | Lt 197 (Function $args:* $private:(FunctionPrivate "timezone")) 198 $right:(ConstValue) & 199 (IsTimestampTZ $right) & 200 (IsTimestamp $ts:(SecondScalarListExpr $args)) & 201 ^(IsConstValueOrTuple $ts) 202 ) 203 => 204 ((OpName) 205 $ts 206 (MakeTimeZoneFunction (FirstScalarListExpr $args) $right) 207 ) 208 209 # NormalizeCmpTimeZoneFunctionTZ normalizes timezone functions within 210 # comparison operators. It only matches expressions when: 211 # 212 # 1. The left side of the comparison is a timezone() function. 213 # 2. The second argument to timezone() is a variable of type TIMESTAMPTZ. 214 # 3. The right side of the comparison is a constant value TIMESTAMP. 215 # 216 # Here's an example: 217 # 218 # timezone('America/Denver', tz) = '2020-06-01 12:35:55' 219 # => 220 # tz = timezone('America/Denver', '2020-06-01 12:35:55') 221 # 222 # This normalization is possible because the overloaded function timezone(zone, 223 # TIMESTAMPTZ) is the inverse of timezone(zone, TIMESTAMP). 224 [NormalizeCmpTimeZoneFunctionTZ, Normalize] 225 (Eq | Ge | Gt | Le | Lt 226 (Function $args:* $private:(FunctionPrivate "timezone")) 227 $right:(ConstValue) & 228 (IsTimestamp $right) & 229 (IsTimestampTZ $tz:(SecondScalarListExpr $args)) & 230 ^(IsConstValueOrTuple $tz) 231 ) 232 => 233 ((OpName) 234 $tz 235 (MakeTimeZoneFunction (FirstScalarListExpr $args) $right) 236 )