github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/ordering/select.go (about) 1 // Copyright 2018 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 ordering 12 13 import ( 14 "github.com/cockroachdb/cockroach/pkg/sql/opt" 15 "github.com/cockroachdb/cockroach/pkg/sql/opt/memo" 16 "github.com/cockroachdb/cockroach/pkg/sql/opt/props" 17 "github.com/cockroachdb/cockroach/pkg/sql/opt/props/physical" 18 ) 19 20 func selectCanProvideOrdering(expr memo.RelExpr, required *physical.OrderingChoice) bool { 21 // Select operator can always pass through ordering to its input. 22 return true 23 } 24 25 func selectBuildChildReqOrdering( 26 parent memo.RelExpr, required *physical.OrderingChoice, childIdx int, 27 ) physical.OrderingChoice { 28 if childIdx != 0 { 29 return physical.OrderingChoice{} 30 } 31 return trimColumnGroups(required, &parent.(*memo.SelectExpr).Input.Relational().FuncDeps) 32 } 33 34 // trimColumnGroups removes columns from ColumnOrderingChoice groups as 35 // necessary, so that all columns in each group are equivalent according to 36 // the given FDs. It is used when the parent expression can have column 37 // equivalences that the input expression does not (for example a Select with an 38 // equality condition); the columns in a group must be equivalent at the level 39 // of the operator where the ordering is required. 40 func trimColumnGroups( 41 required *physical.OrderingChoice, fds *props.FuncDepSet, 42 ) physical.OrderingChoice { 43 res := *required 44 copied := false 45 for i := range res.Columns { 46 c := &res.Columns[i] 47 eqGroup := fds.ComputeEquivGroup(c.AnyID()) 48 if !c.Group.SubsetOf(eqGroup) { 49 if !copied { 50 res = res.Copy() 51 copied = true 52 } 53 res.Columns[i].Group = c.Group.Intersection(eqGroup) 54 } 55 } 56 return res 57 } 58 59 func selectBuildProvided(expr memo.RelExpr, required *physical.OrderingChoice) opt.Ordering { 60 s := expr.(*memo.SelectExpr) 61 rel := s.Relational() 62 // We don't need to remap columns, but we want to remove columns that are now 63 // unnecessary (e.g. because the Select constrains them to be constant). 64 return remapProvided(s.Input.ProvidedPhysical().Ordering, &rel.FuncDeps, rel.OutputCols) 65 }