PostgreSQL Source Code git master
namespace.h File Reference
#include "nodes/primnodes.h"
#include "storage/lock.h"
#include "storage/procnumber.h"
Include dependency graph for namespace.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  _FuncCandidateList
 
struct  SearchPathMatcher
 

Macros

#define RangeVarGetRelid(relation, lockmode, missing_ok)
 

Typedefs

typedef struct _FuncCandidateListFuncCandidateList
 
typedef enum TempNamespaceStatus TempNamespaceStatus
 
typedef struct SearchPathMatcher SearchPathMatcher
 
typedef enum RVROption RVROption
 
typedef void(* RangeVarGetRelidCallback) (const RangeVar *relation, Oid relId, Oid oldRelId, void *callback_arg)
 

Enumerations

enum  TempNamespaceStatus { TEMP_NAMESPACE_NOT_TEMP , TEMP_NAMESPACE_IDLE , TEMP_NAMESPACE_IN_USE }
 
enum  RVROption { RVR_MISSING_OK = 1 << 0 , RVR_NOWAIT = 1 << 1 , RVR_SKIP_LOCKED = 1 << 2 }
 

Functions

Oid RangeVarGetRelidExtended (const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
 
Oid RangeVarGetCreationNamespace (const RangeVar *newRelation)
 
Oid RangeVarGetAndCheckCreationNamespace (RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
 
void RangeVarAdjustRelationPersistence (RangeVar *newRelation, Oid nspid)
 
Oid RelnameGetRelid (const char *relname)
 
bool RelationIsVisible (Oid relid)
 
Oid TypenameGetTypid (const char *typname)
 
Oid TypenameGetTypidExtended (const char *typname, bool temp_ok)
 
bool TypeIsVisible (Oid typid)
 
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok)
 
bool OperatorIsVisible (Oid oprid)
 
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
 
bool OpclassIsVisible (Oid opcid)
 
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
 
bool OpfamilyIsVisible (Oid opfid)
 
Oid CollationGetCollid (const char *collname)
 
bool CollationIsVisible (Oid collid)
 
Oid ConversionGetConid (const char *conname)
 
bool ConversionIsVisible (Oid conid)
 
Oid get_statistics_object_oid (List *names, bool missing_ok)
 
bool StatisticsObjIsVisible (Oid stxid)
 
Oid get_ts_parser_oid (List *names, bool missing_ok)
 
bool TSParserIsVisible (Oid prsId)
 
Oid get_ts_dict_oid (List *names, bool missing_ok)
 
bool TSDictionaryIsVisible (Oid dictId)
 
Oid get_ts_template_oid (List *names, bool missing_ok)
 
bool TSTemplateIsVisible (Oid tmplId)
 
Oid get_ts_config_oid (List *names, bool missing_ok)
 
bool TSConfigIsVisible (Oid cfgid)
 
void DeconstructQualifiedName (const List *names, char **nspname_p, char **objname_p)
 
Oid LookupNamespaceNoError (const char *nspname)
 
Oid LookupExplicitNamespace (const char *nspname, bool missing_ok)
 
Oid get_namespace_oid (const char *nspname, bool missing_ok)
 
Oid LookupCreationNamespace (const char *nspname)
 
void CheckSetNamespace (Oid oldNspOid, Oid nspOid)
 
Oid QualifiedNameGetCreationNamespace (const List *names, char **objname_p)
 
RangeVarmakeRangeVarFromNameList (const List *names)
 
char * NameListToString (const List *names)
 
char * NameListToQuotedString (const List *names)
 
bool isTempNamespace (Oid namespaceId)
 
bool isTempToastNamespace (Oid namespaceId)
 
bool isTempOrTempToastNamespace (Oid namespaceId)
 
bool isAnyTempNamespace (Oid namespaceId)
 
bool isOtherTempNamespace (Oid namespaceId)
 
TempNamespaceStatus checkTempNamespaceStatus (Oid namespaceId)
 
ProcNumber GetTempNamespaceProcNumber (Oid namespaceId)
 
Oid GetTempToastNamespace (void)
 
void GetTempNamespaceState (Oid *tempNamespaceId, Oid *tempToastNamespaceId)
 
void SetTempNamespaceState (Oid tempNamespaceId, Oid tempToastNamespaceId)
 
void ResetTempTableNamespace (void)
 
SearchPathMatcherGetSearchPathMatcher (MemoryContext context)
 
SearchPathMatcherCopySearchPathMatcher (SearchPathMatcher *path)
 
bool SearchPathMatchesCurrentEnvironment (SearchPathMatcher *path)
 
Oid get_collation_oid (List *collname, bool missing_ok)
 
Oid get_conversion_oid (List *conname, bool missing_ok)
 
Oid FindDefaultConversionProc (int32 for_encoding, int32 to_encoding)
 
void InitializeSearchPath (void)
 
void AtEOXact_Namespace (bool isCommit, bool parallel)
 
void AtEOSubXact_Namespace (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
Listfetch_search_path (bool includeImplicit)
 
int fetch_search_path_array (Oid *sarray, int sarray_len)
 

Variables

PGDLLIMPORT char * namespace_search_path
 

Macro Definition Documentation

◆ RangeVarGetRelid

#define RangeVarGetRelid (   relation,
  lockmode,
  missing_ok 
)
Value:
RangeVarGetRelidExtended(relation, lockmode, \
(missing_ok) ? RVR_MISSING_OK : 0, NULL, NULL)
@ RVR_MISSING_OK
Definition: namespace.h:72
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Definition: namespace.c:441

Definition at line 80 of file namespace.h.

Typedef Documentation

◆ FuncCandidateList

◆ RangeVarGetRelidCallback

typedef void(* RangeVarGetRelidCallback) (const RangeVar *relation, Oid relId, Oid oldRelId, void *callback_arg)

Definition at line 77 of file namespace.h.

◆ RVROption

typedef enum RVROption RVROption

◆ SearchPathMatcher

◆ TempNamespaceStatus

Enumeration Type Documentation

◆ RVROption

enum RVROption
Enumerator
RVR_MISSING_OK 
RVR_NOWAIT 
RVR_SKIP_LOCKED 

Definition at line 70 of file namespace.h.

71{
72 RVR_MISSING_OK = 1 << 0, /* don't error if relation doesn't exist */
73 RVR_NOWAIT = 1 << 1, /* error if relation cannot be locked */
74 RVR_SKIP_LOCKED = 1 << 2, /* skip if relation cannot be locked */
75} RVROption;
RVROption
Definition: namespace.h:71
@ RVR_SKIP_LOCKED
Definition: namespace.h:74
@ RVR_NOWAIT
Definition: namespace.h:73

◆ TempNamespaceStatus

Enumerator
TEMP_NAMESPACE_NOT_TEMP 
TEMP_NAMESPACE_IDLE 
TEMP_NAMESPACE_IN_USE 

Definition at line 45 of file namespace.h.

46{
47 TEMP_NAMESPACE_NOT_TEMP, /* nonexistent, or non-temp namespace */
48 TEMP_NAMESPACE_IDLE, /* exists, belongs to no active session */
49 TEMP_NAMESPACE_IN_USE, /* belongs to some active session */
TempNamespaceStatus
Definition: namespace.h:46
@ TEMP_NAMESPACE_IN_USE
Definition: namespace.h:49
@ TEMP_NAMESPACE_NOT_TEMP
Definition: namespace.h:47
@ TEMP_NAMESPACE_IDLE
Definition: namespace.h:48

Function Documentation

◆ AtEOSubXact_Namespace()

void AtEOSubXact_Namespace ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

Definition at line 4558 of file namespace.c.

4560{
4561
4562 if (myTempNamespaceSubID == mySubid)
4563 {
4564 if (isCommit)
4565 myTempNamespaceSubID = parentSubid;
4566 else
4567 {
4569 /* TEMP namespace creation failed, so reset state */
4572 baseSearchPathValid = false; /* need to rebuild list */
4573 searchPathCacheValid = false;
4574
4575 /*
4576 * Reset the temporary namespace flag in MyProc. We assume that
4577 * this operation is atomic.
4578 *
4579 * Because this subtransaction is aborting, the pg_namespace row
4580 * is not visible to anyone else anyway, but that doesn't matter:
4581 * it's not a problem if objects contained in this namespace are
4582 * removed concurrently.
4583 */
4585 }
4586 }
4587}
#define InvalidSubTransactionId
Definition: c.h:615
static bool searchPathCacheValid
Definition: namespace.c:164
static bool baseSearchPathValid
Definition: namespace.c:158
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:205
static Oid myTempToastNamespace
Definition: namespace.c:203
static Oid myTempNamespace
Definition: namespace.c:201
#define InvalidOid
Definition: postgres_ext.h:37
PGPROC * MyProc
Definition: proc.c:66
Oid tempNamespaceId
Definition: proc.h:210

References baseSearchPathValid, InvalidOid, InvalidSubTransactionId, MyProc, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, searchPathCacheValid, and PGPROC::tempNamespaceId.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4512 of file namespace.c.

4513{
4514 /*
4515 * If we abort the transaction in which a temp namespace was selected,
4516 * we'll have to do any creation or cleanout work over again. So, just
4517 * forget the namespace entirely until next time. On the other hand, if
4518 * we commit then register an exit callback to clean out the temp tables
4519 * at backend shutdown. (We only want to register the callback once per
4520 * session, so this is a good place to do it.)
4521 */
4523 {
4524 if (isCommit)
4526 else
4527 {
4530 baseSearchPathValid = false; /* need to rebuild list */
4531 searchPathCacheValid = false;
4532
4533 /*
4534 * Reset the temporary namespace flag in MyProc. We assume that
4535 * this operation is atomic.
4536 *
4537 * Because this transaction is aborting, the pg_namespace row is
4538 * not visible to anyone else anyway, but that doesn't matter:
4539 * it's not a problem if objects contained in this namespace are
4540 * removed concurrently.
4541 */
4543 }
4545 }
4546
4547}
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:337
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4624

References baseSearchPathValid, before_shmem_exit(), InvalidOid, InvalidSubTransactionId, MyProc, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, RemoveTempRelationsCallback(), searchPathCacheValid, and PGPROC::tempNamespaceId.

Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 3459 of file namespace.c.

3460{
3461 /* disallow renaming into or out of temp schemas */
3462 if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
3463 ereport(ERROR,
3464 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3465 errmsg("cannot move objects into or out of temporary schemas")));
3466
3467 /* same for TOAST schema */
3468 if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
3469 ereport(ERROR,
3470 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3471 errmsg("cannot move objects into or out of TOAST schema")));
3472}
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3687

References ereport, errcode(), errmsg(), ERROR, and isAnyTempNamespace().

Referenced by AlterObjectNamespace_internal(), AlterTableNamespace(), and AlterTypeNamespaceInternal().

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3729 of file namespace.c.

3730{
3731 PGPROC *proc;
3732 ProcNumber procNumber;
3733
3735
3736 procNumber = GetTempNamespaceProcNumber(namespaceId);
3737
3738 /* No such namespace, or its name shows it's not temp? */
3739 if (procNumber == INVALID_PROC_NUMBER)
3741
3742 /* Is the backend alive? */
3743 proc = ProcNumberGetProc(procNumber);
3744 if (proc == NULL)
3745 return TEMP_NAMESPACE_IDLE;
3746
3747 /* Is the backend connected to the same database we are looking at? */
3748 if (proc->databaseId != MyDatabaseId)
3749 return TEMP_NAMESPACE_IDLE;
3750
3751 /* Does the backend own the temporary namespace? */
3752 if (proc->tempNamespaceId != namespaceId)
3753 return TEMP_NAMESPACE_IDLE;
3754
3755 /* Yup, so namespace is busy */
3756 return TEMP_NAMESPACE_IN_USE;
3757}
#define Assert(condition)
Definition: c.h:815
#define OidIsValid(objectId)
Definition: c.h:732
Oid MyDatabaseId
Definition: globals.c:93
ProcNumber GetTempNamespaceProcNumber(Oid namespaceId)
Definition: namespace.c:3766
PGPROC * ProcNumberGetProc(ProcNumber procNumber)
Definition: procarray.c:3138
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
int ProcNumber
Definition: procnumber.h:24
Definition: proc.h:162
Oid databaseId
Definition: proc.h:207

References Assert, PGPROC::databaseId, GetTempNamespaceProcNumber(), INVALID_PROC_NUMBER, MyDatabaseId, OidIsValid, ProcNumberGetProc(), TEMP_NAMESPACE_IDLE, TEMP_NAMESPACE_IN_USE, TEMP_NAMESPACE_NOT_TEMP, and PGPROC::tempNamespaceId.

Referenced by do_autovacuum().

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2373 of file namespace.c.

2374{
2375 int32 dbencoding = GetDatabaseEncoding();
2376 ListCell *l;
2377
2379
2380 foreach(l, activeSearchPath)
2381 {
2382 Oid namespaceId = lfirst_oid(l);
2383 Oid collid;
2384
2385 if (namespaceId == myTempNamespace)
2386 continue; /* do not look in temp namespace */
2387
2388 collid = lookup_collation(collname, namespaceId, dbencoding);
2389 if (OidIsValid(collid))
2390 return collid;
2391 }
2392
2393 /* Not found in path */
2394 return InvalidOid;
2395}
int32_t int32
Definition: c.h:484
Oid collid
int GetDatabaseEncoding(void)
Definition: mbutils.c:1261
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:2322
static List * activeSearchPath
Definition: namespace.c:136
static void recomputeNamespacePath(void)
Definition: namespace.c:4299
#define lfirst_oid(lc)
Definition: pg_list.h:174
unsigned int Oid
Definition: postgres_ext.h:32

References activeSearchPath, collid, GetDatabaseEncoding(), InvalidOid, lfirst_oid, lookup_collation(), myTempNamespace, OidIsValid, and recomputeNamespacePath().

Referenced by CollationIsVisibleExt().

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2407 of file namespace.c.

2408{
2409 return CollationIsVisibleExt(collid, NULL);
2410}
static bool CollationIsVisibleExt(Oid collid, bool *is_missing)
Definition: namespace.c:2419

References CollationIsVisibleExt(), and collid.

Referenced by generate_collation_name(), getObjectDescription(), and regcollationout().

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2477 of file namespace.c.

2478{
2479 Oid conid;
2480 ListCell *l;
2481
2483
2484 foreach(l, activeSearchPath)
2485 {
2486 Oid namespaceId = lfirst_oid(l);
2487
2488 if (namespaceId == myTempNamespace)
2489 continue; /* do not look in temp namespace */
2490
2491 conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2492 PointerGetDatum(conname),
2493 ObjectIdGetDatum(namespaceId));
2494 if (OidIsValid(conid))
2495 return conid;
2496 }
2497
2498 /* Not found in path */
2499 return InvalidOid;
2500}
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:111

References activeSearchPath, GetSysCacheOid2, InvalidOid, lfirst_oid, myTempNamespace, ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by ConversionIsVisibleExt().

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2509 of file namespace.c.

2510{
2511 return ConversionIsVisibleExt(conid, NULL);
2512}
static bool ConversionIsVisibleExt(Oid conid, bool *is_missing)
Definition: namespace.c:2521

References ConversionIsVisibleExt().

Referenced by getObjectDescription().

◆ CopySearchPathMatcher()

SearchPathMatcher * CopySearchPathMatcher ( SearchPathMatcher path)

Definition at line 3889 of file namespace.c.

3890{
3891 SearchPathMatcher *result;
3892
3893 result = (SearchPathMatcher *) palloc(sizeof(SearchPathMatcher));
3894 result->schemas = list_copy(path->schemas);
3895 result->addCatalog = path->addCatalog;
3896 result->addTemp = path->addTemp;
3897 result->generation = path->generation;
3898
3899 return result;
3900}
List * list_copy(const List *oldlist)
Definition: list.c:1573
void * palloc(Size size)
Definition: mcxt.c:1317
uint64 generation
Definition: namespace.h:64

References SearchPathMatcher::addCatalog, SearchPathMatcher::addTemp, SearchPathMatcher::generation, list_copy(), palloc(), and SearchPathMatcher::schemas.

Referenced by CopyCachedPlan().

◆ DeconstructQualifiedName()

void DeconstructQualifiedName ( const List names,
char **  nspname_p,
char **  objname_p 
)

Definition at line 3301 of file namespace.c.

3304{
3305 char *catalogname;
3306 char *schemaname = NULL;
3307 char *objname = NULL;
3308
3309 switch (list_length(names))
3310 {
3311 case 1:
3312 objname = strVal(linitial(names));
3313 break;
3314 case 2:
3315 schemaname = strVal(linitial(names));
3316 objname = strVal(lsecond(names));
3317 break;
3318 case 3:
3319 catalogname = strVal(linitial(names));
3320 schemaname = strVal(lsecond(names));
3321 objname = strVal(lthird(names));
3322
3323 /*
3324 * We check the catalog name and then ignore it.
3325 */
3326 if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
3327 ereport(ERROR,
3328 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3329 errmsg("cross-database references are not implemented: %s",
3330 NameListToString(names))));
3331 break;
3332 default:
3333 ereport(ERROR,
3334 (errcode(ERRCODE_SYNTAX_ERROR),
3335 errmsg("improper qualified name (too many dotted names): %s",
3336 NameListToString(names))));
3337 break;
3338 }
3339
3340 *nspname_p = schemaname;
3341 *objname_p = objname;
3342}
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3187
char * NameListToString(const List *names)
Definition: namespace.c:3594
static int list_length(const List *l)
Definition: pg_list.h:152
#define lthird(l)
Definition: pg_list.h:188
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
#define strVal(v)
Definition: value.h:82

References ereport, errcode(), errmsg(), ERROR, get_database_name(), linitial, list_length(), lsecond, lthird, MyDatabaseId, NameListToString(), and strVal.

Referenced by AlterStatistics(), FuncnameGetCandidates(), get_collation_oid(), get_conversion_oid(), get_statistics_object_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), LookupTypeNameExtended(), make_oper_cache_key(), OpClassCacheLookup(), OpernameGetCandidates(), OpernameGetOprid(), OpFamilyCacheLookup(), QualifiedNameGetCreationNamespace(), and ResolveOpClass().

◆ fetch_search_path()

List * fetch_search_path ( bool  includeImplicit)

Definition at line 4819 of file namespace.c.

4820{
4821 List *result;
4822
4824
4825 /*
4826 * If the temp namespace should be first, force it to exist. This is so
4827 * that callers can trust the result to reflect the actual default
4828 * creation namespace. It's a bit bogus to do this here, since
4829 * current_schema() is supposedly a stable function without side-effects,
4830 * but the alternatives seem worse.
4831 */
4833 {
4836 }
4837
4838 result = list_copy(activeSearchPath);
4839 if (!includeImplicit)
4840 {
4841 while (result && linitial_oid(result) != activeCreationNamespace)
4842 result = list_delete_first(result);
4843 }
4844
4845 return result;
4846}
List * list_delete_first(List *list)
Definition: list.c:943
static Oid activeCreationNamespace
Definition: namespace.c:139
static bool activeTempCreationPending
Definition: namespace.c:142
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:4362
#define linitial_oid(l)
Definition: pg_list.h:180
Definition: pg_list.h:54

References AccessTempTableNamespace(), activeCreationNamespace, activeSearchPath, activeTempCreationPending, linitial_oid, list_copy(), list_delete_first(), and recomputeNamespacePath().

Referenced by AfterTriggerSetState(), CreateExtensionInternal(), current_schema(), current_schemas(), and ObjectsInPublicationToOids().

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4859 of file namespace.c.

4860{
4861 int count = 0;
4862 ListCell *l;
4863
4865
4866 foreach(l, activeSearchPath)
4867 {
4868 Oid namespaceId = lfirst_oid(l);
4869
4870 if (namespaceId == myTempNamespace)
4871 continue; /* do not include temp namespace */
4872
4873 if (count < sarray_len)
4874 sarray[count] = namespaceId;
4875 count++;
4876 }
4877
4878 return count;
4879}

References activeSearchPath, lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 4080 of file namespace.c.

4081{
4082 Oid proc;
4083 ListCell *l;
4084
4086
4087 foreach(l, activeSearchPath)
4088 {
4089 Oid namespaceId = lfirst_oid(l);
4090
4091 if (namespaceId == myTempNamespace)
4092 continue; /* do not look in temp namespace */
4093
4094 proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
4095 if (OidIsValid(proc))
4096 return proc;
4097 }
4098
4099 /* Not found in path */
4100 return InvalidOid;
4101}
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)

References activeSearchPath, FindDefaultConversion(), InvalidOid, lfirst_oid, myTempNamespace, OidIsValid, and recomputeNamespacePath().

Referenced by BeginCopyFrom(), InitializeClientEncoding(), pg_do_encoding_conversion(), PrepareClientEncoding(), and test_enc_conversion().

◆ FuncnameGetCandidates()

FuncCandidateList FuncnameGetCandidates ( List names,
int  nargs,
List argnames,
bool  expand_variadic,
bool  expand_defaults,
bool  include_out_arguments,
bool  missing_ok 
)

Definition at line 1192 of file namespace.c.

1195{
1196 FuncCandidateList resultList = NULL;
1197 bool any_special = false;
1198 char *schemaname;
1199 char *funcname;
1200 Oid namespaceId;
1201 CatCList *catlist;
1202 int i;
1203
1204 /* check for caller error */
1205 Assert(nargs >= 0 || !(expand_variadic | expand_defaults));
1206
1207 /* deconstruct the name list */
1208 DeconstructQualifiedName(names, &schemaname, &funcname);
1209
1210 if (schemaname)
1211 {
1212 /* use exact schema given */
1213 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
1214 if (!OidIsValid(namespaceId))
1215 return NULL;
1216 }
1217 else
1218 {
1219 /* flag to indicate we need namespace search */
1220 namespaceId = InvalidOid;
1222 }
1223
1224 /* Search syscache by name only */
1225 catlist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(funcname));
1226
1227 for (i = 0; i < catlist->n_members; i++)
1228 {
1229 HeapTuple proctup = &catlist->members[i]->tuple;
1230 Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
1231 Oid *proargtypes = procform->proargtypes.values;
1232 int pronargs = procform->pronargs;
1233 int effective_nargs;
1234 int pathpos = 0;
1235 bool variadic;
1236 bool use_defaults;
1237 Oid va_elem_type;
1238 int *argnumbers = NULL;
1239 FuncCandidateList newResult;
1240
1241 if (OidIsValid(namespaceId))
1242 {
1243 /* Consider only procs in specified namespace */
1244 if (procform->pronamespace != namespaceId)
1245 continue;
1246 }
1247 else
1248 {
1249 /*
1250 * Consider only procs that are in the search path and are not in
1251 * the temp namespace.
1252 */
1253 ListCell *nsp;
1254
1255 foreach(nsp, activeSearchPath)
1256 {
1257 if (procform->pronamespace == lfirst_oid(nsp) &&
1258 procform->pronamespace != myTempNamespace)
1259 break;
1260 pathpos++;
1261 }
1262 if (nsp == NULL)
1263 continue; /* proc is not in search path */
1264 }
1265
1266 /*
1267 * If we are asked to match to OUT arguments, then use the
1268 * proallargtypes array (which includes those); otherwise use
1269 * proargtypes (which doesn't). Of course, if proallargtypes is null,
1270 * we always use proargtypes.
1271 */
1272 if (include_out_arguments)
1273 {
1274 Datum proallargtypes;
1275 bool isNull;
1276
1277 proallargtypes = SysCacheGetAttr(PROCNAMEARGSNSP, proctup,
1278 Anum_pg_proc_proallargtypes,
1279 &isNull);
1280 if (!isNull)
1281 {
1282 ArrayType *arr = DatumGetArrayTypeP(proallargtypes);
1283
1284 pronargs = ARR_DIMS(arr)[0];
1285 if (ARR_NDIM(arr) != 1 ||
1286 pronargs < 0 ||
1287 ARR_HASNULL(arr) ||
1288 ARR_ELEMTYPE(arr) != OIDOID)
1289 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
1290 Assert(pronargs >= procform->pronargs);
1291 proargtypes = (Oid *) ARR_DATA_PTR(arr);
1292 }
1293 }
1294
1295 if (argnames != NIL)
1296 {
1297 /*
1298 * Call uses named or mixed notation
1299 *
1300 * Named or mixed notation can match a variadic function only if
1301 * expand_variadic is off; otherwise there is no way to match the
1302 * presumed-nameless parameters expanded from the variadic array.
1303 */
1304 if (OidIsValid(procform->provariadic) && expand_variadic)
1305 continue;
1306 va_elem_type = InvalidOid;
1307 variadic = false;
1308
1309 /*
1310 * Check argument count.
1311 */
1312 Assert(nargs >= 0); /* -1 not supported with argnames */
1313
1314 if (pronargs > nargs && expand_defaults)
1315 {
1316 /* Ignore if not enough default expressions */
1317 if (nargs + procform->pronargdefaults < pronargs)
1318 continue;
1319 use_defaults = true;
1320 }
1321 else
1322 use_defaults = false;
1323
1324 /* Ignore if it doesn't match requested argument count */
1325 if (pronargs != nargs && !use_defaults)
1326 continue;
1327
1328 /* Check for argument name match, generate positional mapping */
1329 if (!MatchNamedCall(proctup, nargs, argnames,
1330 include_out_arguments, pronargs,
1331 &argnumbers))
1332 continue;
1333
1334 /* Named argument matching is always "special" */
1335 any_special = true;
1336 }
1337 else
1338 {
1339 /*
1340 * Call uses positional notation
1341 *
1342 * Check if function is variadic, and get variadic element type if
1343 * so. If expand_variadic is false, we should just ignore
1344 * variadic-ness.
1345 */
1346 if (pronargs <= nargs && expand_variadic)
1347 {
1348 va_elem_type = procform->provariadic;
1349 variadic = OidIsValid(va_elem_type);
1350 any_special |= variadic;
1351 }
1352 else
1353 {
1354 va_elem_type = InvalidOid;
1355 variadic = false;
1356 }
1357
1358 /*
1359 * Check if function can match by using parameter defaults.
1360 */
1361 if (pronargs > nargs && expand_defaults)
1362 {
1363 /* Ignore if not enough default expressions */
1364 if (nargs + procform->pronargdefaults < pronargs)
1365 continue;
1366 use_defaults = true;
1367 any_special = true;
1368 }
1369 else
1370 use_defaults = false;
1371
1372 /* Ignore if it doesn't match requested argument count */
1373 if (nargs >= 0 && pronargs != nargs && !variadic && !use_defaults)
1374 continue;
1375 }
1376
1377 /*
1378 * We must compute the effective argument list so that we can easily
1379 * compare it to earlier results. We waste a palloc cycle if it gets
1380 * masked by an earlier result, but really that's a pretty infrequent
1381 * case so it's not worth worrying about.
1382 */
1383 effective_nargs = Max(pronargs, nargs);
1384 newResult = (FuncCandidateList)
1385 palloc(offsetof(struct _FuncCandidateList, args) +
1386 effective_nargs * sizeof(Oid));
1387 newResult->pathpos = pathpos;
1388 newResult->oid = procform->oid;
1389 newResult->nominalnargs = pronargs;
1390 newResult->nargs = effective_nargs;
1391 newResult->argnumbers = argnumbers;
1392 if (argnumbers)
1393 {
1394 /* Re-order the argument types into call's logical order */
1395 for (int j = 0; j < pronargs; j++)
1396 newResult->args[j] = proargtypes[argnumbers[j]];
1397 }
1398 else
1399 {
1400 /* Simple positional case, just copy proargtypes as-is */
1401 memcpy(newResult->args, proargtypes, pronargs * sizeof(Oid));
1402 }
1403 if (variadic)
1404 {
1405 newResult->nvargs = effective_nargs - pronargs + 1;
1406 /* Expand variadic argument into N copies of element type */
1407 for (int j = pronargs - 1; j < effective_nargs; j++)
1408 newResult->args[j] = va_elem_type;
1409 }
1410 else
1411 newResult->nvargs = 0;
1412 newResult->ndargs = use_defaults ? pronargs - nargs : 0;
1413
1414 /*
1415 * Does it have the same arguments as something we already accepted?
1416 * If so, decide what to do to avoid returning duplicate argument
1417 * lists. We can skip this check for the single-namespace case if no
1418 * special (named, variadic or defaults) match has been made, since
1419 * then the unique index on pg_proc guarantees all the matches have
1420 * different argument lists.
1421 */
1422 if (resultList != NULL &&
1423 (any_special || !OidIsValid(namespaceId)))
1424 {
1425 /*
1426 * If we have an ordered list from SearchSysCacheList (the normal
1427 * case), then any conflicting proc must immediately adjoin this
1428 * one in the list, so we only need to look at the newest result
1429 * item. If we have an unordered list, we have to scan the whole
1430 * result list. Also, if either the current candidate or any
1431 * previous candidate is a special match, we can't assume that
1432 * conflicts are adjacent.
1433 *
1434 * We ignore defaulted arguments in deciding what is a match.
1435 */
1436 FuncCandidateList prevResult;
1437
1438 if (catlist->ordered && !any_special)
1439 {
1440 /* ndargs must be 0 if !any_special */
1441 if (effective_nargs == resultList->nargs &&
1442 memcmp(newResult->args,
1443 resultList->args,
1444 effective_nargs * sizeof(Oid)) == 0)
1445 prevResult = resultList;
1446 else
1447 prevResult = NULL;
1448 }
1449 else
1450 {
1451 int cmp_nargs = newResult->nargs - newResult->ndargs;
1452
1453 for (prevResult = resultList;
1454 prevResult;
1455 prevResult = prevResult->next)
1456 {
1457 if (cmp_nargs == prevResult->nargs - prevResult->ndargs &&
1458 memcmp(newResult->args,
1459 prevResult->args,
1460 cmp_nargs * sizeof(Oid)) == 0)
1461 break;
1462 }
1463 }
1464
1465 if (prevResult)
1466 {
1467 /*
1468 * We have a match with a previous result. Decide which one
1469 * to keep, or mark it ambiguous if we can't decide. The
1470 * logic here is preference > 0 means prefer the old result,
1471 * preference < 0 means prefer the new, preference = 0 means
1472 * ambiguous.
1473 */
1474 int preference;
1475
1476 if (pathpos != prevResult->pathpos)
1477 {
1478 /*
1479 * Prefer the one that's earlier in the search path.
1480 */
1481 preference = pathpos - prevResult->pathpos;
1482 }
1483 else if (variadic && prevResult->nvargs == 0)
1484 {
1485 /*
1486 * With variadic functions we could have, for example,
1487 * both foo(numeric) and foo(variadic numeric[]) in the
1488 * same namespace; if so we prefer the non-variadic match
1489 * on efficiency grounds.
1490 */
1491 preference = 1;
1492 }
1493 else if (!variadic && prevResult->nvargs > 0)
1494 {
1495 preference = -1;
1496 }
1497 else
1498 {
1499 /*----------
1500 * We can't decide. This can happen with, for example,
1501 * both foo(numeric, variadic numeric[]) and
1502 * foo(variadic numeric[]) in the same namespace, or
1503 * both foo(int) and foo (int, int default something)
1504 * in the same namespace, or both foo(a int, b text)
1505 * and foo(b text, a int) in the same namespace.
1506 *----------
1507 */
1508 preference = 0;
1509 }
1510
1511 if (preference > 0)
1512 {
1513 /* keep previous result */
1514 pfree(newResult);
1515 continue;
1516 }
1517 else if (preference < 0)
1518 {
1519 /* remove previous result from the list */
1520 if (prevResult == resultList)
1521 resultList = prevResult->next;
1522 else
1523 {
1524 FuncCandidateList prevPrevResult;
1525
1526 for (prevPrevResult = resultList;
1527 prevPrevResult;
1528 prevPrevResult = prevPrevResult->next)
1529 {
1530 if (prevResult == prevPrevResult->next)
1531 {
1532 prevPrevResult->next = prevResult->next;
1533 break;
1534 }
1535 }
1536 Assert(prevPrevResult); /* assert we found it */
1537 }
1538 pfree(prevResult);
1539 /* fall through to add newResult to list */
1540 }
1541 else
1542 {
1543 /* mark old result as ambiguous, discard new */
1544 prevResult->oid = InvalidOid;
1545 pfree(newResult);
1546 continue;
1547 }
1548 }
1549 }
1550
1551 /*
1552 * Okay to add it to result list
1553 */
1554 newResult->next = resultList;
1555 resultList = newResult;
1556 }
1557
1558 ReleaseSysCacheList(catlist);
1559
1560 return resultList;
1561}
#define ARR_NDIM(a)
Definition: array.h:290
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define ARR_DIMS(a)
Definition: array.h:294
#define ARR_HASNULL(a)
Definition: array.h:291
#define Max(x, y)
Definition: c.h:955
#define elog(elevel,...)
Definition: elog.h:225
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
#define funcname
Definition: indent_codes.h:69
int j
Definition: isn.c:73
int i
Definition: isn.c:72
void pfree(void *pointer)
Definition: mcxt.c:1521
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:3385
void DeconstructQualifiedName(const List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:3301
static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, bool include_out_arguments, int pronargs, int **argnumbers)
Definition: namespace.c:1585
struct _FuncCandidateList * FuncCandidateList
#define NIL
Definition: pg_list.h:68
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
int16 pronargs
Definition: pg_proc.h:81
uintptr_t Datum
Definition: postgres.h:69
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:355
struct _FuncCandidateList * next
Definition: namespace.h:31
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:39
bool ordered
Definition: catcache.h:176
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:180
int n_members
Definition: catcache.h:178
HeapTupleData tuple
Definition: catcache.h:123
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:600
#define ReleaseSysCacheList(x)
Definition: syscache.h:134
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:127

References activeSearchPath, _FuncCandidateList::argnumbers, generate_unaccent_rules::args, _FuncCandidateList::args, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, Assert, CStringGetDatum(), DatumGetArrayTypeP, DeconstructQualifiedName(), elog, ERROR, funcname, GETSTRUCT, i, InvalidOid, j, lfirst_oid, LookupExplicitNamespace(), MatchNamedCall(), Max, catclist::members, myTempNamespace, catclist::n_members, _FuncCandidateList::nargs, _FuncCandidateList::ndargs, _FuncCandidateList::next, NIL, _FuncCandidateList::nominalnargs, _FuncCandidateList::nvargs, _FuncCandidateList::oid, OidIsValid, catclist::ordered, palloc(), _FuncCandidateList::pathpos, pfree(), pronargs, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, SysCacheGetAttr(), and catctup::tuple.

Referenced by func_get_detail(), FunctionIsVisibleExt(), LookupFuncNameInternal(), regprocedurein(), regprocin(), and regprocout().

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1696 of file namespace.c.

1697{
1698 return FunctionIsVisibleExt(funcid, NULL);
1699}
static bool FunctionIsVisibleExt(Oid funcid, bool *is_missing)
Definition: namespace.c:1708

References FunctionIsVisibleExt().

Referenced by format_procedure_extended().

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3971 of file namespace.c.

3972{
3973 char *schemaname;
3974 char *collation_name;
3975 int32 dbencoding = GetDatabaseEncoding();
3976 Oid namespaceId;
3977 Oid colloid;
3978 ListCell *l;
3979
3980 /* deconstruct the name list */
3981 DeconstructQualifiedName(collname, &schemaname, &collation_name);
3982
3983 if (schemaname)
3984 {
3985 /* use exact schema given */
3986 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3987 if (missing_ok && !OidIsValid(namespaceId))
3988 return InvalidOid;
3989
3990 colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3991 if (OidIsValid(colloid))
3992 return colloid;
3993 }
3994 else
3995 {
3996 /* search for it in search path */
3998
3999 foreach(l, activeSearchPath)
4000 {
4001 namespaceId = lfirst_oid(l);
4002
4003 if (namespaceId == myTempNamespace)
4004 continue; /* do not look in temp namespace */
4005
4006 colloid = lookup_collation(collation_name, namespaceId, dbencoding);
4007 if (OidIsValid(colloid))
4008 return colloid;
4009 }
4010 }
4011
4012 /* Not found in path */
4013 if (!missing_ok)
4014 ereport(ERROR,
4015 (errcode(ERRCODE_UNDEFINED_OBJECT),
4016 errmsg("collation \"%s\" for encoding \"%s\" does not exist",
4018 return InvalidOid;
4019}
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1267

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetDatabaseEncoding(), GetDatabaseEncodingName(), InvalidOid, lfirst_oid, lookup_collation(), LookupExplicitNamespace(), myTempNamespace, NameListToString(), OidIsValid, and recomputeNamespacePath().

Referenced by AlterCollation(), ComputeIndexAttrs(), ComputePartitionAttrs(), DefineCollation(), DefineDomain(), DefineRange(), get_object_address(), LookupCollation(), and regcollationin().

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 4025 of file namespace.c.

4026{
4027 char *schemaname;
4028 char *conversion_name;
4029 Oid namespaceId;
4030 Oid conoid = InvalidOid;
4031 ListCell *l;
4032
4033 /* deconstruct the name list */
4034 DeconstructQualifiedName(conname, &schemaname, &conversion_name);
4035
4036 if (schemaname)
4037 {
4038 /* use exact schema given */
4039 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
4040 if (missing_ok && !OidIsValid(namespaceId))
4041 conoid = InvalidOid;
4042 else
4043 conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
4044 PointerGetDatum(conversion_name),
4045 ObjectIdGetDatum(namespaceId));
4046 }
4047 else
4048 {
4049 /* search for it in search path */
4051
4052 foreach(l, activeSearchPath)
4053 {
4054 namespaceId = lfirst_oid(l);
4055
4056 if (namespaceId == myTempNamespace)
4057 continue; /* do not look in temp namespace */
4058
4059 conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
4060 PointerGetDatum(conversion_name),
4061 ObjectIdGetDatum(namespaceId));
4062 if (OidIsValid(conoid))
4063 return conoid;
4064 }
4065 }
4066
4067 /* Not found in path */
4068 if (!OidIsValid(conoid) && !missing_ok)
4069 ereport(ERROR,
4070 (errcode(ERRCODE_UNDEFINED_OBJECT),
4071 errmsg("conversion \"%s\" does not exist",
4072 NameListToString(conname))));
4073 return conoid;
4074}

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by get_object_address().

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2575 of file namespace.c.

2576{
2577 char *schemaname;
2578 char *stats_name;
2579 Oid namespaceId;
2580 Oid stats_oid = InvalidOid;
2581 ListCell *l;
2582
2583 /* deconstruct the name list */
2584 DeconstructQualifiedName(names, &schemaname, &stats_name);
2585
2586 if (schemaname)
2587 {
2588 /* use exact schema given */
2589 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2590 if (missing_ok && !OidIsValid(namespaceId))
2591 stats_oid = InvalidOid;
2592 else
2593 stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2594 PointerGetDatum(stats_name),
2595 ObjectIdGetDatum(namespaceId));
2596 }
2597 else
2598 {
2599 /* search for it in search path */
2601
2602 foreach(l, activeSearchPath)
2603 {
2604 namespaceId = lfirst_oid(l);
2605
2606 if (namespaceId == myTempNamespace)
2607 continue; /* do not look in temp namespace */
2608 stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2609 PointerGetDatum(stats_name),
2610 ObjectIdGetDatum(namespaceId));
2611 if (OidIsValid(stats_oid))
2612 break;
2613 }
2614 }
2615
2616 if (!OidIsValid(stats_oid) && !missing_ok)
2617 ereport(ERROR,
2618 (errcode(ERRCODE_UNDEFINED_OBJECT),
2619 errmsg("statistics object \"%s\" does not exist",
2620 NameListToString(names))));
2621
2622 return stats_oid;
2623}

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by AlterStatistics(), and get_object_address().

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 3152 of file namespace.c.

3153{
3154 char *schemaname;
3155 char *config_name;
3156 Oid namespaceId;
3157 Oid cfgoid = InvalidOid;
3158 ListCell *l;
3159
3160 /* deconstruct the name list */
3161 DeconstructQualifiedName(names, &schemaname, &config_name);
3162
3163 if (schemaname)
3164 {
3165 /* use exact schema given */
3166 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3167 if (missing_ok && !OidIsValid(namespaceId))
3168 cfgoid = InvalidOid;
3169 else
3170 cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
3171 PointerGetDatum(config_name),
3172 ObjectIdGetDatum(namespaceId));
3173 }
3174 else
3175 {
3176 /* search for it in search path */
3178
3179 foreach(l, activeSearchPath)
3180 {
3181 namespaceId = lfirst_oid(l);
3182
3183 if (namespaceId == myTempNamespace)
3184 continue; /* do not look in temp namespace */
3185
3186 cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
3187 PointerGetDatum(config_name),
3188 ObjectIdGetDatum(namespaceId));
3189 if (OidIsValid(cfgoid))
3190 break;
3191 }
3192 }
3193
3194 if (!OidIsValid(cfgoid) && !missing_ok)
3195 ereport(ERROR,
3196 (errcode(ERRCODE_UNDEFINED_OBJECT),
3197 errmsg("text search configuration \"%s\" does not exist",
3198 NameListToString(names))));
3199
3200 return cfgoid;
3201}

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by check_default_text_search_config(), DefineTSConfiguration(), get_object_address(), GetTSConfigTuple(), getTSCurrentConfig(), regconfigin(), and tsvector_update_trigger().

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2861 of file namespace.c.

2862{
2863 char *schemaname;
2864 char *dict_name;
2865 Oid namespaceId;
2866 Oid dictoid = InvalidOid;
2867 ListCell *l;
2868
2869 /* deconstruct the name list */
2870 DeconstructQualifiedName(names, &schemaname, &dict_name);
2871
2872 if (schemaname)
2873 {
2874 /* use exact schema given */
2875 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2876 if (missing_ok && !OidIsValid(namespaceId))
2877 dictoid = InvalidOid;
2878 else
2879 dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2880 PointerGetDatum(dict_name),
2881 ObjectIdGetDatum(namespaceId));
2882 }
2883 else
2884 {
2885 /* search for it in search path */
2887
2888 foreach(l, activeSearchPath)
2889 {
2890 namespaceId = lfirst_oid(l);
2891
2892 if (namespaceId == myTempNamespace)
2893 continue; /* do not look in temp namespace */
2894
2895 dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2896 PointerGetDatum(dict_name),
2897 ObjectIdGetDatum(namespaceId));
2898 if (OidIsValid(dictoid))
2899 break;
2900 }
2901 }
2902
2903 if (!OidIsValid(dictoid) && !missing_ok)
2904 ereport(ERROR,
2905 (errcode(ERRCODE_UNDEFINED_OBJECT),
2906 errmsg("text search dictionary \"%s\" does not exist",
2907 NameListToString(names))));
2908
2909 return dictoid;
2910}

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by AlterTSDictionary(), get_object_address(), MakeConfigurationMapping(), regdictionaryin(), and thesaurus_init().

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2716 of file namespace.c.

2717{
2718 char *schemaname;
2719 char *parser_name;
2720 Oid namespaceId;
2721 Oid prsoid = InvalidOid;
2722 ListCell *l;
2723
2724 /* deconstruct the name list */
2725 DeconstructQualifiedName(names, &schemaname, &parser_name);
2726
2727 if (schemaname)
2728 {
2729 /* use exact schema given */
2730 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2731 if (missing_ok && !OidIsValid(namespaceId))
2732 prsoid = InvalidOid;
2733 else
2734 prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2735 PointerGetDatum(parser_name),
2736 ObjectIdGetDatum(namespaceId));
2737 }
2738 else
2739 {
2740 /* search for it in search path */
2742
2743 foreach(l, activeSearchPath)
2744 {
2745 namespaceId = lfirst_oid(l);
2746
2747 if (namespaceId == myTempNamespace)
2748 continue; /* do not look in temp namespace */
2749
2750 prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2751 PointerGetDatum(parser_name),
2752 ObjectIdGetDatum(namespaceId));
2753 if (OidIsValid(prsoid))
2754 break;
2755 }
2756 }
2757
2758 if (!OidIsValid(prsoid) && !missing_ok)
2759 ereport(ERROR,
2760 (errcode(ERRCODE_UNDEFINED_OBJECT),
2761 errmsg("text search parser \"%s\" does not exist",
2762 NameListToString(names))));
2763
2764 return prsoid;
2765}

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by DefineTSConfiguration(), get_object_address(), ts_parse_byname(), and ts_token_type_byname().

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 3007 of file namespace.c.

3008{
3009 char *schemaname;
3010 char *template_name;
3011 Oid namespaceId;
3012 Oid tmploid = InvalidOid;
3013 ListCell *l;
3014
3015 /* deconstruct the name list */
3016 DeconstructQualifiedName(names, &schemaname, &template_name);
3017
3018 if (schemaname)
3019 {
3020 /* use exact schema given */
3021 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3022 if (missing_ok && !OidIsValid(namespaceId))
3023 tmploid = InvalidOid;
3024 else
3025 tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
3026 PointerGetDatum(template_name),
3027 ObjectIdGetDatum(namespaceId));
3028 }
3029 else
3030 {
3031 /* search for it in search path */
3033
3034 foreach(l, activeSearchPath)
3035 {
3036 namespaceId = lfirst_oid(l);
3037
3038 if (namespaceId == myTempNamespace)
3039 continue; /* do not look in temp namespace */
3040
3041 tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
3042 PointerGetDatum(template_name),
3043 ObjectIdGetDatum(namespaceId));
3044 if (OidIsValid(tmploid))
3045 break;
3046 }
3047 }
3048
3049 if (!OidIsValid(tmploid) && !missing_ok)
3050 ereport(ERROR,
3051 (errcode(ERRCODE_UNDEFINED_OBJECT),
3052 errmsg("text search template \"%s\" does not exist",
3053 NameListToString(names))));
3054
3055 return tmploid;
3056}

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by DefineTSDictionary(), and get_object_address().

◆ GetSearchPathMatcher()

SearchPathMatcher * GetSearchPathMatcher ( MemoryContext  context)

Definition at line 3852 of file namespace.c.

3853{
3854 SearchPathMatcher *result;
3855 List *schemas;
3856 MemoryContext oldcxt;
3857
3859
3860 oldcxt = MemoryContextSwitchTo(context);
3861
3862 result = (SearchPathMatcher *) palloc0(sizeof(SearchPathMatcher));
3863 schemas = list_copy(activeSearchPath);
3864 while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3865 {
3866 if (linitial_oid(schemas) == myTempNamespace)
3867 result->addTemp = true;
3868 else
3869 {
3870 Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3871 result->addCatalog = true;
3872 }
3873 schemas = list_delete_first(schemas);
3874 }
3875 result->schemas = schemas;
3877
3878 MemoryContextSwitchTo(oldcxt);
3879
3880 return result;
3881}
void * palloc0(Size size)
Definition: mcxt.c:1347
static uint64 activePathGeneration
Definition: namespace.c:145
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124

References activeCreationNamespace, activePathGeneration, activeSearchPath, SearchPathMatcher::addCatalog, SearchPathMatcher::addTemp, Assert, SearchPathMatcher::generation, linitial_oid, list_copy(), list_delete_first(), MemoryContextSwitchTo(), myTempNamespace, palloc0(), recomputeNamespacePath(), and SearchPathMatcher::schemas.

Referenced by CompleteCachedPlan(), and RevalidateCachedQuery().

◆ GetTempNamespaceProcNumber()

ProcNumber GetTempNamespaceProcNumber ( Oid  namespaceId)

Definition at line 3766 of file namespace.c.

3767{
3768 int result;
3769 char *nspname;
3770
3771 /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3772 nspname = get_namespace_name(namespaceId);
3773 if (!nspname)
3774 return INVALID_PROC_NUMBER; /* no such namespace? */
3775 if (strncmp(nspname, "pg_temp_", 8) == 0)
3776 result = atoi(nspname + 8);
3777 else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3778 result = atoi(nspname + 14);
3779 else
3780 result = INVALID_PROC_NUMBER;
3781 pfree(nspname);
3782 return result;
3783}
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3366

References get_namespace_name(), INVALID_PROC_NUMBER, and pfree().

Referenced by checkTempNamespaceStatus(), pg_relation_filepath(), and RelationBuildDesc().

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3805 of file namespace.c.

3806{
3807 /* Return namespace OIDs, or 0 if session has not created temp namespace */
3808 *tempNamespaceId = myTempNamespace;
3809 *tempToastNamespaceId = myTempToastNamespace;
3810}

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3791 of file namespace.c.

3792{
3794 return myTempToastNamespace;
3795}

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4736 of file namespace.c.

4737{
4739 {
4740 /*
4741 * In bootstrap mode, the search path must be 'pg_catalog' so that
4742 * tables are created in the proper namespace; ignore the GUC setting.
4743 */
4744 MemoryContext oldcxt;
4745
4747 baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4748 MemoryContextSwitchTo(oldcxt);
4749 baseCreationNamespace = PG_CATALOG_NAMESPACE;
4751 baseSearchPathValid = true;
4756 activePathGeneration++; /* pro forma */
4757 }
4758 else
4759 {
4760 /*
4761 * In normal mode, arrange for a callback on any syscache invalidation
4762 * that will affect the search_path cache.
4763 */
4764
4765 /* namespace name or ACLs may have changed */
4766 CacheRegisterSyscacheCallback(NAMESPACEOID,
4768 (Datum) 0);
4769
4770 /* role name may affect the meaning of "$user" */
4773 (Datum) 0);
4774
4775 /* role membership may affect ACLs */
4776 CacheRegisterSyscacheCallback(AUTHMEMROLEMEM,
4778 (Datum) 0);
4779
4780 /* database owner may affect ACLs */
4783 (Datum) 0);
4784
4785 /* Force search path to be recomputed on next use */
4786 baseSearchPathValid = false;
4787 searchPathCacheValid = false;
4788 }
4789}
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1704
MemoryContext TopMemoryContext
Definition: mcxt.c:149
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:466
Oid GetUserId(void)
Definition: miscinit.c:517
static bool baseTempCreationPending
Definition: namespace.c:153
static Oid baseCreationNamespace
Definition: namespace.c:151
static Oid namespaceUser
Definition: namespace.c:155
static void InvalidationCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4796
static List * baseSearchPath
Definition: namespace.c:149
#define list_make1_oid(x1)
Definition: pg_list.h:242

References activeCreationNamespace, activePathGeneration, activeSearchPath, activeTempCreationPending, baseCreationNamespace, baseSearchPath, baseSearchPathValid, baseTempCreationPending, CacheRegisterSyscacheCallback(), GetUserId(), InvalidationCallback(), IsBootstrapProcessingMode, list_make1_oid, MemoryContextSwitchTo(), namespaceUser, searchPathCacheValid, and TopMemoryContext.

Referenced by InitPostgres().

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3687 of file namespace.c.

3688{
3689 bool result;
3690 char *nspname;
3691
3692 /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3693 nspname = get_namespace_name(namespaceId);
3694 if (!nspname)
3695 return false; /* no such namespace? */
3696 result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3697 (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3698 pfree(nspname);
3699 return result;
3700}

References get_namespace_name(), and pfree().

Referenced by AlterTableMoveAll(), check_publication_add_schema(), CheckSetNamespace(), EventTriggerSQLDropAddObject(), isOtherTempNamespace(), and RangeVarAdjustRelationPersistence().

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3710 of file namespace.c.

3711{
3712 /* If it's my own temp namespace, say "false" */
3713 if (isTempOrTempToastNamespace(namespaceId))
3714 return false;
3715 /* Else, if it's any temp namespace, say "true" */
3716 return isAnyTempNamespace(namespaceId);
3717}
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3673

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3673 of file namespace.c.

3674{
3676 (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3677 return true;
3678 return false;
3679}

References myTempNamespace, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table(), isOtherTempNamespace(), pg_relation_filepath(), RangeVarAdjustRelationPersistence(), RelationBuildDesc(), and RelationBuildLocalRelation().

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3661 of file namespace.c.

3662{
3664 return true;
3665 return false;
3666}

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 3428 of file namespace.c.

3429{
3430 Oid namespaceId;
3431 AclResult aclresult;
3432
3433 /* check for pg_temp alias */
3434 if (strcmp(nspname, "pg_temp") == 0)
3435 {
3436 /* Initialize temp namespace */
3438 return myTempNamespace;
3439 }
3440
3441 namespaceId = get_namespace_oid(nspname, false);
3442
3443 aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
3444 if (aclresult != ACLCHECK_OK)
3445 aclcheck_error(aclresult, OBJECT_SCHEMA,
3446 nspname);
3447
3448 return namespaceId;
3449}
AclResult
Definition: acl.h:182
@ ACLCHECK_OK
Definition: acl.h:183
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2622
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3804
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3535
@ OBJECT_SCHEMA
Definition: parsenodes.h:2348
#define ACL_CREATE
Definition: parsenodes.h:85

References AccessTempTableNamespace(), ACL_CREATE, aclcheck_error(), ACLCHECK_OK, get_namespace_oid(), GetUserId(), myTempNamespace, object_aclcheck(), and OBJECT_SCHEMA.

Referenced by AlterExtensionNamespace(), AlterTypeNamespace(), ExecAlterObjectSchemaStmt(), ImportForeignSchema(), and make_new_heap().

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 3385 of file namespace.c.

3386{
3387 Oid namespaceId;
3388 AclResult aclresult;
3389
3390 /* check for pg_temp alias */
3391 if (strcmp(nspname, "pg_temp") == 0)
3392 {
3394 return myTempNamespace;
3395
3396 /*
3397 * Since this is used only for looking up existing objects, there is
3398 * no point in trying to initialize the temp namespace here; and doing
3399 * so might create problems for some callers --- just fall through.
3400 */
3401 }
3402
3403 namespaceId = get_namespace_oid(nspname, missing_ok);
3404 if (missing_ok && !OidIsValid(namespaceId))
3405 return InvalidOid;
3406
3407 aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_USAGE);
3408 if (aclresult != ACLCHECK_OK)
3409 aclcheck_error(aclresult, OBJECT_SCHEMA,
3410 nspname);
3411 /* Schema search hook for this lookup */
3412 InvokeNamespaceSearchHook(namespaceId, true);
3413
3414 return namespaceId;
3415}
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:208
#define ACL_USAGE
Definition: parsenodes.h:84

References ACL_USAGE, aclcheck_error(), ACLCHECK_OK, get_namespace_oid(), GetUserId(), InvalidOid, InvokeNamespaceSearchHook, myTempNamespace, object_aclcheck(), OBJECT_SCHEMA, and OidIsValid.

Referenced by AfterTriggerSetState(), FuncnameGetCandidates(), get_collation_oid(), get_conversion_oid(), get_statistics_object_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), LookupTypeNameExtended(), make_oper_cache_key(), objectsInSchemaToOids(), OpClassCacheLookup(), OpernameGetCandidates(), OpernameGetOprid(), OpFamilyCacheLookup(), RangeVarGetRelidExtended(), ResolveOpClass(), schema_to_xml(), schema_to_xml_and_xmlschema(), and schema_to_xmlschema_internal().

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 3355 of file namespace.c.

3356{
3357 /* check for pg_temp alias */
3358 if (strcmp(nspname, "pg_temp") == 0)
3359 {
3361 {
3363 return myTempNamespace;
3364 }
3365
3366 /*
3367 * Since this is used only for looking up existing objects, there is
3368 * no point in trying to initialize the temp namespace here; and doing
3369 * so might create problems for some callers. Just report "not found".
3370 */
3371 return InvalidOid;
3372 }
3373
3374 return get_namespace_oid(nspname, true);
3375}

References get_namespace_oid(), InvalidOid, InvokeNamespaceSearchHook, myTempNamespace, and OidIsValid.

Referenced by DropErrorMsgNonExistent(), refnameNamespaceItem(), and schema_does_not_exist_skipping().

◆ makeRangeVarFromNameList()

RangeVar * makeRangeVarFromNameList ( const List names)

Definition at line 3554 of file namespace.c.

3555{
3556 RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3557
3558 switch (list_length(names))
3559 {
3560 case 1:
3561 rel->relname = strVal(linitial(names));
3562 break;
3563 case 2:
3564 rel->schemaname = strVal(linitial(names));
3565 rel->relname = strVal(lsecond(names));
3566 break;
3567 case 3:
3568 rel->catalogname = strVal(linitial(names));
3569 rel->schemaname = strVal(lsecond(names));
3570 rel->relname = strVal(lthird(names));
3571 break;
3572 default:
3573 ereport(ERROR,
3574 (errcode(ERRCODE_SYNTAX_ERROR),
3575 errmsg("improper relation name (too many dotted names): %s",
3576 NameListToString(names))));
3577 break;
3578 }
3579
3580 return rel;
3581}
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:426
char * relname
Definition: primnodes.h:82
char * catalogname
Definition: primnodes.h:76
char * schemaname
Definition: primnodes.h:79

References RangeVar::catalogname, ereport, errcode(), errmsg(), ERROR, linitial, list_length(), lsecond, lthird, makeRangeVar(), NameListToString(), RangeVar::relname, RangeVar::schemaname, and strVal.

Referenced by bt_metap(), bt_multi_page_stats(), bt_page_items_internal(), bt_page_stats_internal(), convert_table_name(), currtid_byrelname(), generateSerialExtraStmts(), get_object_address_attrdef(), get_object_address_attribute(), get_object_address_publication_rel(), get_object_address_relobject(), get_raw_page_internal(), get_rel_from_relname(), get_relation_by_qualified_name(), nextval(), owningrel_does_not_exist_skipping(), pg_get_serial_sequence(), pg_get_viewdef_name(), pg_get_viewdef_name_ext(), pg_relpages(), pg_relpages_v1_5(), pgrowlocks(), pgstatindex(), pgstatindex_v1_5(), pgstattuple(), pgstattuple_v1_5(), plpgsql_parse_cwordrowtype(), plpgsql_parse_cwordtype(), process_owned_by(), regclassin(), RelationNameGetTupleDesc(), RemoveRelations(), row_security_active_name(), schema_does_not_exist_skipping(), and text_regclass().

◆ NameListToQuotedString()

char * NameListToQuotedString ( const List names)

Definition at line 3628 of file namespace.c.

3629{
3631 ListCell *l;
3632
3633 initStringInfo(&string);
3634
3635 foreach(l, names)
3636 {
3637 if (l != list_head(names))
3638 appendStringInfoChar(&string, '.');
3640 }
3641
3642 return string.data;
3643}
#define lfirst(lc)
Definition: pg_list.h:172
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
char string[11]
Definition: preproc-type.c:52
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:12940
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97

References appendStringInfoChar(), appendStringInfoString(), initStringInfo(), lfirst, list_head(), quote_identifier(), and strVal.

◆ NameListToString()

char * NameListToString ( const List names)

Definition at line 3594 of file namespace.c.

3595{
3597 ListCell *l;
3598
3599 initStringInfo(&string);
3600
3601 foreach(l, names)
3602 {
3603 Node *name = (Node *) lfirst(l);
3604
3605 if (l != list_head(names))
3606 appendStringInfoChar(&string, '.');
3607
3608 if (IsA(name, String))
3610 else if (IsA(name, A_Star))
3611 appendStringInfoChar(&string, '*');
3612 else
3613 elog(ERROR, "unexpected node type in name list: %d",
3614 (int) nodeTag(name));
3615 }
3616
3617 return string.data;
3618}
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define nodeTag(nodeptr)
Definition: nodes.h:133
Definition: nodes.h:129
Definition: value.h:64
const char * name

References appendStringInfoChar(), appendStringInfoString(), elog, ERROR, initStringInfo(), IsA, lfirst, list_head(), name, nodeTag, and strVal.

Referenced by AggregateCreate(), AlterCollation(), AlterFunction(), AlterStatistics(), AlterTSConfiguration(), AlterTSDictionary(), check_object_ownership(), CreateConversionCommand(), CreateEventTrigger(), CreateProceduralLanguage(), CreateTransform(), CreateTriggerFiringOn(), DeconstructQualifiedName(), defGetString(), DefineOperator(), DefineType(), does_not_exist_skipping(), dropOperators(), dropProcedures(), ExpandColumnRefStar(), findRangeSubOpclass(), findTypeAnalyzeFunction(), findTypeInputFunction(), findTypeOutputFunction(), findTypeReceiveFunction(), findTypeSendFunction(), findTypeSubscriptingFunction(), findTypeTypmodinFunction(), findTypeTypmodoutFunction(), func_signature_string(), get_collation_oid(), get_conversion_oid(), get_object_address_attrdef(), get_object_address_attribute(), get_statistics_object_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), interpret_func_support(), lookup_fdw_handler_func(), LookupFuncName(), LookupFuncWithArgs(), LookupTypeNameExtended(), makeRangeVarFromNameList(), op_signature_string(), OpClassCacheLookup(), OperatorCreate(), OpFamilyCacheLookup(), owningrel_does_not_exist_skipping(), ParseFuncOrColumn(), plpgsql_post_column_ref(), regclassin(), regcollationin(), regconfigin(), regdictionaryin(), RemoveObjects(), ResolveOpClass(), storeOperators(), storeProcedures(), transformColumnRef(), transformRangeTableSample(), ValidateJoinEstimator(), ValidateOperatorReference(), and ValidateRestrictionEstimator().

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 2154 of file namespace.c.

2155{
2156 return OpclassIsVisibleExt(opcid, NULL);
2157}
static bool OpclassIsVisibleExt(Oid opcid, bool *is_missing)
Definition: namespace.c:2166

References OpclassIsVisibleExt().

Referenced by get_opclass_name(), and getObjectDescription().

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 2121 of file namespace.c.

2122{
2123 Oid opcid;
2124 ListCell *l;
2125
2127
2128 foreach(l, activeSearchPath)
2129 {
2130 Oid namespaceId = lfirst_oid(l);
2131
2132 if (namespaceId == myTempNamespace)
2133 continue; /* do not look in temp namespace */
2134
2135 opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
2136 ObjectIdGetDatum(amid),
2137 PointerGetDatum(opcname),
2138 ObjectIdGetDatum(namespaceId));
2139 if (OidIsValid(opcid))
2140 return opcid;
2141 }
2142
2143 /* Not found in path */
2144 return InvalidOid;
2145}
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:113

References activeSearchPath, GetSysCacheOid3, InvalidOid, lfirst_oid, myTempNamespace, ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by OpClassCacheLookup(), OpclassIsVisibleExt(), and ResolveOpClass().

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 2049 of file namespace.c.

2050{
2051 return OperatorIsVisibleExt(oprid, NULL);
2052}
static bool OperatorIsVisibleExt(Oid oprid, bool *is_missing)
Definition: namespace.c:2061
Oid oprid(Operator op)
Definition: parse_oper.c:238

References OperatorIsVisibleExt(), and oprid().

Referenced by format_operator_extended().

◆ OpernameGetCandidates()

FuncCandidateList OpernameGetCandidates ( List names,
char  oprkind,
bool  missing_schema_ok 
)

Definition at line 1888 of file namespace.c.

1889{
1890 FuncCandidateList resultList = NULL;
1891 char *resultSpace = NULL;
1892 int nextResult = 0;
1893 char *schemaname;
1894 char *opername;
1895 Oid namespaceId;
1896 CatCList *catlist;
1897 int i;
1898
1899 /* deconstruct the name list */
1900 DeconstructQualifiedName(names, &schemaname, &opername);
1901
1902 if (schemaname)
1903 {
1904 /* use exact schema given */
1905 namespaceId = LookupExplicitNamespace(schemaname, missing_schema_ok);
1906 if (missing_schema_ok && !OidIsValid(namespaceId))
1907 return NULL;
1908 }
1909 else
1910 {
1911 /* flag to indicate we need namespace search */
1912 namespaceId = InvalidOid;
1914 }
1915
1916 /* Search syscache by name only */
1917 catlist = SearchSysCacheList1(OPERNAMENSP, CStringGetDatum(opername));
1918
1919 /*
1920 * In typical scenarios, most if not all of the operators found by the
1921 * catcache search will end up getting returned; and there can be quite a
1922 * few, for common operator names such as '=' or '+'. To reduce the time
1923 * spent in palloc, we allocate the result space as an array large enough
1924 * to hold all the operators. The original coding of this routine did a
1925 * separate palloc for each operator, but profiling revealed that the
1926 * pallocs used an unreasonably large fraction of parsing time.
1927 */
1928#define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
1929 2 * sizeof(Oid))
1930
1931 if (catlist->n_members > 0)
1932 resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
1933
1934 for (i = 0; i < catlist->n_members; i++)
1935 {
1936 HeapTuple opertup = &catlist->members[i]->tuple;
1937 Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1938 int pathpos = 0;
1939 FuncCandidateList newResult;
1940
1941 /* Ignore operators of wrong kind, if specific kind requested */
1942 if (oprkind && operform->oprkind != oprkind)
1943 continue;
1944
1945 if (OidIsValid(namespaceId))
1946 {
1947 /* Consider only opers in specified namespace */
1948 if (operform->oprnamespace != namespaceId)
1949 continue;
1950 /* No need to check args, they must all be different */
1951 }
1952 else
1953 {
1954 /*
1955 * Consider only opers that are in the search path and are not in
1956 * the temp namespace.
1957 */
1958 ListCell *nsp;
1959
1960 foreach(nsp, activeSearchPath)
1961 {
1962 if (operform->oprnamespace == lfirst_oid(nsp) &&
1963 operform->oprnamespace != myTempNamespace)
1964 break;
1965 pathpos++;
1966 }
1967 if (nsp == NULL)
1968 continue; /* oper is not in search path */
1969
1970 /*
1971 * Okay, it's in the search path, but does it have the same
1972 * arguments as something we already accepted? If so, keep only
1973 * the one that appears earlier in the search path.
1974 *
1975 * If we have an ordered list from SearchSysCacheList (the normal
1976 * case), then any conflicting oper must immediately adjoin this
1977 * one in the list, so we only need to look at the newest result
1978 * item. If we have an unordered list, we have to scan the whole
1979 * result list.
1980 */
1981 if (resultList)
1982 {
1983 FuncCandidateList prevResult;
1984
1985 if (catlist->ordered)
1986 {
1987 if (operform->oprleft == resultList->args[0] &&
1988 operform->oprright == resultList->args[1])
1989 prevResult = resultList;
1990 else
1991 prevResult = NULL;
1992 }
1993 else
1994 {
1995 for (prevResult = resultList;
1996 prevResult;
1997 prevResult = prevResult->next)
1998 {
1999 if (operform->oprleft == prevResult->args[0] &&
2000 operform->oprright == prevResult->args[1])
2001 break;
2002 }
2003 }
2004 if (prevResult)
2005 {
2006 /* We have a match with a previous result */
2007 Assert(pathpos != prevResult->pathpos);
2008 if (pathpos > prevResult->pathpos)
2009 continue; /* keep previous result */
2010 /* replace previous result */
2011 prevResult->pathpos = pathpos;
2012 prevResult->oid = operform->oid;
2013 continue; /* args are same, of course */
2014 }
2015 }
2016 }
2017
2018 /*
2019 * Okay to add it to result list
2020 */
2021 newResult = (FuncCandidateList) (resultSpace + nextResult);
2022 nextResult += SPACE_PER_OP;
2023
2024 newResult->pathpos = pathpos;
2025 newResult->oid = operform->oid;
2026 newResult->nominalnargs = 2;
2027 newResult->nargs = 2;
2028 newResult->nvargs = 0;
2029 newResult->ndargs = 0;
2030 newResult->argnumbers = NULL;
2031 newResult->args[0] = operform->oprleft;
2032 newResult->args[1] = operform->oprright;
2033 newResult->next = resultList;
2034 resultList = newResult;
2035 }
2036
2037 ReleaseSysCacheList(catlist);
2038
2039 return resultList;
2040}
#define SPACE_PER_OP
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83

References activeSearchPath, _FuncCandidateList::argnumbers, _FuncCandidateList::args, Assert, CStringGetDatum(), DeconstructQualifiedName(), GETSTRUCT, i, InvalidOid, lfirst_oid, LookupExplicitNamespace(), catclist::members, myTempNamespace, catclist::n_members, _FuncCandidateList::nargs, _FuncCandidateList::ndargs, _FuncCandidateList::next, _FuncCandidateList::nominalnargs, _FuncCandidateList::nvargs, _FuncCandidateList::oid, OidIsValid, catclist::ordered, palloc(), _FuncCandidateList::pathpos, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, SPACE_PER_OP, and catctup::tuple.

Referenced by left_oper(), oper(), regoperin(), and regoperout().

◆ OpernameGetOprid()

Oid OpernameGetOprid ( List names,
Oid  oprleft,
Oid  oprright 
)

Definition at line 1785 of file namespace.c.

1786{
1787 char *schemaname;
1788 char *opername;
1789 CatCList *catlist;
1790 ListCell *l;
1791
1792 /* deconstruct the name list */
1793 DeconstructQualifiedName(names, &schemaname, &opername);
1794
1795 if (schemaname)
1796 {
1797 /* search only in exact schema given */
1798 Oid namespaceId;
1799
1800 namespaceId = LookupExplicitNamespace(schemaname, true);
1801 if (OidIsValid(namespaceId))
1802 {
1803 HeapTuple opertup;
1804
1805 opertup = SearchSysCache4(OPERNAMENSP,
1806 CStringGetDatum(opername),
1807 ObjectIdGetDatum(oprleft),
1808 ObjectIdGetDatum(oprright),
1809 ObjectIdGetDatum(namespaceId));
1810 if (HeapTupleIsValid(opertup))
1811 {
1812 Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup);
1813 Oid result = operclass->oid;
1814
1815 ReleaseSysCache(opertup);
1816 return result;
1817 }
1818 }
1819
1820 return InvalidOid;
1821 }
1822
1823 /* Search syscache by name and argument types */
1824 catlist = SearchSysCacheList3(OPERNAMENSP,
1825 CStringGetDatum(opername),
1826 ObjectIdGetDatum(oprleft),
1827 ObjectIdGetDatum(oprright));
1828
1829 if (catlist->n_members == 0)
1830 {
1831 /* no hope, fall out early */
1832 ReleaseSysCacheList(catlist);
1833 return InvalidOid;
1834 }
1835
1836 /*
1837 * We have to find the list member that is first in the search path, if
1838 * there's more than one. This doubly-nested loop looks ugly, but in
1839 * practice there should usually be few catlist members.
1840 */
1842
1843 foreach(l, activeSearchPath)
1844 {
1845 Oid namespaceId = lfirst_oid(l);
1846 int i;
1847
1848 if (namespaceId == myTempNamespace)
1849 continue; /* do not look in temp namespace */
1850
1851 for (i = 0; i < catlist->n_members; i++)
1852 {
1853 HeapTuple opertup = &catlist->members[i]->tuple;
1854 Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1855
1856 if (operform->oprnamespace == namespaceId)
1857 {
1858 Oid result = operform->oid;
1859
1860 ReleaseSysCacheList(catlist);
1861 return result;
1862 }
1863 }
1864 }
1865
1866 ReleaseSysCacheList(catlist);
1867 return InvalidOid;
1868}
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:254
#define SearchSysCacheList3(cacheId, key1, key2, key3)
Definition: syscache.h:131

References activeSearchPath, CStringGetDatum(), DeconstructQualifiedName(), GETSTRUCT, HeapTupleIsValid, i, InvalidOid, lfirst_oid, LookupExplicitNamespace(), catclist::members, myTempNamespace, catclist::n_members, ObjectIdGetDatum(), OidIsValid, recomputeNamespacePath(), ReleaseSysCache(), ReleaseSysCacheList, SearchSysCache4(), SearchSysCacheList3, and catctup::tuple.

Referenced by binary_oper_exact(), left_oper(), LookupOperName(), OperatorIsVisibleExt(), and regoperatorin().

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 2256 of file namespace.c.

2257{
2258 return OpfamilyIsVisibleExt(opfid, NULL);
2259}
static bool OpfamilyIsVisibleExt(Oid opfid, bool *is_missing)
Definition: namespace.c:2268

References OpfamilyIsVisibleExt().

Referenced by getOpFamilyDescription().

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 2223 of file namespace.c.

2224{
2225 Oid opfid;
2226 ListCell *l;
2227
2229
2230 foreach(l, activeSearchPath)
2231 {
2232 Oid namespaceId = lfirst_oid(l);
2233
2234 if (namespaceId == myTempNamespace)
2235 continue; /* do not look in temp namespace */
2236
2237 opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
2238 ObjectIdGetDatum(amid),
2239 PointerGetDatum(opfname),
2240 ObjectIdGetDatum(namespaceId));
2241 if (OidIsValid(opfid))
2242 return opfid;
2243 }
2244
2245 /* Not found in path */
2246 return InvalidOid;
2247}

References activeSearchPath, GetSysCacheOid3, InvalidOid, lfirst_oid, myTempNamespace, ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisibleExt().

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( const List names,
char **  objname_p 
)

Definition at line 3487 of file namespace.c.

3488{
3489 char *schemaname;
3490 Oid namespaceId;
3491
3492 /* deconstruct the name list */
3493 DeconstructQualifiedName(names, &schemaname, objname_p);
3494
3495 if (schemaname)
3496 {
3497 /* check for pg_temp alias */
3498 if (strcmp(schemaname, "pg_temp") == 0)
3499 {
3500 /* Initialize temp namespace */
3502 return myTempNamespace;
3503 }
3504 /* use exact schema given */
3505 namespaceId = get_namespace_oid(schemaname, false);
3506 /* we do not check for USAGE rights here! */
3507 }
3508 else
3509 {
3510 /* use the default creation namespace */
3513 {
3514 /* Need to initialize temp namespace */
3516 return myTempNamespace;
3517 }
3518 namespaceId = activeCreationNamespace;
3519 if (!OidIsValid(namespaceId))
3520 ereport(ERROR,
3521 (errcode(ERRCODE_UNDEFINED_SCHEMA),
3522 errmsg("no schema has been selected to create in")));
3523 }
3524
3525 return namespaceId;
3526}

References AccessTempTableNamespace(), activeCreationNamespace, activeTempCreationPending, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, get_namespace_oid(), myTempNamespace, OidIsValid, and recomputeNamespacePath().

Referenced by compute_return_type(), CreateConversionCommand(), CreateFunction(), CreateStatistics(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), DefineType(), and get_other_operator().

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 846 of file namespace.c.

847{
848 switch (newRelation->relpersistence)
849 {
850 case RELPERSISTENCE_TEMP:
852 {
855 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
856 errmsg("cannot create relations in temporary schemas of other sessions")));
857 else
859 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
860 errmsg("cannot create temporary relation in non-temporary schema")));
861 }
862 break;
863 case RELPERSISTENCE_PERMANENT:
865 newRelation->relpersistence = RELPERSISTENCE_TEMP;
866 else if (isAnyTempNamespace(nspid))
868 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
869 errmsg("cannot create relations in temporary schemas of other sessions")));
870 break;
871 default:
874 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
875 errmsg("only temporary relations may be created in temporary schemas")));
876 }
877}
int nspid
char relpersistence
Definition: primnodes.h:88

References ereport, errcode(), errmsg(), ERROR, isAnyTempNamespace(), isTempOrTempToastNamespace(), nspid, and RangeVar::relpersistence.

Referenced by DefineCompositeType(), generateSerialExtraStmts(), and RangeVarGetAndCheckCreationNamespace().

◆ RangeVarGetAndCheckCreationNamespace()

Oid RangeVarGetAndCheckCreationNamespace ( RangeVar relation,
LOCKMODE  lockmode,
Oid existing_relation_id 
)

Definition at line 739 of file namespace.c.

742{
743 uint64 inval_count;
744 Oid relid;
745 Oid oldrelid = InvalidOid;
746 Oid nspid;
747 Oid oldnspid = InvalidOid;
748 bool retry = false;
749
750 /*
751 * We check the catalog name and then ignore it.
752 */
753 if (relation->catalogname)
754 {
755 if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
757 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
758 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
759 relation->catalogname, relation->schemaname,
760 relation->relname)));
761 }
762
763 /*
764 * As in RangeVarGetRelidExtended(), we guard against concurrent DDL
765 * operations by tracking whether any invalidation messages are processed
766 * while we're doing the name lookups and acquiring locks. See comments
767 * in that function for a more detailed explanation of this logic.
768 */
769 for (;;)
770 {
771 AclResult aclresult;
772
773 inval_count = SharedInvalidMessageCounter;
774
775 /* Look up creation namespace and check for existing relation. */
778 if (existing_relation_id != NULL)
779 relid = get_relname_relid(relation->relname, nspid);
780 else
781 relid = InvalidOid;
782
783 /*
784 * In bootstrap processing mode, we don't bother with permissions or
785 * locking. Permissions might not be working yet, and locking is
786 * unnecessary.
787 */
789 break;
790
791 /* Check namespace permissions. */
792 aclresult = object_aclcheck(NamespaceRelationId, nspid, GetUserId(), ACL_CREATE);
793 if (aclresult != ACLCHECK_OK)
794 aclcheck_error(aclresult, OBJECT_SCHEMA,
796
797 if (retry)
798 {
799 /* If nothing changed, we're done. */
800 if (relid == oldrelid && nspid == oldnspid)
801 break;
802 /* If creation namespace has changed, give up old lock. */
803 if (nspid != oldnspid)
804 UnlockDatabaseObject(NamespaceRelationId, oldnspid, 0,
806 /* If name points to something different, give up old lock. */
807 if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock)
808 UnlockRelationOid(oldrelid, lockmode);
809 }
810
811 /* Lock namespace. */
812 if (nspid != oldnspid)
813 LockDatabaseObject(NamespaceRelationId, nspid, 0, AccessShareLock);
814
815 /* Lock relation, if required if and we have permission. */
816 if (lockmode != NoLock && OidIsValid(relid))
817 {
818 if (!object_ownercheck(RelationRelationId, relid, GetUserId()))
820 relation->relname);
821 if (relid != oldrelid)
822 LockRelationOid(relid, lockmode);
823 }
824
825 /* If no invalidation message were processed, we're done! */
826 if (inval_count == SharedInvalidMessageCounter)
827 break;
828
829 /* Something may have changed, so recheck our work. */
830 retry = true;
831 oldrelid = relid;
832 oldnspid = nspid;
833 }
834
836 if (existing_relation_id != NULL)
837 *existing_relation_id = relid;
838 return nspid;
839}
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:4058
uint64_t uint64
Definition: c.h:489
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:226
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:993
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:107
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1052
#define NoLock
Definition: lockdefs.h:34
#define AccessShareLock
Definition: lockdefs.h:36
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:2003
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1885
void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
Definition: namespace.c:846
Oid RangeVarGetCreationNamespace(const RangeVar *newRelation)
Definition: namespace.c:654
ObjectType get_relkind_objtype(char relkind)
uint64 SharedInvalidMessageCounter
Definition: sinval.c:24

References AccessShareLock, ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, RangeVar::catalogname, ereport, errcode(), errmsg(), ERROR, get_database_name(), get_namespace_name(), get_rel_relkind(), get_relkind_objtype(), get_relname_relid(), GetUserId(), InvalidOid, IsBootstrapProcessingMode, LockDatabaseObject(), LockRelationOid(), MyDatabaseId, NoLock, nspid, object_aclcheck(), object_ownercheck(), OBJECT_SCHEMA, OidIsValid, RangeVarAdjustRelationPersistence(), RangeVarGetCreationNamespace(), RangeVar::relname, RangeVar::schemaname, SharedInvalidMessageCounter, UnlockDatabaseObject(), and UnlockRelationOid().

Referenced by AlterTableNamespace(), DefineCompositeType(), DefineRelation(), DefineSequence(), DefineVirtualRelation(), and transformCreateStmt().

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 654 of file namespace.c.

655{
656 Oid namespaceId;
657
658 /*
659 * We check the catalog name and then ignore it.
660 */
661 if (newRelation->catalogname)
662 {
663 if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
665 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
666 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
667 newRelation->catalogname, newRelation->schemaname,
668 newRelation->relname)));
669 }
670
671 if (newRelation->schemaname)
672 {
673 /* check for pg_temp alias */
674 if (strcmp(newRelation->schemaname, "pg_temp") == 0)
675 {
676 /* Initialize temp namespace */
678 return myTempNamespace;
679 }
680 /* use exact schema given */
681 namespaceId = get_namespace_oid(newRelation->schemaname, false);
682 /* we do not check for USAGE rights here! */
683 }
684 else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
685 {
686 /* Initialize temp namespace */
688 return myTempNamespace;
689 }
690 else
691 {
692 /* use the default creation namespace */
695 {
696 /* Need to initialize temp namespace */
698 return myTempNamespace;
699 }
700 namespaceId = activeCreationNamespace;
701 if (!OidIsValid(namespaceId))
703 (errcode(ERRCODE_UNDEFINED_SCHEMA),
704 errmsg("no schema has been selected to create in")));
705 }
706
707 /* Note: callers will check for CREATE rights when appropriate */
708
709 return namespaceId;
710}

References AccessTempTableNamespace(), activeCreationNamespace, activeTempCreationPending, RangeVar::catalogname, ereport, errcode(), errmsg(), ERROR, get_database_name(), get_namespace_oid(), MyDatabaseId, myTempNamespace, OidIsValid, recomputeNamespacePath(), RangeVar::relname, RangeVar::relpersistence, and RangeVar::schemaname.

Referenced by CreateTableAsRelExists(), generateSerialExtraStmts(), and RangeVarGetAndCheckCreationNamespace().

◆ RangeVarGetRelidExtended()

Oid RangeVarGetRelidExtended ( const RangeVar relation,
LOCKMODE  lockmode,
uint32  flags,
RangeVarGetRelidCallback  callback,
void *  callback_arg 
)

Definition at line 441 of file namespace.c.

444{
445 uint64 inval_count;
446 Oid relId;
447 Oid oldRelId = InvalidOid;
448 bool retry = false;
449 bool missing_ok = (flags & RVR_MISSING_OK) != 0;
450
451 /* verify that flags do no conflict */
452 Assert(!((flags & RVR_NOWAIT) && (flags & RVR_SKIP_LOCKED)));
453
454 /*
455 * We check the catalog name and then ignore it.
456 */
457 if (relation->catalogname)
458 {
459 if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
461 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
462 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
463 relation->catalogname, relation->schemaname,
464 relation->relname)));
465 }
466
467 /*
468 * DDL operations can change the results of a name lookup. Since all such
469 * operations will generate invalidation messages, we keep track of
470 * whether any such messages show up while we're performing the operation,
471 * and retry until either (1) no more invalidation messages show up or (2)
472 * the answer doesn't change.
473 *
474 * But if lockmode = NoLock, then we assume that either the caller is OK
475 * with the answer changing under them, or that they already hold some
476 * appropriate lock, and therefore return the first answer we get without
477 * checking for invalidation messages. Also, if the requested lock is
478 * already held, LockRelationOid will not AcceptInvalidationMessages, so
479 * we may fail to notice a change. We could protect against that case by
480 * calling AcceptInvalidationMessages() before beginning this loop, but
481 * that would add a significant amount overhead, so for now we don't.
482 */
483 for (;;)
484 {
485 /*
486 * Remember this value, so that, after looking up the relation name
487 * and locking its OID, we can check whether any invalidation messages
488 * have been processed that might require a do-over.
489 */
490 inval_count = SharedInvalidMessageCounter;
491
492 /*
493 * Some non-default relpersistence value may have been specified. The
494 * parser never generates such a RangeVar in simple DML, but it can
495 * happen in contexts such as "CREATE TEMP TABLE foo (f1 int PRIMARY
496 * KEY)". Such a command will generate an added CREATE INDEX
497 * operation, which must be careful to find the temp table, even when
498 * pg_temp is not first in the search path.
499 */
500 if (relation->relpersistence == RELPERSISTENCE_TEMP)
501 {
503 relId = InvalidOid; /* this probably can't happen? */
504 else
505 {
506 if (relation->schemaname)
507 {
508 Oid namespaceId;
509
510 namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
511
512 /*
513 * For missing_ok, allow a non-existent schema name to
514 * return InvalidOid.
515 */
516 if (namespaceId != myTempNamespace)
518 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
519 errmsg("temporary tables cannot specify a schema name")));
520 }
521
522 relId = get_relname_relid(relation->relname, myTempNamespace);
523 }
524 }
525 else if (relation->schemaname)
526 {
527 Oid namespaceId;
528
529 /* use exact schema given */
530 namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
531 if (missing_ok && !OidIsValid(namespaceId))
532 relId = InvalidOid;
533 else
534 relId = get_relname_relid(relation->relname, namespaceId);
535 }
536 else
537 {
538 /* search the namespace path */
539 relId = RelnameGetRelid(relation->relname);
540 }
541
542 /*
543 * Invoke caller-supplied callback, if any.
544 *
545 * This callback is a good place to check permissions: we haven't
546 * taken the table lock yet (and it's really best to check permissions
547 * before locking anything!), but we've gotten far enough to know what
548 * OID we think we should lock. Of course, concurrent DDL might
549 * change things while we're waiting for the lock, but in that case
550 * the callback will be invoked again for the new OID.
551 */
552 if (callback)
553 callback(relation, relId, oldRelId, callback_arg);
554
555 /*
556 * If no lock requested, we assume the caller knows what they're
557 * doing. They should have already acquired a heavyweight lock on
558 * this relation earlier in the processing of this same statement, so
559 * it wouldn't be appropriate to AcceptInvalidationMessages() here, as
560 * that might pull the rug out from under them.
561 */
562 if (lockmode == NoLock)
563 break;
564
565 /*
566 * If, upon retry, we get back the same OID we did last time, then the
567 * invalidation messages we processed did not change the final answer.
568 * So we're done.
569 *
570 * If we got a different OID, we've locked the relation that used to
571 * have this name rather than the one that does now. So release the
572 * lock.
573 */
574 if (retry)
575 {
576 if (relId == oldRelId)
577 break;
578 if (OidIsValid(oldRelId))
579 UnlockRelationOid(oldRelId, lockmode);
580 }
581
582 /*
583 * Lock relation. This will also accept any pending invalidation
584 * messages. If we got back InvalidOid, indicating not found, then
585 * there's nothing to lock, but we accept invalidation messages
586 * anyway, to flush any negative catcache entries that may be
587 * lingering.
588 */
589 if (!OidIsValid(relId))
591 else if (!(flags & (RVR_NOWAIT | RVR_SKIP_LOCKED)))
592 LockRelationOid(relId, lockmode);
593 else if (!ConditionalLockRelationOid(relId, lockmode))
594 {
595 int elevel = (flags & RVR_SKIP_LOCKED) ? DEBUG1 : ERROR;
596
597 if (relation->schemaname)
598 ereport(elevel,
599 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
600 errmsg("could not obtain lock on relation \"%s.%s\"",
601 relation->schemaname, relation->relname)));
602 else
603 ereport(elevel,
604 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
605 errmsg("could not obtain lock on relation \"%s\"",
606 relation->relname)));
607
608 return InvalidOid;
609 }
610
611 /*
612 * If no invalidation message were processed, we're done!
613 */
614 if (inval_count == SharedInvalidMessageCounter)
615 break;
616
617 /*
618 * Something may have changed. Let's repeat the name lookup, to make
619 * sure this name still references the same relation it did
620 * previously.
621 */
622 retry = true;
623 oldRelId = relId;
624 }
625
626 if (!OidIsValid(relId))
627 {
628 int elevel = missing_ok ? DEBUG1 : ERROR;
629
630 if (relation->schemaname)
631 ereport(elevel,
633 errmsg("relation \"%s.%s\" does not exist",
634 relation->schemaname, relation->relname)));
635 else
636 ereport(elevel,
638 errmsg("relation \"%s\" does not exist",
639 relation->relname)));
640 }
641 return relId;
642}
#define DEBUG1
Definition: elog.h:30
void AcceptInvalidationMessages(void)
Definition: inval.c:863
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:150
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:885
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:78
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46

References AcceptInvalidationMessages(), Assert, callback(), RangeVar::catalogname, ConditionalLockRelationOid(), DEBUG1, ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, get_database_name(), get_relname_relid(), InvalidOid, LockRelationOid(), LookupExplicitNamespace(), MyDatabaseId, myTempNamespace, NoLock, OidIsValid, RangeVar::relname, RelnameGetRelid(), RangeVar::relpersistence, RVR_MISSING_OK, RVR_NOWAIT, RVR_SKIP_LOCKED, RangeVar::schemaname, SharedInvalidMessageCounter, and UnlockRelationOid().

Referenced by AlterPolicy(), AlterSequence(), AlterTableLookupRelation(), AlterTableNamespace(), ATExecAttachPartitionIdx(), cluster(), CreatePolicy(), ExecRefreshMatView(), ExecuteTruncate(), expand_vacuum_rel(), LockTableCommand(), ProcessUtilitySlow(), ReindexIndex(), ReindexTable(), RemoveRelations(), rename_policy(), renameatt(), RenameConstraint(), RenameRelation(), RenameRewriteRule(), and renametrig().

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 913 of file namespace.c.

914{
915 return RelationIsVisibleExt(relid, NULL);
916}
static bool RelationIsVisibleExt(Oid relid, bool *is_missing)
Definition: namespace.c:925

References RelationIsVisibleExt().

Referenced by generate_relation_name(), getRelationDescription(), and regclassout().

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 885 of file namespace.c.

886{
887 Oid relid;
888 ListCell *l;
889
891
892 foreach(l, activeSearchPath)
893 {
894 Oid namespaceId = lfirst_oid(l);
895
896 relid = get_relname_relid(relname, namespaceId);
897 if (OidIsValid(relid))
898 return relid;
899 }
900
901 /* Not found in path */
902 return InvalidOid;
903}
NameData relname
Definition: pg_class.h:38

References activeSearchPath, get_relname_relid(), InvalidOid, lfirst_oid, OidIsValid, recomputeNamespacePath(), and relname.

Referenced by plpgsql_parse_wordrowtype(), and RangeVarGetRelidExtended().

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4644 of file namespace.c.

4645{
4648}
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4598

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

◆ SearchPathMatchesCurrentEnvironment()

bool SearchPathMatchesCurrentEnvironment ( SearchPathMatcher path)

Definition at line 3911 of file namespace.c.

3912{
3913 ListCell *lc,
3914 *lcp;
3915
3917
3918 /* Quick out if already known equal to active path. */
3919 if (path->generation == activePathGeneration)
3920 return true;
3921
3922 /* We scan down the activeSearchPath to see if it matches the input. */
3924
3925 /* If path->addTemp, first item should be my temp namespace. */
3926 if (path->addTemp)
3927 {
3928 if (lc && lfirst_oid(lc) == myTempNamespace)
3929 lc = lnext(activeSearchPath, lc);
3930 else
3931 return false;
3932 }
3933 /* If path->addCatalog, next item should be pg_catalog. */
3934 if (path->addCatalog)
3935 {
3936 if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3937 lc = lnext(activeSearchPath, lc);
3938 else
3939 return false;
3940 }
3941 /* We should now be looking at the activeCreationNamespace. */
3942 if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3943 return false;
3944 /* The remainder of activeSearchPath should match path->schemas. */
3945 foreach(lcp, path->schemas)
3946 {
3947 if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3948 lc = lnext(activeSearchPath, lc);
3949 else
3950 return false;
3951 }
3952 if (lc)
3953 return false;
3954
3955 /*
3956 * Update path->generation so that future tests will return quickly, so
3957 * long as the active search path doesn't change.
3958 */
3960
3961 return true;
3962}
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343

References activeCreationNamespace, activePathGeneration, activeSearchPath, SearchPathMatcher::addCatalog, SearchPathMatcher::addTemp, SearchPathMatcher::generation, InvalidOid, lfirst_oid, list_head(), lnext(), myTempNamespace, recomputeNamespacePath(), and SearchPathMatcher::schemas.

Referenced by CachedPlanAllowsSimpleValidityCheck(), CachedPlanIsSimplyValid(), and RevalidateCachedQuery().

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3821 of file namespace.c.

3822{
3823 /* Worker should not have created its own namespaces ... */
3827
3828 /* Assign same namespace OIDs that leader has */
3829 myTempNamespace = tempNamespaceId;
3830 myTempToastNamespace = tempToastNamespaceId;
3831
3832 /*
3833 * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
3834 * Even if the namespace is new so far as the leader is concerned, it's
3835 * not new to the worker, and we certainly wouldn't want the worker trying
3836 * to destroy it.
3837 */
3838
3839 baseSearchPathValid = false; /* may need to rebuild list */
3840 searchPathCacheValid = false;
3841}

References Assert, baseSearchPathValid, InvalidOid, InvalidSubTransactionId, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, and searchPathCacheValid.

Referenced by ParallelWorkerMain().

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  stxid)

Definition at line 2632 of file namespace.c.

2633{
2634 return StatisticsObjIsVisibleExt(stxid, NULL);
2635}
static bool StatisticsObjIsVisibleExt(Oid stxid, bool *is_missing)
Definition: namespace.c:2644

References StatisticsObjIsVisibleExt().

Referenced by getObjectDescription().

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 3210 of file namespace.c.

3211{
3212 return TSConfigIsVisibleExt(cfgid, NULL);
3213}
static bool TSConfigIsVisibleExt(Oid cfgid, bool *is_missing)
Definition: namespace.c:3222

References TSConfigIsVisibleExt().

Referenced by getObjectDescription(), and regconfigout().

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2919 of file namespace.c.

2920{
2921 return TSDictionaryIsVisibleExt(dictId, NULL);
2922}
static bool TSDictionaryIsVisibleExt(Oid dictId, bool *is_missing)
Definition: namespace.c:2931

References TSDictionaryIsVisibleExt().

Referenced by getObjectDescription(), and regdictionaryout().

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2774 of file namespace.c.

2775{
2776 return TSParserIsVisibleExt(prsId, NULL);
2777}
static bool TSParserIsVisibleExt(Oid prsId, bool *is_missing)
Definition: namespace.c:2786

References TSParserIsVisibleExt().

Referenced by getObjectDescription().

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 3065 of file namespace.c.

3066{
3067 return TSTemplateIsVisibleExt(tmplId, NULL);
3068}
static bool TSTemplateIsVisibleExt(Oid tmplId, bool *is_missing)
Definition: namespace.c:3077

References TSTemplateIsVisibleExt().

Referenced by getObjectDescription().

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 1040 of file namespace.c.

1041{
1042 return TypeIsVisibleExt(typid, NULL);
1043}
static bool TypeIsVisibleExt(Oid typid, bool *is_missing)
Definition: namespace.c:1052

References TypeIsVisibleExt().

Referenced by format_type_extended().

◆ TypenameGetTypid()

Oid TypenameGetTypid ( const char *  typname)

Definition at line 995 of file namespace.c.

996{
997 return TypenameGetTypidExtended(typname, true);
998}
Oid TypenameGetTypidExtended(const char *typname, bool temp_ok)
Definition: namespace.c:1008
NameData typname
Definition: pg_type.h:41

References TypenameGetTypidExtended(), and typname.

◆ TypenameGetTypidExtended()

Oid TypenameGetTypidExtended ( const char *  typname,
bool  temp_ok 
)

Definition at line 1008 of file namespace.c.

1009{
1010 Oid typid;
1011 ListCell *l;
1012
1014
1015 foreach(l, activeSearchPath)
1016 {
1017 Oid namespaceId = lfirst_oid(l);
1018
1019 if (!temp_ok && namespaceId == myTempNamespace)
1020 continue; /* do not look in temp namespace */
1021
1022 typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
1024 ObjectIdGetDatum(namespaceId));
1025 if (OidIsValid(typid))
1026 return typid;
1027 }
1028
1029 /* Not found in path */
1030 return InvalidOid;
1031}

References activeSearchPath, GetSysCacheOid2, InvalidOid, lfirst_oid, myTempNamespace, ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), recomputeNamespacePath(), and typname.

Referenced by LookupTypeNameExtended(), and TypenameGetTypid().

Variable Documentation

◆ namespace_search_path

PGDLLIMPORT char* namespace_search_path
extern

Definition at line 211 of file namespace.c.

Referenced by CreateSchemaCommand(), and recomputeNamespacePath().