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

     1  // Copyright 2020 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package norm
    12  
    13  import (
    14  	"github.com/cockroachdb/cockroach/pkg/sql/opt"
    15  	"github.com/cockroachdb/cockroach/pkg/sql/opt/memo"
    16  )
    17  
    18  // ProjectColMapLeft returns a Projections operator that maps the left side
    19  // columns in a SetPrivate to the output columns in it. Useful for replacing set
    20  // operations with simpler constructs.
    21  func (c *CustomFuncs) ProjectColMapLeft(set *memo.SetPrivate) memo.ProjectionsExpr {
    22  	return c.projectColMapSide(set.OutCols, set.LeftCols)
    23  }
    24  
    25  // ProjectColMapRight returns a Project operator that maps the right side
    26  // columns in a SetPrivate to the output columns in it. Useful for replacing set
    27  // operations with simpler constructs.
    28  func (c *CustomFuncs) ProjectColMapRight(set *memo.SetPrivate) memo.ProjectionsExpr {
    29  	return c.projectColMapSide(set.OutCols, set.RightCols)
    30  }
    31  
    32  // projectColMapSide implements the side-agnostic logic from ProjectColMapLeft
    33  // and ProjectColMapRight.
    34  func (c *CustomFuncs) projectColMapSide(toList, fromList opt.ColList) memo.ProjectionsExpr {
    35  	items := make(memo.ProjectionsExpr, 0, len(toList))
    36  	for idx, fromCol := range fromList {
    37  		toCol := toList[idx]
    38  		// If the to and from col ids are the same, do not project them. They
    39  		// are passed-through instead. See opt.Metadata for more details about
    40  		// why some col ids could exist on one side and the output of a set
    41  		// operation.
    42  		if fromCol != toCol {
    43  			items = append(items, c.f.ConstructProjectionsItem(c.f.ConstructVariable(fromCol), toCol))
    44  		}
    45  	}
    46  	return items
    47  }
    48  
    49  // ProjectPassthroughLeft returns a ColSet that contains the columns that can
    50  // be passed-through from the left side in a SetPrivate when eliminating a set
    51  // operation, like in EliminateUnionAllLeft. Columns in both the output
    52  // ColList and the left ColList should be passed-through.
    53  func (c *CustomFuncs) ProjectPassthroughLeft(set *memo.SetPrivate) opt.ColSet {
    54  	out := set.OutCols.ToSet()
    55  	out.IntersectionWith(set.LeftCols.ToSet())
    56  	return out
    57  }
    58  
    59  // ProjectPassthroughRight returns a ColSet that contains the columns that can
    60  // be passed-through from the right side in a SetPrivate when eliminating a set
    61  // operation, like in EliminateUnionAllRight. Columns in both the output
    62  // ColList and the right ColList should be passed-through.
    63  func (c *CustomFuncs) ProjectPassthroughRight(set *memo.SetPrivate) opt.ColSet {
    64  	out := set.OutCols.ToSet()
    65  	out.IntersectionWith(set.RightCols.ToSet())
    66  	return out
    67  }
    68  
    69  // PruneSetPrivate returns a SetPrivate based on the given SetPrivate, but with
    70  // unneeded input and output columns discarded.
    71  func (c *CustomFuncs) PruneSetPrivate(needed opt.ColSet, set *memo.SetPrivate) *memo.SetPrivate {
    72  	length := needed.Len()
    73  	prunedSet := memo.SetPrivate{
    74  		LeftCols:  make(opt.ColList, 0, length),
    75  		RightCols: make(opt.ColList, 0, length),
    76  		OutCols:   make(opt.ColList, 0, length),
    77  	}
    78  	for idx, outCol := range set.OutCols {
    79  		if needed.Contains(outCol) {
    80  			prunedSet.LeftCols = append(prunedSet.LeftCols, set.LeftCols[idx])
    81  			prunedSet.RightCols = append(prunedSet.RightCols, set.RightCols[idx])
    82  			prunedSet.OutCols = append(prunedSet.OutCols, outCol)
    83  		}
    84  	}
    85  	return &prunedSet
    86  }