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 }