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

     1  // Copyright 2017 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 sql
    12  
    13  import "github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    14  
    15  // ReqOrdering is the ordering that must be preserved by an operator when it is
    16  // distributed. It is used to configure DistSQL with the orderings it needs to
    17  // maintain when joining streams.
    18  type ReqOrdering = sqlbase.ColumnOrdering
    19  
    20  // planReqOrdering describes known ordering information for the rows generated by
    21  // this node. The ordering information includes columns the output is ordered
    22  // by and columns for which we know all rows have the same value.
    23  func planReqOrdering(plan planNode) ReqOrdering {
    24  	switch n := plan.(type) {
    25  	case *explainPlanNode:
    26  		return planReqOrdering(n.run.results)
    27  	case *limitNode:
    28  		return planReqOrdering(n.plan)
    29  	case *max1RowNode:
    30  		return planReqOrdering(n.plan)
    31  	case *spoolNode:
    32  		return planReqOrdering(n.source)
    33  	case *saveTableNode:
    34  		return planReqOrdering(n.source)
    35  	case *serializeNode:
    36  		return planReqOrdering(n.source)
    37  	case *deleteNode:
    38  		if n.run.rowsNeeded {
    39  			return planReqOrdering(n.source)
    40  		}
    41  	case *projectSetNode:
    42  		return n.reqOrdering
    43  
    44  	case *filterNode:
    45  		return n.reqOrdering
    46  
    47  	case *groupNode:
    48  		return n.reqOrdering
    49  
    50  	case *distinctNode:
    51  		return n.reqOrdering
    52  
    53  	case *indexJoinNode:
    54  		return n.reqOrdering
    55  
    56  	case *windowNode:
    57  		// TODO: window partitions can be ordered if the source is ordered
    58  		// appropriately.
    59  	case *joinNode:
    60  		return n.reqOrdering
    61  	case *unionNode:
    62  		// TODO(knz): this can be ordered if the source is ordered already.
    63  	case *insertNode, *insertFastPathNode:
    64  		// TODO(knz): RETURNING is ordered by the PK.
    65  	case *updateNode, *upsertNode:
    66  		// After an update, the original order may have been destroyed.
    67  		// For example, if the PK is updated by a SET expression.
    68  		// So we can't assume any ordering.
    69  		//
    70  		// TODO(knz/radu): this can be refined by an analysis which
    71  		// determines whether the columns that participate in the ordering
    72  		// of the source are being updated. If they are not, the source
    73  		// ordering can be propagated.
    74  
    75  	case *scanNode:
    76  		return n.reqOrdering
    77  	case *ordinalityNode:
    78  		return n.reqOrdering
    79  	case *renderNode:
    80  		return n.reqOrdering
    81  	case *sortNode:
    82  		return n.ordering
    83  	case *lookupJoinNode:
    84  		return n.reqOrdering
    85  	case *zigzagJoinNode:
    86  		return n.reqOrdering
    87  	}
    88  
    89  	return nil
    90  }