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  )