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  }