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

     1  # =============================================================================
     2  # project.opt contains normalization rules for the Project operator.
     3  # =============================================================================
     4  
     5  # EliminateProject discards a Project operator which is not adding or removing
     6  # columns.
     7  [EliminateProject, Normalize]
     8  (Project
     9      $input:*
    10      $projections:[]
    11      $passthrough:* &
    12          (ColsAreEqual $passthrough (OutputCols $input))
    13  )
    14  =>
    15  $input
    16  
    17  # MergeProjects merges an outer Project operator with an inner Project operator
    18  # if there are no references to the inner synthesized columns. This has the
    19  # side effect of pruning unused synthesized columns of the inner Project.
    20  [MergeProjects, Normalize]
    21  (Project
    22      $input:(Project $innerInput:* $innerProjections:*)
    23      $projections:* &
    24          (CanMergeProjections $projections $innerProjections)
    25      $passthrough:*
    26  )
    27  =>
    28  (Project
    29      $innerInput
    30      (MergeProjections
    31          $projections
    32          $innerProjections
    33          $passthrough
    34      )
    35      (DifferenceCols
    36          $passthrough
    37          (ProjectionCols $innerProjections)
    38      )
    39  )
    40  
    41  # MergeProjectWithValues merges an outer Project operator with an inner Values
    42  # operator that has a single row, as long as:
    43  #
    44  #   1. The Values operator has a single row (since if not, the projections would
    45  #      need to replicated for each row, which is undesirable).
    46  #
    47  #   2. The projections do not reference Values columns, since combined Values
    48  #      columns cannot reference one another.
    49  #
    50  # This rule has the side effect of pruning unused columns of the Values
    51  # operator.
    52  [MergeProjectWithValues, Normalize]
    53  (Project
    54      $input:(Values [ * ])
    55      $projections:* &
    56          ^(AreProjectionsCorrelated
    57              $projections
    58              (OutputCols $input)
    59          )
    60      $passthrough:*
    61  )
    62  =>
    63  (MergeProjectWithValues $projections $passthrough $input)
    64  
    65  # PushColumnRemappingIntoValues folds ProjectionsItems into the passthrough set
    66  # if they simply remap Values output columns that are not already in
    67  # passthrough. The Values output columns are replaced with the corresponding
    68  # columns projected by the folded ProjectionsItems.
    69  #
    70  # Example:
    71  #
    72  # project
    73  #  ├── columns: x:2!null
    74  #  ├── values
    75  #  │    ├── columns: column1:1!null
    76  #  │    ├── cardinality: [2 - 2]
    77  #  │    ├── (1,)
    78  #  │    └── (2,)
    79  #  └── projections
    80  #       └── column1:1 [as=x:2, outer=(1)]
    81  # =>
    82  # project
    83  #  ├── columns: x:2!null
    84  #  └── values
    85  #       ├── columns: x:2!null
    86  #       ├── cardinality: [2 - 2]
    87  #       ├── (1,)
    88  #       └── (2,)
    89  #
    90  # This allows other rules to fire. In the example above, the project would now
    91  # be removed by EliminateProject.
    92  [PushColumnRemappingIntoValues, Normalize]
    93  (Project
    94      $input:(Values)
    95      $projections:*
    96      $passthrough:* &
    97          (CanPushColumnRemappingIntoValues
    98              $projections
    99              $passthrough
   100              $input
   101          )
   102  )
   103  =>
   104  (PushColumnRemappingIntoValues $input $projections $passthrough)
   105  
   106  # FoldTupleAccessIntoValues replaces a Values with a single column that
   107  # references a column of tuples with a new Values that has a column for each
   108  # tuple index. This works as long as the surrounding Project does not reference
   109  # the original tuple column itself, since then it would be invalid to eliminate
   110  # that reference. However, references to fields within the tuple are allowed,
   111  # and are translated to the new unnested Values columns.
   112  #
   113  # This rule simplifies access to the Values operator in hopes of allowing other
   114  # rules to fire.
   115  #
   116  # Example:
   117  #
   118  #   SELECT (tup).@1, (tup).@2 FROM (VALUES ((1,2)), ((3,4))) AS v(tup)
   119  #   =>
   120  #   SELECT tup_1, tup_2 FROM (VALUES (1, 2), (3, 4)) AS v(tup_1, tup_2)
   121  #
   122  [FoldTupleAccessIntoValues, Normalize]
   123  (Project
   124      $input:(Values) & (CanUnnestTuplesFromValues $input)
   125      $projections:* &
   126          (OnlyTupleColumnsAccessed
   127              $projections
   128              $col:(SingleColFromSet (OutputCols $input))
   129          )
   130      $passthrough:* & (ColsAreEmpty $passthrough)
   131  )
   132  =>
   133  (Project
   134      (UnnestTuplesFromValues
   135          $input
   136          $tuplecols:(MakeColsForUnnestTuples $col)
   137      )
   138      (FoldTupleColumnAccess $projections $tuplecols $col)
   139      $passthrough
   140  )