github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/sem/tree/var_name.go (about)

     1  // Copyright 2016 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 tree
    12  
    13  import (
    14  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
    15  	"github.com/cockroachdb/errors"
    16  )
    17  
    18  // VarName occurs inside scalar expressions.
    19  //
    20  // Immediately after parsing, the following types can occur:
    21  //
    22  //   - UnqualifiedStar: a naked star as argument to a function, e.g. count(*),
    23  //     or at the top level of a SELECT clause.
    24  //     See also uses of StarExpr() and StarSelectExpr() in the grammar.
    25  //
    26  // - UnresolvedName: other names of the form `a.b....e` or `a.b...e.*`.
    27  //
    28  // Consumers of variable names do not like UnresolvedNames and instead
    29  // expect either AllColumnsSelector or ColumnItem. Use
    30  // NormalizeVarName() for this.
    31  //
    32  // After a ColumnItem is available, it should be further resolved, for this
    33  // the Resolve() method should be used; see name_resolution.go.
    34  type VarName interface {
    35  	TypedExpr
    36  
    37  	// NormalizeVarName() guarantees to return a variable name
    38  	// that is not an UnresolvedName. This converts the UnresolvedName
    39  	// to an AllColumnsSelector or ColumnItem as necessary.
    40  	NormalizeVarName() (VarName, error)
    41  }
    42  
    43  var _ VarName = &UnresolvedName{}
    44  var _ VarName = UnqualifiedStar{}
    45  var _ VarName = &AllColumnsSelector{}
    46  var _ VarName = &TupleStar{}
    47  var _ VarName = &ColumnItem{}
    48  
    49  // UnqualifiedStar corresponds to a standalone '*' in a scalar
    50  // expression.
    51  type UnqualifiedStar struct{}
    52  
    53  // Format implements the NodeFormatter interface.
    54  func (UnqualifiedStar) Format(ctx *FmtCtx) { ctx.WriteByte('*') }
    55  func (u UnqualifiedStar) String() string   { return AsString(u) }
    56  
    57  // NormalizeVarName implements the VarName interface.
    58  func (u UnqualifiedStar) NormalizeVarName() (VarName, error) { return u, nil }
    59  
    60  var singletonStarName VarName = UnqualifiedStar{}
    61  
    62  // StarExpr is a convenience function that represents an unqualified "*".
    63  func StarExpr() VarName { return singletonStarName }
    64  
    65  // ResolvedType implements the TypedExpr interface.
    66  func (UnqualifiedStar) ResolvedType() *types.T {
    67  	panic(errors.AssertionFailedf("unqualified stars ought to be replaced before this point"))
    68  }
    69  
    70  // Variable implements the VariableExpr interface.
    71  func (UnqualifiedStar) Variable() {}
    72  
    73  // UnresolvedName is defined in name_part.go. It also implements the
    74  // VarName interface, and thus TypedExpr too.
    75  
    76  // ResolvedType implements the TypedExpr interface.
    77  func (*UnresolvedName) ResolvedType() *types.T {
    78  	panic(errors.AssertionFailedf("unresolved names ought to be replaced before this point"))
    79  }
    80  
    81  // Variable implements the VariableExpr interface.  Although, the
    82  // UnresolvedName ought to be replaced to an IndexedVar before the points the
    83  // VariableExpr interface is used.
    84  func (*UnresolvedName) Variable() {}
    85  
    86  // NormalizeVarName implements the VarName interface.
    87  func (n *UnresolvedName) NormalizeVarName() (VarName, error) {
    88  	return classifyColumnItem(n)
    89  }
    90  
    91  // AllColumnsSelector corresponds to a selection of all
    92  // columns in a table when used in a SELECT clause.
    93  // (e.g. `table.*`).
    94  type AllColumnsSelector struct {
    95  	// TableName corresponds to the table prefix, before the star.
    96  	TableName *UnresolvedObjectName
    97  }
    98  
    99  // Format implements the NodeFormatter interface.
   100  func (a *AllColumnsSelector) Format(ctx *FmtCtx) {
   101  	ctx.FormatNode(a.TableName)
   102  	ctx.WriteString(".*")
   103  }
   104  func (a *AllColumnsSelector) String() string { return AsString(a) }
   105  
   106  // NormalizeVarName implements the VarName interface.
   107  func (a *AllColumnsSelector) NormalizeVarName() (VarName, error) { return a, nil }
   108  
   109  // Variable implements the VariableExpr interface.  Although, the
   110  // AllColumnsSelector ought to be replaced to an IndexedVar before the points the
   111  // VariableExpr interface is used.
   112  func (a *AllColumnsSelector) Variable() {}
   113  
   114  // ResolvedType implements the TypedExpr interface.
   115  func (*AllColumnsSelector) ResolvedType() *types.T {
   116  	panic(errors.AssertionFailedf("all-columns selectors ought to be replaced before this point"))
   117  }
   118  
   119  // ColumnItem corresponds to the name of a column in an expression.
   120  type ColumnItem struct {
   121  	// TableName holds the table prefix, if the name refers to a column. It is
   122  	// optional.
   123  	//
   124  	// This uses UnresolvedObjectName because we need to preserve the
   125  	// information about which parts were initially specified in the SQL
   126  	// text. ColumnItems are intermediate data structures anyway, that
   127  	// still need to undergo name resolution.
   128  	TableName *UnresolvedObjectName
   129  	// ColumnName names the designated column.
   130  	ColumnName Name
   131  }
   132  
   133  // Format implements the NodeFormatter interface.
   134  // If this is updated, then dummyColumnItem.Format should be updated as well.
   135  func (c *ColumnItem) Format(ctx *FmtCtx) {
   136  	if c.TableName != nil {
   137  		ctx.FormatNode(c.TableName)
   138  		ctx.WriteByte('.')
   139  	}
   140  	ctx.FormatNode(&c.ColumnName)
   141  }
   142  func (c *ColumnItem) String() string { return AsString(c) }
   143  
   144  // NormalizeVarName implements the VarName interface.
   145  func (c *ColumnItem) NormalizeVarName() (VarName, error) { return c, nil }
   146  
   147  // Column retrieves the unqualified column name.
   148  func (c *ColumnItem) Column() string {
   149  	return string(c.ColumnName)
   150  }
   151  
   152  // Variable implements the VariableExpr interface.
   153  //
   154  // Note that in common uses, ColumnItem ought to be replaced to an
   155  // IndexedVar prior to evaluation.
   156  func (c *ColumnItem) Variable() {}
   157  
   158  // ResolvedType implements the TypedExpr interface.
   159  func (c *ColumnItem) ResolvedType() *types.T {
   160  	if presetTypesForTesting == nil {
   161  		return nil
   162  	}
   163  	return presetTypesForTesting[c.String()]
   164  }
   165  
   166  // NewColumnItem constructs a column item from an already valid
   167  // TableName. This can be used for e.g. pretty-printing.
   168  func NewColumnItem(tn *TableName, colName Name) *ColumnItem {
   169  	c := MakeColumnItem(tn, colName)
   170  	return &c
   171  }
   172  
   173  // MakeColumnItem constructs a column item from an already valid
   174  // TableName. This can be used for e.g. pretty-printing.
   175  func MakeColumnItem(tn *TableName, colName Name) ColumnItem {
   176  	c := ColumnItem{ColumnName: colName}
   177  	if tn.Table() != "" {
   178  		numParts := 1
   179  		if tn.ExplicitCatalog {
   180  			numParts = 3
   181  		} else if tn.ExplicitSchema {
   182  			numParts = 2
   183  		}
   184  
   185  		c.TableName = &UnresolvedObjectName{
   186  			NumParts: numParts,
   187  			Parts:    [3]string{tn.Table(), tn.Schema(), tn.Catalog()},
   188  		}
   189  	}
   190  	return c
   191  }