ResolveTarget performs name resolution for an object name when the target object is not expected to exist already. It does not mutate the input name. It additionally returns the resolved prefix qualification for the object. For example, if the unresolved name was "a.b" and the name was resolved to "
( ctx context.Context, u *UnresolvedObjectName, r ObjectNameTargetResolver, curDb string, searchPath sessiondata.SearchPath, )
| 365 | // name was "a.b" and the name was resolved to "a.public.b", the |
| 366 | // prefix "a.public" is returned. |
| 367 | func ResolveTarget( |
| 368 | ctx context.Context, |
| 369 | u *UnresolvedObjectName, |
| 370 | r ObjectNameTargetResolver, |
| 371 | curDb string, |
| 372 | searchPath sessiondata.SearchPath, |
| 373 | ) (found bool, namePrefix ObjectNamePrefix, scMeta SchemaMeta, err error) { |
| 374 | namePrefix = ObjectNamePrefix{ |
| 375 | SchemaName: Name(u.Schema()), |
| 376 | ExplicitSchema: u.HasExplicitSchema(), |
| 377 | CatalogName: Name(u.Catalog()), |
| 378 | ExplicitCatalog: u.HasExplicitCatalog(), |
| 379 | } |
| 380 | if u.HasExplicitSchema() { |
| 381 | // pg_temp can be used as an alias for the current sessions temporary schema. |
| 382 | // We must perform this resolution before looking up the object. This |
| 383 | // resolution only succeeds if the session already has a temporary schema. |
| 384 | scName, err := searchPath.MaybeResolveTemporarySchema(u.Schema()) |
| 385 | if err != nil { |
| 386 | return false, namePrefix, nil, err |
| 387 | } |
| 388 | if u.HasExplicitCatalog() { |
| 389 | // Already 3 parts: nothing to do. |
| 390 | namePrefix.CatalogName = Name(u.Catalog()) |
| 391 | namePrefix.SchemaName = Name(scName) |
| 392 | found, scMeta, err = r.LookupSchema(ctx, u.Catalog(), scName) |
| 393 | return found, namePrefix, scMeta, err |
| 394 | } |
| 395 | // Two parts: D.T. |
| 396 | // Try to use the current database, and be satisfied if it's sufficient to find the object. |
| 397 | if found, scMeta, err = r.LookupSchema(ctx, curDb, scName); found || err != nil { |
| 398 | if err == nil { |
| 399 | namePrefix.CatalogName = Name(curDb) |
| 400 | namePrefix.SchemaName = Name(scName) |
| 401 | } |
| 402 | return found, namePrefix, scMeta, err |
| 403 | } |
| 404 | // No luck so far. Compatibility with CockroachDB v1.1: use D.public.T instead. |
| 405 | if found, scMeta, err = r.LookupSchema(ctx, u.Schema(), PublicSchema); found || err != nil { |
| 406 | if err == nil { |
| 407 | namePrefix.CatalogName = Name(u.Schema()) |
| 408 | namePrefix.SchemaName = PublicSchemaName |
| 409 | namePrefix.ExplicitCatalog = true |
| 410 | } |
| 411 | return found, namePrefix, scMeta, err |
| 412 | } |
| 413 | // Welp, really haven't found anything. |
| 414 | return false, namePrefix, nil, nil |
| 415 | } |
| 416 | |
| 417 | // This is a naked table name. Use the current schema = the first |
| 418 | // valid item in the search path. |
| 419 | iter := searchPath.IterWithoutImplicitPGSchemas() |
| 420 | for scName, ok := iter.Next(); ok; scName, ok = iter.Next() { |
| 421 | if found, scMeta, err = r.LookupSchema(ctx, curDb, scName); found || err != nil { |
| 422 | if err == nil { |
| 423 | namePrefix.CatalogName = Name(curDb) |
| 424 | namePrefix.SchemaName = Name(scName) |
nothing calls this directly
no test coverage detected