github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/norm/rules/bool.opt (about)

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