github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sem/tree/table_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 // TableName corresponds to the name of a table in a FROM clause, 14 // INSERT or UPDATE statement, etc. 15 // 16 // This is constructed for incoming SQL queries from an UnresolvedObjectName, 17 // 18 // Internal uses of this struct should not construct instances of 19 // TableName directly, and instead use the NewTableName / 20 // MakeTableName functions underneath. 21 // 22 // TableName is a public type for objName. It exposes the fields 23 // and can be default-constructed but cannot be instantiated with a 24 // non-default value; this encourages the use of the constructors below. 25 type TableName struct { 26 objName 27 } 28 29 // Format implements the NodeFormatter interface. 30 func (t *TableName) Format(ctx *FmtCtx) { 31 if ctx.tableNameFormatter != nil { 32 ctx.tableNameFormatter(ctx, t) 33 return 34 } 35 t.ObjectNamePrefix.Format(ctx) 36 if t.ExplicitSchema || ctx.alwaysFormatTablePrefix() { 37 ctx.WriteByte('.') 38 } 39 ctx.FormatNode(&t.ObjectName) 40 } 41 func (t *TableName) String() string { return AsString(t) } 42 43 func (t *TableName) objectName() {} 44 45 // FQString renders the table name in full, not omitting the prefix 46 // schema and catalog names. Suitable for logging, etc. 47 func (t *TableName) FQString() string { 48 ctx := NewFmtCtx(FmtSimple) 49 ctx.FormatNode(&t.CatalogName) 50 ctx.WriteByte('.') 51 ctx.FormatNode(&t.SchemaName) 52 ctx.WriteByte('.') 53 ctx.FormatNode(&t.ObjectName) 54 return ctx.CloseAndGetString() 55 } 56 57 // Table retrieves the unqualified table name. 58 func (t *TableName) Table() string { 59 return string(t.ObjectName) 60 } 61 62 // Equals returns true if the two table names are identical (including 63 // the ExplicitSchema/ExplicitCatalog flags). 64 func (t *TableName) Equals(other *TableName) bool { 65 return *t == *other 66 } 67 68 // tableExpr implements the TableExpr interface. 69 func (*TableName) tableExpr() {} 70 71 // MakeTableName creates a new table name qualified with just a schema. 72 func MakeTableName(db, tbl Name) TableName { 73 return TableName{objName{ 74 ObjectName: tbl, 75 ObjectNamePrefix: ObjectNamePrefix{ 76 CatalogName: db, 77 SchemaName: PublicSchemaName, 78 ExplicitSchema: true, 79 ExplicitCatalog: true, 80 }, 81 }} 82 } 83 84 // NewTableName creates a new table name qualified with a given 85 // catalog and the public schema. 86 func NewTableName(db, tbl Name) *TableName { 87 tn := MakeTableName(db, tbl) 88 return &tn 89 } 90 91 // MakeTableNameWithSchema creates a new fully qualified table name. 92 func MakeTableNameWithSchema(db, schema, tbl Name) TableName { 93 return TableName{objName{ 94 ObjectName: tbl, 95 ObjectNamePrefix: ObjectNamePrefix{ 96 CatalogName: db, 97 SchemaName: schema, 98 ExplicitSchema: true, 99 ExplicitCatalog: true, 100 }, 101 }} 102 } 103 104 // MakeTableNameFromPrefix creates a table name from an unqualified name 105 // and a resolved prefix. 106 func MakeTableNameFromPrefix(prefix ObjectNamePrefix, object Name) TableName { 107 return TableName{objName{ 108 ObjectName: object, 109 ObjectNamePrefix: prefix, 110 }} 111 } 112 113 // MakeUnqualifiedTableName creates a new base table name. 114 func MakeUnqualifiedTableName(tbl Name) TableName { 115 return TableName{objName{ 116 ObjectName: tbl, 117 }} 118 } 119 120 // NewUnqualifiedTableName creates a new base table name. 121 func NewUnqualifiedTableName(tbl Name) *TableName { 122 tn := MakeUnqualifiedTableName(tbl) 123 return &tn 124 } 125 126 func makeTableNameFromUnresolvedName(n *UnresolvedName) TableName { 127 return TableName{objName{ 128 ObjectName: Name(n.Parts[0]), 129 ObjectNamePrefix: makeObjectNamePrefixFromUnresolvedName(n), 130 }} 131 } 132 133 func makeObjectNamePrefixFromUnresolvedName(n *UnresolvedName) ObjectNamePrefix { 134 return ObjectNamePrefix{ 135 SchemaName: Name(n.Parts[1]), 136 CatalogName: Name(n.Parts[2]), 137 ExplicitSchema: n.NumParts >= 2, 138 ExplicitCatalog: n.NumParts >= 3, 139 } 140 } 141 142 // TableNames represents a comma separated list (see the Format method) 143 // of table names. 144 type TableNames []TableName 145 146 // Format implements the NodeFormatter interface. 147 func (ts *TableNames) Format(ctx *FmtCtx) { 148 sep := "" 149 for i := range *ts { 150 ctx.WriteString(sep) 151 ctx.FormatNode(&(*ts)[i]) 152 sep = ", " 153 } 154 } 155 func (ts *TableNames) String() string { return AsString(ts) } 156 157 // TableIndexName refers to a table index. There are a few cases: 158 // 159 // - if both the table name and the index name are set, refers to a specific 160 // index in a specific table. 161 // 162 // - if the table name is set and index name is empty, refers to the primary 163 // index of that table. 164 // 165 // - if the table name is empty and the index name is set, refers to an index 166 // of that name among all tables within a catalog/schema; if there is a 167 // duplicate name, that will result in an error. Note that it is possible to 168 // specify the schema or catalog without specifying a table name; in this 169 // case, Table.ObjectNamePrefix has the fields set but Table.ObjectName is 170 // empty. 171 type TableIndexName struct { 172 Table TableName 173 Index UnrestrictedName 174 } 175 176 // Format implements the NodeFormatter interface. 177 func (n *TableIndexName) Format(ctx *FmtCtx) { 178 if n.Index == "" { 179 ctx.FormatNode(&n.Table) 180 return 181 } 182 183 if n.Table.ObjectName != "" { 184 // The table is specified. 185 ctx.FormatNode(&n.Table) 186 ctx.WriteByte('@') 187 ctx.FormatNode(&n.Index) 188 return 189 } 190 191 // The table is not specified. The schema/catalog can still be specified. 192 if n.Table.ExplicitSchema || ctx.alwaysFormatTablePrefix() { 193 ctx.FormatNode(&n.Table.ObjectNamePrefix) 194 ctx.WriteByte('.') 195 } 196 // In this case, we must format the index name as a restricted name (quotes 197 // must be added for reserved keywords). 198 ctx.FormatNode((*Name)(&n.Index)) 199 } 200 201 func (n *TableIndexName) String() string { return AsString(n) } 202 203 // TableIndexNames is a list of indexes. 204 type TableIndexNames []*TableIndexName 205 206 // Format implements the NodeFormatter interface. 207 func (n *TableIndexNames) Format(ctx *FmtCtx) { 208 sep := "" 209 for _, tni := range *n { 210 ctx.WriteString(sep) 211 ctx.FormatNode(tni) 212 sep = ", " 213 } 214 }