github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/ordering/row_number.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/physical" 17 ) 18 19 func ordinalityCanProvideOrdering(expr memo.RelExpr, required *physical.OrderingChoice) bool { 20 r := expr.(*memo.OrdinalityExpr) 21 prefix := ordinalityOrdPrefix(r, required) 22 if prefix < len(required.Columns) { 23 truncated := required.Copy() 24 truncated.Truncate(prefix) 25 return r.Ordering.Implies(&truncated) 26 } 27 return r.Ordering.Implies(required) 28 } 29 30 // ordinalityOrdPrefix is the length of the longest prefix of required.Columns 31 // before the ordinality column (or the entire length if the ordinality column 32 // is not in the required ordering). 33 // 34 // By construction, any prefix of the ordering internally required of the input 35 // (i.e. OrdinalityPrivate.Ordering) is also ordered by the ordinality column. 36 // For example, if the internal ordering is +a,+b, then the ord column numbers 37 // rows in the +a,+b order and any of these required orderings can be provided: 38 // +ord 39 // +a,+ord 40 // +a,+b,+ord 41 // 42 // As long as normalization rules are enabled, they will have already reduced 43 // the ordering required of this operator to take into account that the 44 // ordinality column is a key, so there will not be ordering columns after the 45 // ordinality column in that case. 46 func ordinalityOrdPrefix(r *memo.OrdinalityExpr, required *physical.OrderingChoice) int { 47 ordCol := opt.MakeOrderingColumn(r.ColID, false /* descending */) 48 for i := range required.Columns { 49 if required.MatchesAt(i, ordCol) { 50 return i 51 } 52 } 53 return len(required.Columns) 54 } 55 56 func ordinalityBuildChildReqOrdering( 57 parent memo.RelExpr, required *physical.OrderingChoice, childIdx int, 58 ) physical.OrderingChoice { 59 if childIdx != 0 { 60 return physical.OrderingChoice{} 61 } 62 // RowNumber always requires its internal ordering. 63 return parent.(*memo.OrdinalityExpr).Ordering 64 } 65 66 func ordinalityBuildProvided(expr memo.RelExpr, required *physical.OrderingChoice) opt.Ordering { 67 r := expr.(*memo.OrdinalityExpr) 68 childProvided := r.Input.ProvidedPhysical().Ordering 69 prefix := ordinalityOrdPrefix(r, required) 70 if prefix == len(required.Columns) { 71 // The required ordering doesn't contain the ordinality column, so it only 72 // refers to columns that are in the input. 73 return trimProvided(childProvided, required, &r.Relational().FuncDeps) 74 } 75 76 truncated := required.Copy() 77 truncated.Truncate(prefix) 78 // The input's provided ordering satisfies both <truncated> and the RowNumber 79 // internal ordering; it may need to be trimmed. 80 provided := trimProvided(childProvided, &truncated, &r.Relational().FuncDeps) 81 // Add the ordinality column to the provided ordering so that it satisfies 82 // <required>. 83 provided = append( 84 provided[:len(provided):len(provided)], // force reallocation 85 opt.MakeOrderingColumn(r.ColID, false /* descending */), 86 ) 87 return provided 88 }