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 }