github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/resolver.go (about) 1 // Copyright 2018 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 ( 14 "context" 15 "fmt" 16 17 "github.com/cockroachdb/cockroach/pkg/keys" 18 "github.com/cockroachdb/cockroach/pkg/kv" 19 "github.com/cockroachdb/cockroach/pkg/sql/catalog/resolver" 20 "github.com/cockroachdb/cockroach/pkg/sql/opt/cat" 21 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 22 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 23 "github.com/cockroachdb/cockroach/pkg/sql/privilege" 24 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 25 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 26 "github.com/cockroachdb/cockroach/pkg/sql/types" 27 "github.com/cockroachdb/cockroach/pkg/util/hlc" 28 "github.com/cockroachdb/errors" 29 ) 30 31 var _ resolver.SchemaResolver = &planner{} 32 33 // ResolveUncachedDatabaseByName looks up a database name from the store. 34 func (p *planner) ResolveUncachedDatabaseByName( 35 ctx context.Context, dbName string, required bool, 36 ) (res *UncachedDatabaseDescriptor, err error) { 37 p.runWithOptions(resolveFlags{skipCache: true}, func() { 38 res, err = p.LogicalSchemaAccessor().GetDatabaseDesc( 39 ctx, p.txn, p.ExecCfg().Codec, dbName, p.CommonLookupFlags(required), 40 ) 41 }) 42 return res, err 43 } 44 45 // runWithOptions sets the provided resolution flags for the 46 // duration of the call of the passed argument fn. 47 // 48 // This is meant to be used like this (for example): 49 // 50 // var someVar T 51 // var err error 52 // p.runWithOptions(resolveFlags{skipCache: true}, func() { 53 // someVar, err = ResolveExistingTableObject(ctx, p, ...) 54 // }) 55 // if err != nil { ... } 56 // use(someVar) 57 func (p *planner) runWithOptions(flags resolveFlags, fn func()) { 58 if flags.skipCache { 59 defer func(prev bool) { p.avoidCachedDescriptors = prev }(p.avoidCachedDescriptors) 60 p.avoidCachedDescriptors = true 61 } 62 fn() 63 } 64 65 type resolveFlags struct { 66 skipCache bool 67 } 68 69 func (p *planner) ResolveMutableTableDescriptor( 70 ctx context.Context, tn *TableName, required bool, requiredType resolver.ResolveRequiredType, 71 ) (table *MutableTableDescriptor, err error) { 72 return resolver.ResolveMutableExistingTableObject(ctx, p, tn, required, requiredType) 73 } 74 75 func (p *planner) ResolveUncachedTableDescriptor( 76 ctx context.Context, tn *TableName, required bool, requiredType resolver.ResolveRequiredType, 77 ) (table *ImmutableTableDescriptor, err error) { 78 p.runWithOptions(resolveFlags{skipCache: true}, func() { 79 lookupFlags := tree.ObjectLookupFlags{CommonLookupFlags: tree.CommonLookupFlags{Required: required}} 80 table, err = resolver.ResolveExistingTableObject(ctx, p, tn, lookupFlags, requiredType) 81 }) 82 return table, err 83 } 84 85 func (p *planner) ResolveUncachedDatabase( 86 ctx context.Context, un *tree.UnresolvedObjectName, 87 ) (res *UncachedDatabaseDescriptor, namePrefix tree.ObjectNamePrefix, err error) { 88 p.runWithOptions(resolveFlags{skipCache: true}, func() { 89 res, namePrefix, err = resolver.ResolveTargetObject(ctx, p, un) 90 }) 91 return res, namePrefix, err 92 } 93 94 // LookupSchema implements the tree.ObjectNameTargetResolver interface. 95 func (p *planner) LookupSchema( 96 ctx context.Context, dbName, scName string, 97 ) (found bool, scMeta tree.SchemaMeta, err error) { 98 sc := p.LogicalSchemaAccessor() 99 dbDesc, err := sc.GetDatabaseDesc(ctx, p.txn, p.ExecCfg().Codec, dbName, p.CommonLookupFlags(false /*required*/)) 100 if err != nil || dbDesc == nil { 101 return false, nil, err 102 } 103 found, _, err = sc.IsValidSchema(ctx, p.txn, p.ExecCfg().Codec, dbDesc.ID, scName) 104 if err != nil { 105 return false, nil, err 106 } 107 return found, dbDesc, nil 108 } 109 110 // LookupObject implements the tree.ObjectNameExistingResolver interface. 111 func (p *planner) LookupObject( 112 ctx context.Context, lookupFlags tree.ObjectLookupFlags, dbName, scName, tbName string, 113 ) (found bool, objMeta tree.NameResolutionResult, err error) { 114 sc := p.LogicalSchemaAccessor() 115 lookupFlags.CommonLookupFlags = p.CommonLookupFlags(false /* required */) 116 objDesc, err := sc.GetObjectDesc(ctx, p.txn, p.ExecCfg().Settings, p.ExecCfg().Codec, dbName, scName, tbName, lookupFlags) 117 118 // The returned object may contain types.T that need hydrating. 119 if objDesc != nil { 120 if err := p.maybeHydrateTypesInDescriptor(ctx, objDesc); err != nil { 121 return false, nil, err 122 } 123 } 124 125 return objDesc != nil, objDesc, err 126 } 127 128 // CommonLookupFlags is part of the resolver.SchemaResolver interface. 129 func (p *planner) CommonLookupFlags(required bool) tree.CommonLookupFlags { 130 return tree.CommonLookupFlags{ 131 Required: required, 132 AvoidCached: p.avoidCachedDescriptors, 133 } 134 } 135 136 func (p *planner) makeTypeLookupFn(ctx context.Context) sqlbase.TypeLookupFunc { 137 return func(id sqlbase.ID) (*tree.TypeName, *TypeDescriptor, error) { 138 return resolver.ResolveTypeDescByID(ctx, p.txn, p.ExecCfg().Codec, id) 139 } 140 } 141 142 // ResolveType implements the TypeReferenceResolver interface. 143 func (p *planner) ResolveType( 144 ctx context.Context, name *tree.UnresolvedObjectName, 145 ) (*types.T, error) { 146 lookupFlags := tree.ObjectLookupFlags{ 147 CommonLookupFlags: tree.CommonLookupFlags{Required: true}, 148 DesiredObjectKind: tree.TypeObject, 149 RequireMutable: false, 150 } 151 // TODO (rohany): The ResolveAnyDescType argument doesn't do anything here 152 // if we are looking for a type. This should be cleaned up. 153 desc, prefix, err := resolver.ResolveExistingObject(ctx, p, name, lookupFlags, resolver.ResolveAnyDescType) 154 if err != nil { 155 return nil, err 156 } 157 tn := tree.MakeTypeNameFromPrefix(prefix, tree.Name(name.Object())) 158 tdesc := desc.(*sqlbase.ImmutableTypeDescriptor) 159 return tdesc.MakeTypesT(&tn, p.makeTypeLookupFn(ctx)) 160 } 161 162 // ResolveTypeByID implements the tree.TypeResolver interface. 163 func (p *planner) ResolveTypeByID(ctx context.Context, id uint32) (*types.T, error) { 164 name, desc, err := resolver.ResolveTypeDescByID(ctx, p.txn, p.ExecCfg().Codec, sqlbase.ID(id)) 165 if err != nil { 166 return nil, err 167 } 168 return desc.MakeTypesT(name, p.makeTypeLookupFn(ctx)) 169 } 170 171 // maybeHydrateTypesInDescriptor hydrates any types.T's in the input descriptor. 172 // TODO (rohany): Once we lease types, this should be pushed down into the 173 // leased object collection. 174 func (p *planner) maybeHydrateTypesInDescriptor( 175 ctx context.Context, objDesc tree.NameResolutionResult, 176 ) error { 177 // As of now, only {Mutable,Immutable}TableDescriptor have types.T that 178 // need to be hydrated. 179 switch desc := objDesc.(type) { 180 case *sqlbase.MutableTableDescriptor: 181 if err := sqlbase.HydrateTypesInTableDescriptor(desc.TableDesc(), p.makeTypeLookupFn(ctx)); err != nil { 182 return err 183 } 184 case *sqlbase.ImmutableTableDescriptor: 185 if err := sqlbase.HydrateTypesInTableDescriptor(desc.TableDesc(), p.makeTypeLookupFn(ctx)); err != nil { 186 return err 187 } 188 } 189 return nil 190 } 191 192 // ObjectLookupFlags is part of the resolver.SchemaResolver interface. 193 func (p *planner) ObjectLookupFlags(required, requireMutable bool) tree.ObjectLookupFlags { 194 return tree.ObjectLookupFlags{ 195 CommonLookupFlags: p.CommonLookupFlags(required), 196 RequireMutable: requireMutable, 197 } 198 } 199 200 // getDescriptorsFromTargetList fetches the descriptors for the targets. 201 func getDescriptorsFromTargetList( 202 ctx context.Context, p *planner, targets tree.TargetList, 203 ) ([]sqlbase.DescriptorProto, error) { 204 if targets.Databases != nil { 205 if len(targets.Databases) == 0 { 206 return nil, errNoDatabase 207 } 208 descs := make([]sqlbase.DescriptorProto, 0, len(targets.Databases)) 209 for _, database := range targets.Databases { 210 descriptor, err := p.ResolveUncachedDatabaseByName(ctx, string(database), true /*required*/) 211 if err != nil { 212 return nil, err 213 } 214 descs = append(descs, descriptor) 215 } 216 if len(descs) == 0 { 217 return nil, errNoMatch 218 } 219 return descs, nil 220 } 221 222 if len(targets.Tables) == 0 { 223 return nil, errNoTable 224 } 225 descs := make([]sqlbase.DescriptorProto, 0, len(targets.Tables)) 226 for _, tableTarget := range targets.Tables { 227 tableGlob, err := tableTarget.NormalizeTablePattern() 228 if err != nil { 229 return nil, err 230 } 231 objectNames, err := expandTableGlob(ctx, p, tableGlob) 232 if err != nil { 233 return nil, err 234 } 235 236 for i := range objectNames { 237 // We set required to false here, because there could be type names in 238 // the returned set of names, so we don't want to error out if we 239 // couldn't resolve a name into a table. 240 descriptor, err := resolver.ResolveMutableExistingTableObject(ctx, p, 241 &objectNames[i], false /* required */, resolver.ResolveAnyDescType) 242 if err != nil { 243 return nil, err 244 } 245 if descriptor != nil { 246 descs = append(descs, descriptor) 247 } 248 } 249 } 250 if len(descs) == 0 { 251 return nil, errNoMatch 252 } 253 return descs, nil 254 } 255 256 // getQualifiedTableName returns the database-qualified name of the table 257 // or view represented by the provided descriptor. It is a sort of 258 // reverse of the Resolve() functions. 259 func (p *planner) getQualifiedTableName( 260 ctx context.Context, desc *sqlbase.TableDescriptor, 261 ) (string, error) { 262 dbDesc, err := sqlbase.GetDatabaseDescFromID(ctx, p.txn, p.ExecCfg().Codec, desc.ParentID) 263 if err != nil { 264 return "", err 265 } 266 schemaID := desc.GetParentSchemaID() 267 schemaName, err := resolver.ResolveSchemaNameByID(ctx, p.txn, p.ExecCfg().Codec, desc.ParentID, schemaID) 268 if err != nil { 269 return "", err 270 } 271 tbName := tree.MakeTableNameWithSchema( 272 tree.Name(dbDesc.Name), 273 tree.Name(schemaName), 274 tree.Name(desc.Name), 275 ) 276 return tbName.String(), nil 277 } 278 279 // findTableContainingIndex returns the descriptor of a table 280 // containing the index of the given name. 281 // This is used by expandMutableIndexName(). 282 // 283 // An error is returned if the index name is ambiguous (i.e. exists in 284 // multiple tables). If no table is found and requireTable is true, an 285 // error will be returned, otherwise the TableName and descriptor 286 // returned will be nil. 287 func findTableContainingIndex( 288 ctx context.Context, 289 txn *kv.Txn, 290 sc resolver.SchemaResolver, 291 codec keys.SQLCodec, 292 dbName, scName string, 293 idxName tree.UnrestrictedName, 294 lookupFlags tree.CommonLookupFlags, 295 ) (result *tree.TableName, desc *MutableTableDescriptor, err error) { 296 sa := sc.LogicalSchemaAccessor() 297 dbDesc, err := sa.GetDatabaseDesc(ctx, txn, codec, dbName, lookupFlags) 298 if dbDesc == nil || err != nil { 299 return nil, nil, err 300 } 301 302 tns, err := sa.GetObjectNames(ctx, txn, codec, dbDesc, scName, 303 tree.DatabaseListFlags{CommonLookupFlags: lookupFlags, ExplicitPrefix: true}) 304 if err != nil { 305 return nil, nil, err 306 } 307 308 result = nil 309 for i := range tns { 310 tn := &tns[i] 311 tableDesc, err := resolver.ResolveMutableExistingTableObject(ctx, sc, tn, false /*required*/, resolver.ResolveAnyDescType) 312 if err != nil { 313 return nil, nil, err 314 } 315 if tableDesc == nil || !tableDesc.IsTable() { 316 continue 317 } 318 319 _, dropped, err := tableDesc.FindIndexByName(string(idxName)) 320 if err != nil || dropped { 321 // err is nil if the index does not exist on the table. 322 continue 323 } 324 if result != nil { 325 return nil, nil, pgerror.Newf(pgcode.AmbiguousParameter, 326 "index name %q is ambiguous (found in %s and %s)", 327 idxName, tn.String(), result.String()) 328 } 329 result = tn 330 desc = tableDesc 331 } 332 if result == nil && lookupFlags.Required { 333 return nil, nil, pgerror.Newf(pgcode.UndefinedObject, 334 "index %q does not exist", idxName) 335 } 336 return result, desc, nil 337 } 338 339 // expandMutableIndexName ensures that the index name is qualified with a table 340 // name, and searches the table name if not yet specified. 341 // 342 // It returns the TableName of the underlying table for convenience. 343 // If no table is found and requireTable is true an error will be 344 // returned, otherwise the TableName returned will be nil. 345 // 346 // It *may* return the descriptor of the underlying table, depending 347 // on the lookup path. This can be used in the caller to avoid a 2nd 348 // lookup. 349 func expandMutableIndexName( 350 ctx context.Context, p *planner, index *tree.TableIndexName, requireTable bool, 351 ) (tn *tree.TableName, desc *MutableTableDescriptor, err error) { 352 p.runWithOptions(resolveFlags{skipCache: true}, func() { 353 tn, desc, err = expandIndexName(ctx, p.txn, p, p.ExecCfg().Codec, index, requireTable) 354 }) 355 return tn, desc, err 356 } 357 358 func expandIndexName( 359 ctx context.Context, 360 txn *kv.Txn, 361 sc resolver.SchemaResolver, 362 codec keys.SQLCodec, 363 index *tree.TableIndexName, 364 requireTable bool, 365 ) (tn *tree.TableName, desc *MutableTableDescriptor, err error) { 366 tn = &index.Table 367 if tn.Table() != "" { 368 // The index and its table prefix must exist already. Resolve the table. 369 desc, err = resolver.ResolveMutableExistingTableObject(ctx, sc, tn, requireTable, resolver.ResolveRequireTableDesc) 370 if err != nil { 371 return nil, nil, err 372 } 373 return tn, desc, nil 374 } 375 376 // On the first call to expandMutableIndexName(), index.Table.Table() is empty. 377 // Once the table name is resolved for the index below, index.Table 378 // references the table name. 379 380 // Look up the table prefix. 381 found, _, err := tn.ObjectNamePrefix.Resolve(ctx, sc, sc.CurrentDatabase(), sc.CurrentSearchPath()) 382 if err != nil { 383 return nil, nil, err 384 } 385 if !found { 386 if requireTable { 387 err = pgerror.Newf(pgcode.UndefinedObject, 388 "schema or database was not found while searching index: %q", 389 tree.ErrString(&index.Index)) 390 err = errors.WithHint(err, "check the current database and search_path are valid") 391 return nil, nil, err 392 } 393 return nil, nil, nil 394 } 395 396 lookupFlags := sc.CommonLookupFlags(requireTable) 397 var foundTn *tree.TableName 398 foundTn, desc, err = findTableContainingIndex(ctx, txn, sc, codec, tn.Catalog(), tn.Schema(), index.Index, lookupFlags) 399 if err != nil { 400 return nil, nil, err 401 } 402 403 if foundTn != nil { 404 // Memoize the table name that was found. tn is a reference to the table name 405 // stored in index.Table. 406 *tn = *foundTn 407 } 408 return tn, desc, nil 409 } 410 411 // getTableAndIndex returns the table and index descriptors for a 412 // TableIndexName. 413 // 414 // It can return indexes that are being rolled out. 415 func (p *planner) getTableAndIndex( 416 ctx context.Context, tableWithIndex *tree.TableIndexName, privilege privilege.Kind, 417 ) (*MutableTableDescriptor, *sqlbase.IndexDescriptor, error) { 418 var catalog optCatalog 419 catalog.init(p) 420 catalog.reset() 421 422 idx, _, err := cat.ResolveTableIndex( 423 ctx, &catalog, cat.Flags{AvoidDescriptorCaches: true}, tableWithIndex, 424 ) 425 if err != nil { 426 return nil, nil, err 427 } 428 if err := catalog.CheckPrivilege(ctx, idx.Table(), privilege); err != nil { 429 return nil, nil, err 430 } 431 optIdx := idx.(*optIndex) 432 return sqlbase.NewMutableExistingTableDescriptor(optIdx.tab.desc.TableDescriptor), optIdx.desc, nil 433 } 434 435 // expandTableGlob expands pattern into a list of objects represented 436 // as a tree.TableNames. 437 func expandTableGlob( 438 ctx context.Context, p *planner, pattern tree.TablePattern, 439 ) (tree.TableNames, error) { 440 var catalog optCatalog 441 catalog.init(p) 442 catalog.reset() 443 444 return cat.ExpandDataSourceGlob(ctx, &catalog, cat.Flags{}, pattern) 445 } 446 447 // fkSelfResolver is a SchemaResolver that inserts itself between a 448 // user of name resolution and another SchemaResolver, and will answer 449 // lookups of the new table being created. This is needed in the case 450 // of CREATE TABLE with a foreign key self-reference: the target of 451 // the FK definition is a table that does not exist yet. 452 type fkSelfResolver struct { 453 resolver.SchemaResolver 454 newTableName *tree.TableName 455 newTableDesc *sqlbase.TableDescriptor 456 } 457 458 var _ resolver.SchemaResolver = &fkSelfResolver{} 459 460 // LookupObject implements the tree.ObjectNameExistingResolver interface. 461 func (r *fkSelfResolver) LookupObject( 462 ctx context.Context, lookupFlags tree.ObjectLookupFlags, dbName, scName, tbName string, 463 ) (found bool, objMeta tree.NameResolutionResult, err error) { 464 if dbName == r.newTableName.Catalog() && 465 scName == r.newTableName.Schema() && 466 tbName == r.newTableName.Table() { 467 table := r.newTableDesc 468 if lookupFlags.RequireMutable { 469 return true, sqlbase.NewMutableExistingTableDescriptor(*table), nil 470 } 471 return true, sqlbase.NewImmutableTableDescriptor(*table), nil 472 } 473 lookupFlags.IncludeOffline = false 474 return r.SchemaResolver.LookupObject(ctx, lookupFlags, dbName, scName, tbName) 475 } 476 477 // internalLookupCtx can be used in contexts where all descriptors 478 // have been recently read, to accelerate the lookup of 479 // inter-descriptor relationships. 480 // 481 // This is used mainly in the generators for virtual tables, 482 // aliased as tableLookupFn below. 483 // 484 // It only reveals physical descriptors (not virtual descriptors). 485 type internalLookupCtx struct { 486 dbNames map[sqlbase.ID]string 487 dbIDs []sqlbase.ID 488 dbDescs map[sqlbase.ID]*DatabaseDescriptor 489 tbDescs map[sqlbase.ID]*TableDescriptor 490 tbIDs []sqlbase.ID 491 typDescs map[sqlbase.ID]*TypeDescriptor 492 typIDs []sqlbase.ID 493 } 494 495 // tableLookupFn can be used to retrieve a table descriptor and its corresponding 496 // database descriptor using the table's ID. 497 type tableLookupFn = *internalLookupCtx 498 499 func newInternalLookupCtx( 500 descs []sqlbase.DescriptorProto, prefix *DatabaseDescriptor, 501 ) *internalLookupCtx { 502 wrappedDescs := make([]sqlbase.Descriptor, len(descs)) 503 for i, desc := range descs { 504 wrappedDescs[i] = *sqlbase.WrapDescriptor(desc) 505 } 506 return newInternalLookupCtxFromDescriptors(wrappedDescs, prefix) 507 } 508 509 func newInternalLookupCtxFromDescriptors( 510 descs []sqlbase.Descriptor, prefix *DatabaseDescriptor, 511 ) *internalLookupCtx { 512 dbNames := make(map[sqlbase.ID]string) 513 dbDescs := make(map[sqlbase.ID]*DatabaseDescriptor) 514 tbDescs := make(map[sqlbase.ID]*TableDescriptor) 515 typDescs := make(map[sqlbase.ID]*TypeDescriptor) 516 var tbIDs, typIDs, dbIDs []sqlbase.ID 517 // Record database descriptors for name lookups. 518 for _, desc := range descs { 519 if database := desc.GetDatabase(); database != nil { 520 dbNames[database.ID] = database.Name 521 dbDescs[database.ID] = database 522 if prefix == nil || prefix.ID == database.ID { 523 dbIDs = append(dbIDs, database.ID) 524 } 525 } else if table := desc.Table(hlc.Timestamp{}); table != nil { 526 tbDescs[table.ID] = table 527 if prefix == nil || prefix.ID == table.ParentID { 528 // Only make the table visible for iteration if the prefix was included. 529 tbIDs = append(tbIDs, table.ID) 530 } 531 } else if typ := desc.GetType(); typ != nil { 532 typDescs[typ.ID] = typ 533 if prefix == nil || prefix.ID == typ.ParentID { 534 // Only make the type visible for iteration if the prefix was included. 535 typIDs = append(typIDs, typ.ID) 536 } 537 } 538 } 539 return &internalLookupCtx{ 540 dbNames: dbNames, 541 dbDescs: dbDescs, 542 tbDescs: tbDescs, 543 typDescs: typDescs, 544 tbIDs: tbIDs, 545 dbIDs: dbIDs, 546 typIDs: typIDs, 547 } 548 } 549 550 func (l *internalLookupCtx) getDatabaseByID(id sqlbase.ID) (*DatabaseDescriptor, error) { 551 db, ok := l.dbDescs[id] 552 if !ok { 553 return nil, sqlbase.NewUndefinedDatabaseError(fmt.Sprintf("[%d]", id)) 554 } 555 return db, nil 556 } 557 558 func (l *internalLookupCtx) getTableByID(id sqlbase.ID) (*TableDescriptor, error) { 559 tb, ok := l.tbDescs[id] 560 if !ok { 561 return nil, sqlbase.NewUndefinedRelationError( 562 tree.NewUnqualifiedTableName(tree.Name(fmt.Sprintf("[%d]", id)))) 563 } 564 return tb, nil 565 } 566 567 func (l *internalLookupCtx) getParentName(table *TableDescriptor) string { 568 parentName := l.dbNames[table.GetParentID()] 569 if parentName == "" { 570 // The parent database was deleted. This is possible e.g. when 571 // a database is dropped with CASCADE, and someone queries 572 // this virtual table before the dropped table descriptors are 573 // effectively deleted. 574 parentName = fmt.Sprintf("[%d]", table.GetParentID()) 575 } 576 return parentName 577 } 578 579 // getParentAsTableName returns a TreeTable object of the parent table for a 580 // given table ID. Used to get the parent table of a table with interleaved 581 // indexes. 582 func getParentAsTableName( 583 l simpleSchemaResolver, parentTableID sqlbase.ID, dbPrefix string, 584 ) (tree.TableName, error) { 585 var parentName tree.TableName 586 parentTable, err := l.getTableByID(parentTableID) 587 if err != nil { 588 return tree.TableName{}, err 589 } 590 parentDbDesc, err := l.getDatabaseByID(parentTable.ParentID) 591 if err != nil { 592 return tree.TableName{}, err 593 } 594 parentName = tree.MakeTableName(tree.Name(parentDbDesc.Name), tree.Name(parentTable.Name)) 595 parentName.ExplicitSchema = parentDbDesc.Name != dbPrefix 596 return parentName, nil 597 } 598 599 // getTableAsTableName returns a TableName object for a given TableDescriptor. 600 func getTableAsTableName( 601 l simpleSchemaResolver, table *sqlbase.TableDescriptor, dbPrefix string, 602 ) (tree.TableName, error) { 603 var tableName tree.TableName 604 tableDbDesc, err := l.getDatabaseByID(table.ParentID) 605 if err != nil { 606 return tree.TableName{}, err 607 } 608 tableName = tree.MakeTableName(tree.Name(tableDbDesc.Name), tree.Name(table.Name)) 609 tableName.ExplicitSchema = tableDbDesc.Name != dbPrefix 610 return tableName, nil 611 } 612 613 // The versions below are part of the work for #34240. 614 // TODO(radu): clean these up when everything is switched over. 615 616 // See ResolveMutableTableDescriptor. 617 func (p *planner) ResolveMutableTableDescriptorEx( 618 ctx context.Context, 619 name *tree.UnresolvedObjectName, 620 required bool, 621 requiredType resolver.ResolveRequiredType, 622 ) (*MutableTableDescriptor, error) { 623 tn := name.ToTableName() 624 table, err := resolver.ResolveMutableExistingTableObject(ctx, p, &tn, required, requiredType) 625 if err != nil { 626 return nil, err 627 } 628 name.SetAnnotation(&p.semaCtx.Annotations, &tn) 629 return table, nil 630 } 631 632 // ResolveMutableTableDescriptorExAllowNoPrimaryKey performs the 633 // same logic as ResolveMutableTableDescriptorEx but allows for 634 // the resolved table to not have a primary key. 635 func (p *planner) ResolveMutableTableDescriptorExAllowNoPrimaryKey( 636 ctx context.Context, 637 name *tree.UnresolvedObjectName, 638 required bool, 639 requiredType resolver.ResolveRequiredType, 640 ) (*MutableTableDescriptor, error) { 641 lookupFlags := tree.ObjectLookupFlags{ 642 CommonLookupFlags: tree.CommonLookupFlags{Required: required}, 643 RequireMutable: true, 644 AllowWithoutPrimaryKey: true, 645 } 646 desc, prefix, err := resolver.ResolveExistingObject(ctx, p, name, lookupFlags, requiredType) 647 if err != nil || desc == nil { 648 return nil, err 649 } 650 tn := tree.MakeTableNameFromPrefix(prefix, tree.Name(name.Object())) 651 name.SetAnnotation(&p.semaCtx.Annotations, &tn) 652 return desc.(*MutableTableDescriptor), nil 653 } 654 655 // See ResolveUncachedTableDescriptor. 656 func (p *planner) ResolveUncachedTableDescriptorEx( 657 ctx context.Context, 658 name *tree.UnresolvedObjectName, 659 required bool, 660 requiredType resolver.ResolveRequiredType, 661 ) (table *ImmutableTableDescriptor, err error) { 662 p.runWithOptions(resolveFlags{skipCache: true}, func() { 663 table, err = p.ResolveExistingObjectEx(ctx, name, required, requiredType) 664 }) 665 return table, err 666 } 667 668 // See ResolveExistingTableObject. 669 func (p *planner) ResolveExistingObjectEx( 670 ctx context.Context, 671 name *tree.UnresolvedObjectName, 672 required bool, 673 requiredType resolver.ResolveRequiredType, 674 ) (res *ImmutableTableDescriptor, err error) { 675 lookupFlags := tree.ObjectLookupFlags{CommonLookupFlags: tree.CommonLookupFlags{Required: required}} 676 desc, prefix, err := resolver.ResolveExistingObject(ctx, p, name, lookupFlags, requiredType) 677 if err != nil || desc == nil { 678 return nil, err 679 } 680 tn := tree.MakeTableNameFromPrefix(prefix, tree.Name(name.Object())) 681 name.SetAnnotation(&p.semaCtx.Annotations, &tn) 682 return desc.(*ImmutableTableDescriptor), nil 683 } 684 685 // ResolvedName is a convenience wrapper for UnresolvedObjectName.Resolved. 686 func (p *planner) ResolvedName(u *tree.UnresolvedObjectName) tree.ObjectName { 687 return u.Resolved(&p.semaCtx.Annotations) 688 } 689 690 type simpleSchemaResolver interface { 691 getDatabaseByID(id sqlbase.ID) (*DatabaseDescriptor, error) 692 getTableByID(id sqlbase.ID) (*TableDescriptor, error) 693 }