github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/plan_columns.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  var noColumns = make(sqlbase.ResultColumns, 0)
    16  
    17  // planColumns returns the signature of rows logically computed
    18  // by the given planNode.
    19  // The signature consists of the list of columns with
    20  // their name and type.
    21  //
    22  // The length of the returned slice is guaranteed to be equal to the
    23  // length of the tuple returned by the planNode's Values() method
    24  // during local execution.
    25  //
    26  // The returned slice is *not* mutable. To modify the result column
    27  // set, implement a separate recursion (e.g. needed_columns.go) or use
    28  // planMutableColumns defined below.
    29  func planColumns(plan planNode) sqlbase.ResultColumns {
    30  	return getPlanColumns(plan, false)
    31  }
    32  
    33  // planMutableColumns is similar to planColumns() but returns a
    34  // ResultColumns slice that can be modified by the caller.
    35  func planMutableColumns(plan planNode) sqlbase.ResultColumns {
    36  	return getPlanColumns(plan, true)
    37  }
    38  
    39  // getPlanColumns implements the logic for the
    40  // planColumns/planMutableColumns functions. The mut argument
    41  // indicates whether the slice should be mutable (mut=true) or not.
    42  func getPlanColumns(plan planNode, mut bool) sqlbase.ResultColumns {
    43  	switch n := plan.(type) {
    44  
    45  	// Nodes that define their own schema.
    46  	case *delayedNode:
    47  		return n.columns
    48  	case *groupNode:
    49  		return n.columns
    50  	case *joinNode:
    51  		return n.columns
    52  	case *ordinalityNode:
    53  		return n.columns
    54  	case *renderNode:
    55  		return n.columns
    56  	case *scanNode:
    57  		return n.resultColumns
    58  	case *unionNode:
    59  		return n.columns
    60  	case *valuesNode:
    61  		return n.columns
    62  	case *virtualTableNode:
    63  		return n.columns
    64  	case *explainPlanNode:
    65  		return n.run.results.columns
    66  	case *windowNode:
    67  		return n.columns
    68  	case *showTraceNode:
    69  		return n.columns
    70  	case *zeroNode:
    71  		return n.columns
    72  	case *deleteNode:
    73  		return n.columns
    74  	case *updateNode:
    75  		return n.columns
    76  	case *insertNode:
    77  		return n.columns
    78  	case *insertFastPathNode:
    79  		return n.columns
    80  	case *upsertNode:
    81  		return n.columns
    82  	case *indexJoinNode:
    83  		return n.resultColumns
    84  	case *projectSetNode:
    85  		return n.columns
    86  	case *applyJoinNode:
    87  		return n.columns
    88  	case *lookupJoinNode:
    89  		return n.columns
    90  	case *zigzagJoinNode:
    91  		return n.columns
    92  	case *vTableLookupJoinNode:
    93  		return n.columns
    94  
    95  	// Nodes with a fixed schema.
    96  	case *scrubNode:
    97  		return n.getColumns(mut, sqlbase.ScrubColumns)
    98  	case *explainDistSQLNode:
    99  		return n.getColumns(mut, sqlbase.ExplainDistSQLColumns)
   100  	case *explainVecNode:
   101  		return n.getColumns(mut, sqlbase.ExplainVecColumns)
   102  	case *relocateNode:
   103  		return n.getColumns(mut, sqlbase.AlterTableRelocateColumns)
   104  	case *scatterNode:
   105  		return n.getColumns(mut, sqlbase.AlterTableScatterColumns)
   106  	case *showFingerprintsNode:
   107  		return n.getColumns(mut, sqlbase.ShowFingerprintsColumns)
   108  	case *splitNode:
   109  		return n.getColumns(mut, sqlbase.AlterTableSplitColumns)
   110  	case *unsplitNode:
   111  		return n.getColumns(mut, sqlbase.AlterTableUnsplitColumns)
   112  	case *unsplitAllNode:
   113  		return n.getColumns(mut, sqlbase.AlterTableUnsplitColumns)
   114  	case *showTraceReplicaNode:
   115  		return n.getColumns(mut, sqlbase.ShowReplicaTraceColumns)
   116  	case *sequenceSelectNode:
   117  		return n.getColumns(mut, sqlbase.SequenceSelectColumns)
   118  	case *exportNode:
   119  		return n.getColumns(mut, sqlbase.ExportColumns)
   120  
   121  	// The columns in the hookFnNode are returned by the hook function; we don't
   122  	// know if they can be modified in place or not.
   123  	case *hookFnNode:
   124  		return n.getColumns(mut, n.header)
   125  
   126  	// Nodes that have the same schema as their source or their
   127  	// valueNode helper.
   128  	case *bufferNode:
   129  		return getPlanColumns(n.plan, mut)
   130  	case *distinctNode:
   131  		return getPlanColumns(n.plan, mut)
   132  	case *filterNode:
   133  		return getPlanColumns(n.source.plan, mut)
   134  	case *max1RowNode:
   135  		return getPlanColumns(n.plan, mut)
   136  	case *limitNode:
   137  		return getPlanColumns(n.plan, mut)
   138  	case *spoolNode:
   139  		return getPlanColumns(n.source, mut)
   140  	case *serializeNode:
   141  		return getPlanColumns(n.source, mut)
   142  	case *saveTableNode:
   143  		return getPlanColumns(n.source, mut)
   144  	case *scanBufferNode:
   145  		return getPlanColumns(n.buffer, mut)
   146  	case *sortNode:
   147  		return getPlanColumns(n.plan, mut)
   148  	case *recursiveCTENode:
   149  		return getPlanColumns(n.initial, mut)
   150  
   151  	case *rowSourceToPlanNode:
   152  		return n.planCols
   153  	}
   154  
   155  	// Every other node has no columns in their results.
   156  	return noColumns
   157  }
   158  
   159  // optColumnsSlot is a helper struct for nodes with a static signature
   160  // (e.g. explainDistSQLNode). It allows instances to reuse a common
   161  // (shared) ResultColumns slice as long as no read/write access is
   162  // requested to the slice via planMutableColumns.
   163  type optColumnsSlot struct {
   164  	columns sqlbase.ResultColumns
   165  }
   166  
   167  func (c *optColumnsSlot) getColumns(mut bool, cols sqlbase.ResultColumns) sqlbase.ResultColumns {
   168  	if c.columns != nil {
   169  		return c.columns
   170  	}
   171  	if !mut {
   172  		return cols
   173  	}
   174  	c.columns = make(sqlbase.ResultColumns, len(cols))
   175  	copy(c.columns, cols)
   176  	return c.columns
   177  }