PostgreSQL Source Code  git master
namespace.h File Reference
#include "nodes/primnodes.h"
#include "storage/lock.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  OverrideSearchPath
 

Macros

#define RangeVarGetRelid(relation, lockmode, missing_ok)
 

Typedefs

typedef struct _FuncCandidateListFuncCandidateList
 
typedef enum TempNamespaceStatus TempNamespaceStatus
 
typedef struct OverrideSearchPath OverrideSearchPath
 
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 *newRelation, 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 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 relid)
 
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 (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 (List *names, char **objname_p)
 
RangeVarmakeRangeVarFromNameList (List *names)
 
char * NameListToString (List *names)
 
char * NameListToQuotedString (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)
 
int GetTempNamespaceBackendId (Oid namespaceId)
 
Oid GetTempToastNamespace (void)
 
void GetTempNamespaceState (Oid *tempNamespaceId, Oid *tempToastNamespaceId)
 
void SetTempNamespaceState (Oid tempNamespaceId, Oid tempToastNamespaceId)
 
void ResetTempTableNamespace (void)
 
OverrideSearchPathGetOverrideSearchPath (MemoryContext context)
 
OverrideSearchPathCopyOverrideSearchPath (OverrideSearchPath *path)
 
bool OverrideSearchPathMatchesCurrent (OverrideSearchPath *path)
 
void PushOverrideSearchPath (OverrideSearchPath *newpath)
 
void PopOverrideSearchPath (void)
 
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

char * namespace_search_path
 

Macro Definition Documentation

◆ RangeVarGetRelid

Typedef Documentation

◆ FuncCandidateList

◆ OverrideSearchPath

◆ RangeVarGetRelidCallback

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

Definition at line 75 of file namespace.h.

◆ RVROption

typedef enum RVROption RVROption

◆ TempNamespaceStatus

Enumeration Type Documentation

◆ RVROption

enum RVROption
Enumerator
RVR_MISSING_OK 
RVR_NOWAIT 
RVR_SKIP_LOCKED 

Definition at line 68 of file namespace.h.

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

◆ TempNamespaceStatus

Enumerator
TEMP_NAMESPACE_NOT_TEMP 
TEMP_NAMESPACE_IDLE 
TEMP_NAMESPACE_IN_USE 

Definition at line 43 of file namespace.h.

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

Function Documentation

◆ AtEOSubXact_Namespace()

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

Definition at line 4131 of file namespace.c.

References activeCreationNamespace, activePathGeneration, activeTempCreationPending, baseCreationNamespace, baseSearchPath, baseSearchPathValid, baseTempCreationPending, OverrideStackEntry::creationNamespace, elog, GetCurrentTransactionNestLevel(), InvalidOid, InvalidSubTransactionId, linitial, list_delete_first(), list_free(), MyProc, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, OverrideStackEntry::nestLevel, pfree(), OverrideStackEntry::searchPath, PGPROC::tempNamespaceId, and WARNING.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

4133 {
4134  OverrideStackEntry *entry;
4135 
4136  if (myTempNamespaceSubID == mySubid)
4137  {
4138  if (isCommit)
4139  myTempNamespaceSubID = parentSubid;
4140  else
4141  {
4143  /* TEMP namespace creation failed, so reset state */
4146  baseSearchPathValid = false; /* need to rebuild list */
4147 
4148  /*
4149  * Reset the temporary namespace flag in MyProc. We assume that
4150  * this operation is atomic.
4151  *
4152  * Because this subtransaction is aborting, the pg_namespace row
4153  * is not visible to anyone else anyway, but that doesn't matter:
4154  * it's not a problem if objects contained in this namespace are
4155  * removed concurrently.
4156  */
4158  }
4159  }
4160 
4161  /*
4162  * Clean up if someone failed to do PopOverrideSearchPath
4163  */
4164  while (overrideStack)
4165  {
4168  break;
4169  if (isCommit)
4170  elog(WARNING, "leaked override search path");
4172  list_free(entry->searchPath);
4173  pfree(entry);
4174  /* Always bump generation --- see note in recomputeNamespacePath */
4176  }
4177 
4178  /* Activate the next level down. */
4179  if (overrideStack)
4180  {
4182  activeSearchPath = entry->searchPath;
4184  activeTempCreationPending = false; /* XXX is this OK? */
4185 
4186  /*
4187  * It's probably unnecessary to bump generation here, but this should
4188  * not be a performance-critical case, so better to be over-cautious.
4189  */
4191  }
4192  else
4193  {
4194  /* If not baseSearchPathValid, this is useless but harmless */
4198 
4199  /*
4200  * If we popped an override stack entry, then we already bumped the
4201  * generation above. If we did not, then the above assignments did
4202  * nothing and we need not bump the generation.
4203  */
4204  }
4205 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid tempNamespaceId
Definition: proc.h:148
PGPROC * MyProc
Definition: proc.c:67
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1057
#define linitial(l)
Definition: pg_list.h:174
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:151
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
#define InvalidSubTransactionId
Definition: c.h:527
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1376
#define elog(elevel,...)
Definition: elog.h:214
List * list_delete_first(List *list)
Definition: list.c:860

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4063 of file namespace.c.

References activeCreationNamespace, activePathGeneration, activeTempCreationPending, baseCreationNamespace, baseSearchPath, baseSearchPathValid, baseTempCreationPending, before_shmem_exit(), elog, InvalidOid, InvalidSubTransactionId, linitial, list_delete_first(), list_free(), MyProc, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, pfree(), RemoveTempRelationsCallback(), OverrideStackEntry::searchPath, PGPROC::tempNamespaceId, and WARNING.

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

4064 {
4065  /*
4066  * If we abort the transaction in which a temp namespace was selected,
4067  * we'll have to do any creation or cleanout work over again. So, just
4068  * forget the namespace entirely until next time. On the other hand, if
4069  * we commit then register an exit callback to clean out the temp tables
4070  * at backend shutdown. (We only want to register the callback once per
4071  * session, so this is a good place to do it.)
4072  */
4073  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
4074  {
4075  if (isCommit)
4077  else
4078  {
4081  baseSearchPathValid = false; /* need to rebuild list */
4082 
4083  /*
4084  * Reset the temporary namespace flag in MyProc. We assume that
4085  * this operation is atomic.
4086  *
4087  * Because this transaction is aborting, the pg_namespace row is
4088  * not visible to anyone else anyway, but that doesn't matter:
4089  * it's not a problem if objects contained in this namespace are
4090  * removed concurrently.
4091  */
4093  }
4095  }
4096 
4097  /*
4098  * Clean up if someone failed to do PopOverrideSearchPath
4099  */
4100  if (overrideStack)
4101  {
4102  if (isCommit)
4103  elog(WARNING, "leaked override search path");
4104  while (overrideStack)
4105  {
4106  OverrideStackEntry *entry;
4107 
4110  list_free(entry->searchPath);
4111  pfree(entry);
4112  }
4113  /* If not baseSearchPathValid, this is useless but harmless */
4117  /* Always bump generation --- see note in recomputeNamespacePath */
4119  }
4120 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid tempNamespaceId
Definition: proc.h:148
PGPROC * MyProc
Definition: proc.c:67
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1057
#define linitial(l)
Definition: pg_list.h:174
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:151
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidSubTransactionId
Definition: c.h:527
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1376
#define elog(elevel,...)
Definition: elog.h:214
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4242
List * list_delete_first(List *list)
Definition: list.c:860

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2966 of file namespace.c.

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

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

2967 {
2968  /* disallow renaming into or out of temp schemas */
2969  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2970  ereport(ERROR,
2971  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2972  errmsg("cannot move objects into or out of temporary schemas")));
2973 
2974  /* same for TOAST schema */
2975  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
2976  ereport(ERROR,
2977  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2978  errmsg("cannot move objects into or out of TOAST schema")));
2979 }
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:821
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3194

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3236 of file namespace.c.

References Assert, BackendIdGetProc(), PGPROC::databaseId, GetTempNamespaceBackendId(), InvalidBackendId, MyDatabaseId, OidIsValid, TEMP_NAMESPACE_IDLE, TEMP_NAMESPACE_IN_USE, TEMP_NAMESPACE_NOT_TEMP, and PGPROC::tempNamespaceId.

Referenced by do_autovacuum().

3237 {
3238  PGPROC *proc;
3239  int backendId;
3240 
3242 
3243  backendId = GetTempNamespaceBackendId(namespaceId);
3244 
3245  /* No such namespace, or its name shows it's not temp? */
3246  if (backendId == InvalidBackendId)
3247  return TEMP_NAMESPACE_NOT_TEMP;
3248 
3249  /* Is the backend alive? */
3250  proc = BackendIdGetProc(backendId);
3251  if (proc == NULL)
3252  return TEMP_NAMESPACE_IDLE;
3253 
3254  /* Is the backend connected to the same database we are looking at? */
3255  if (proc->databaseId != MyDatabaseId)
3256  return TEMP_NAMESPACE_IDLE;
3257 
3258  /* Does the backend own the temporary namespace? */
3259  if (proc->tempNamespaceId != namespaceId)
3260  return TEMP_NAMESPACE_IDLE;
3261 
3262  /* Yup, so namespace is busy */
3263  return TEMP_NAMESPACE_IN_USE;
3264 }
Oid tempNamespaceId
Definition: proc.h:148
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3273
#define OidIsValid(objectId)
Definition: c.h:652
Oid databaseId
Definition: proc.h:145
#define InvalidBackendId
Definition: backendid.h:23
Oid MyDatabaseId
Definition: globals.c:85
#define Assert(condition)
Definition: c.h:746
Definition: proc.h:112
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:376

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2013 of file namespace.c.

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

Referenced by CollationIsVisible().

2014 {
2015  int32 dbencoding = GetDatabaseEncoding();
2016  ListCell *l;
2017 
2019 
2020  foreach(l, activeSearchPath)
2021  {
2022  Oid namespaceId = lfirst_oid(l);
2023  Oid collid;
2024 
2025  if (namespaceId == myTempNamespace)
2026  continue; /* do not look in temp namespace */
2027 
2028  collid = lookup_collation(collname, namespaceId, dbencoding);
2029  if (OidIsValid(collid))
2030  return collid;
2031  }
2032 
2033  /* Not found in path */
2034  return InvalidOid;
2035 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
signed int int32
Definition: c.h:363
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1962
int GetDatabaseEncoding(void)
Definition: mbutils.c:1151
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2047 of file namespace.c.

References CollationGetCollid(), COLLOID, elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1().

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

2048 {
2049  HeapTuple colltup;
2050  Form_pg_collation collform;
2051  Oid collnamespace;
2052  bool visible;
2053 
2054  colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
2055  if (!HeapTupleIsValid(colltup))
2056  elog(ERROR, "cache lookup failed for collation %u", collid);
2057  collform = (Form_pg_collation) GETSTRUCT(colltup);
2058 
2060 
2061  /*
2062  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2063  * the system namespace are surely in the path and so we needn't even do
2064  * list_member_oid() for them.
2065  */
2066  collnamespace = collform->collnamespace;
2067  if (collnamespace != PG_CATALOG_NAMESPACE &&
2068  !list_member_oid(activeSearchPath, collnamespace))
2069  visible = false;
2070  else
2071  {
2072  /*
2073  * If it is in the path, it might still not be visible; it could be
2074  * hidden by another collation of the same name earlier in the path,
2075  * or it might not work with the current DB encoding. So we must do a
2076  * slow check to see if this collation would be found by
2077  * CollationGetCollid.
2078  */
2079  char *collname = NameStr(collform->collname);
2080 
2081  visible = (CollationGetCollid(collname) == collid);
2082  }
2083 
2084  ReleaseSysCache(colltup);
2085 
2086  return visible;
2087 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid CollationGetCollid(const char *collname)
Definition: namespace.c:2013
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:51
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2098 of file namespace.c.

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

Referenced by ConversionIsVisible().

2099 {
2100  Oid conid;
2101  ListCell *l;
2102 
2104 
2105  foreach(l, activeSearchPath)
2106  {
2107  Oid namespaceId = lfirst_oid(l);
2108 
2109  if (namespaceId == myTempNamespace)
2110  continue; /* do not look in temp namespace */
2111 
2112  conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2113  PointerGetDatum(conname),
2114  ObjectIdGetDatum(namespaceId));
2115  if (OidIsValid(conid))
2116  return conid;
2117  }
2118 
2119  /* Not found in path */
2120  return InvalidOid;
2121 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2130 of file namespace.c.

References ConversionGetConid(), CONVOID, elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1().

Referenced by getObjectDescription(), and pg_conversion_is_visible().

2131 {
2132  HeapTuple contup;
2133  Form_pg_conversion conform;
2134  Oid connamespace;
2135  bool visible;
2136 
2137  contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
2138  if (!HeapTupleIsValid(contup))
2139  elog(ERROR, "cache lookup failed for conversion %u", conid);
2140  conform = (Form_pg_conversion) GETSTRUCT(contup);
2141 
2143 
2144  /*
2145  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2146  * the system namespace are surely in the path and so we needn't even do
2147  * list_member_oid() for them.
2148  */
2149  connamespace = conform->connamespace;
2150  if (connamespace != PG_CATALOG_NAMESPACE &&
2151  !list_member_oid(activeSearchPath, connamespace))
2152  visible = false;
2153  else
2154  {
2155  /*
2156  * If it is in the path, it might still not be visible; it could be
2157  * hidden by another conversion of the same name earlier in the path.
2158  * So we must do a slow check to see if this conversion would be found
2159  * by ConversionGetConid.
2160  */
2161  char *conname = NameStr(conform->conname);
2162 
2163  visible = (ConversionGetConid(conname) == conid);
2164  }
2165 
2166  ReleaseSysCache(contup);
2167 
2168  return visible;
2169 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
Oid ConversionGetConid(const char *conname)
Definition: namespace.c:2098
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:61
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3396 of file namespace.c.

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

Referenced by CopyCachedPlan().

3397 {
3398  OverrideSearchPath *result;
3399 
3400  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3401  result->schemas = list_copy(path->schemas);
3402  result->addCatalog = path->addCatalog;
3403  result->addTemp = path->addTemp;
3404  result->generation = path->generation;
3405 
3406  return result;
3407 }
List * list_copy(const List *oldlist)
Definition: list.c:1403
void * palloc(Size size)
Definition: mcxt.c:950

◆ DeconstructQualifiedName()

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

Definition at line 2808 of file namespace.c.

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().

2811 {
2812  char *catalogname;
2813  char *schemaname = NULL;
2814  char *objname = NULL;
2815 
2816  switch (list_length(names))
2817  {
2818  case 1:
2819  objname = strVal(linitial(names));
2820  break;
2821  case 2:
2822  schemaname = strVal(linitial(names));
2823  objname = strVal(lsecond(names));
2824  break;
2825  case 3:
2826  catalogname = strVal(linitial(names));
2827  schemaname = strVal(lsecond(names));
2828  objname = strVal(lthird(names));
2829 
2830  /*
2831  * We check the catalog name and then ignore it.
2832  */
2833  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2834  ereport(ERROR,
2835  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2836  errmsg("cross-database references are not implemented: %s",
2837  NameListToString(names))));
2838  break;
2839  default:
2840  ereport(ERROR,
2841  (errcode(ERRCODE_SYNTAX_ERROR),
2842  errmsg("improper qualified name (too many dotted names): %s",
2843  NameListToString(names))));
2844  break;
2845  }
2846 
2847  *nspname_p = schemaname;
2848  *objname_p = objname;
2849 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:610
#define lsecond(l)
Definition: pg_list.h:179
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
char * NameListToString(List *names)
Definition: namespace.c:3101
Oid MyDatabaseId
Definition: globals.c:85
#define ereport(elevel,...)
Definition: elog.h:144
static int list_length(const List *l)
Definition: pg_list.h:149
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define lthird(l)
Definition: pg_list.h:184

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4382 of file namespace.c.

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

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

4383 {
4384  List *result;
4385 
4387 
4388  /*
4389  * If the temp namespace should be first, force it to exist. This is so
4390  * that callers can trust the result to reflect the actual default
4391  * creation namespace. It's a bit bogus to do this here, since
4392  * current_schema() is supposedly a stable function without side-effects,
4393  * but the alternatives seem worse.
4394  */
4396  {
4399  }
4400 
4401  result = list_copy(activeSearchPath);
4402  if (!includeImplicit)
4403  {
4404  while (result && linitial_oid(result) != activeCreationNamespace)
4405  result = list_delete_first(result);
4406  }
4407 
4408  return result;
4409 }
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3914
List * list_copy(const List *oldlist)
Definition: list.c:1403
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
static Oid activeCreationNamespace
Definition: namespace.c:141
static bool activeTempCreationPending
Definition: namespace.c:144
#define linitial_oid(l)
Definition: pg_list.h:176
static List * activeSearchPath
Definition: namespace.c:138
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:860

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4422 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4423 {
4424  int count = 0;
4425  ListCell *l;
4426 
4428 
4429  foreach(l, activeSearchPath)
4430  {
4431  Oid namespaceId = lfirst_oid(l);
4432 
4433  if (namespaceId == myTempNamespace)
4434  continue; /* do not include temp namespace */
4435 
4436  if (count < sarray_len)
4437  sarray[count] = namespaceId;
4438  count++;
4439  }
4440 
4441  return count;
4442 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3709 of file namespace.c.

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

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

3710 {
3711  Oid proc;
3712  ListCell *l;
3713 
3715 
3716  foreach(l, activeSearchPath)
3717  {
3718  Oid namespaceId = lfirst_oid(l);
3719 
3720  if (namespaceId == myTempNamespace)
3721  continue; /* do not look in temp namespace */
3722 
3723  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3724  if (OidIsValid(proc))
3725  return proc;
3726  }
3727 
3728  /* Not found in path */
3729  return InvalidOid;
3730 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ FuncnameGetCandidates()

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

Definition at line 942 of file namespace.c.

References _FuncCandidateList::argnumbers, _FuncCandidateList::args, generate_unaccent_rules::args, Assert, CStringGetDatum, DeconstructQualifiedName(), GETSTRUCT, i, InvalidOid, lfirst_oid, LookupExplicitNamespace(), MatchNamedCall(), Max, catclist::members, myTempNamespace, catclist::n_members, _FuncCandidateList::nargs, _FuncCandidateList::ndargs, _FuncCandidateList::next, NIL, _FuncCandidateList::nvargs, offsetof, _FuncCandidateList::oid, OidIsValid, catclist::ordered, palloc(), _FuncCandidateList::pathpos, pfree(), PROCNAMEARGSNSP, pronargs, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, and catctup::tuple.

Referenced by func_get_detail(), FunctionIsVisible(), LookupFuncNameInternal(), regprocedurein(), regprocin(), regprocout(), to_regproc(), and to_regprocedure().

945 {
946  FuncCandidateList resultList = NULL;
947  bool any_special = false;
948  char *schemaname;
949  char *funcname;
950  Oid namespaceId;
951  CatCList *catlist;
952  int i;
953 
954  /* check for caller error */
955  Assert(nargs >= 0 || !(expand_variadic | expand_defaults));
956 
957  /* deconstruct the name list */
958  DeconstructQualifiedName(names, &schemaname, &funcname);
959 
960  if (schemaname)
961  {
962  /* use exact schema given */
963  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
964  if (!OidIsValid(namespaceId))
965  return NULL;
966  }
967  else
968  {
969  /* flag to indicate we need namespace search */
970  namespaceId = InvalidOid;
972  }
973 
974  /* Search syscache by name only */
976 
977  for (i = 0; i < catlist->n_members; i++)
978  {
979  HeapTuple proctup = &catlist->members[i]->tuple;
980  Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
981  int pronargs = procform->pronargs;
982  int effective_nargs;
983  int pathpos = 0;
984  bool variadic;
985  bool use_defaults;
986  Oid va_elem_type;
987  int *argnumbers = NULL;
988  FuncCandidateList newResult;
989 
990  if (OidIsValid(namespaceId))
991  {
992  /* Consider only procs in specified namespace */
993  if (procform->pronamespace != namespaceId)
994  continue;
995  }
996  else
997  {
998  /*
999  * Consider only procs that are in the search path and are not in
1000  * the temp namespace.
1001  */
1002  ListCell *nsp;
1003 
1004  foreach(nsp, activeSearchPath)
1005  {
1006  if (procform->pronamespace == lfirst_oid(nsp) &&
1007  procform->pronamespace != myTempNamespace)
1008  break;
1009  pathpos++;
1010  }
1011  if (nsp == NULL)
1012  continue; /* proc is not in search path */
1013  }
1014 
1015  if (argnames != NIL)
1016  {
1017  /*
1018  * Call uses named or mixed notation
1019  *
1020  * Named or mixed notation can match a variadic function only if
1021  * expand_variadic is off; otherwise there is no way to match the
1022  * presumed-nameless parameters expanded from the variadic array.
1023  */
1024  if (OidIsValid(procform->provariadic) && expand_variadic)
1025  continue;
1026  va_elem_type = InvalidOid;
1027  variadic = false;
1028 
1029  /*
1030  * Check argument count.
1031  */
1032  Assert(nargs >= 0); /* -1 not supported with argnames */
1033 
1034  if (pronargs > nargs && expand_defaults)
1035  {
1036  /* Ignore if not enough default expressions */
1037  if (nargs + procform->pronargdefaults < pronargs)
1038  continue;
1039  use_defaults = true;
1040  }
1041  else
1042  use_defaults = false;
1043 
1044  /* Ignore if it doesn't match requested argument count */
1045  if (pronargs != nargs && !use_defaults)
1046  continue;
1047 
1048  /* Check for argument name match, generate positional mapping */
1049  if (!MatchNamedCall(proctup, nargs, argnames,
1050  &argnumbers))
1051  continue;
1052 
1053  /* Named argument matching is always "special" */
1054  any_special = true;
1055  }
1056  else
1057  {
1058  /*
1059  * Call uses positional notation
1060  *
1061  * Check if function is variadic, and get variadic element type if
1062  * so. If expand_variadic is false, we should just ignore
1063  * variadic-ness.
1064  */
1065  if (pronargs <= nargs && expand_variadic)
1066  {
1067  va_elem_type = procform->provariadic;
1068  variadic = OidIsValid(va_elem_type);
1069  any_special |= variadic;
1070  }
1071  else
1072  {
1073  va_elem_type = InvalidOid;
1074  variadic = false;
1075  }
1076 
1077  /*
1078  * Check if function can match by using parameter defaults.
1079  */
1080  if (pronargs > nargs && expand_defaults)
1081  {
1082  /* Ignore if not enough default expressions */
1083  if (nargs + procform->pronargdefaults < pronargs)
1084  continue;
1085  use_defaults = true;
1086  any_special = true;
1087  }
1088  else
1089  use_defaults = false;
1090 
1091  /* Ignore if it doesn't match requested argument count */
1092  if (nargs >= 0 && pronargs != nargs && !variadic && !use_defaults)
1093  continue;
1094  }
1095 
1096  /*
1097  * We must compute the effective argument list so that we can easily
1098  * compare it to earlier results. We waste a palloc cycle if it gets
1099  * masked by an earlier result, but really that's a pretty infrequent
1100  * case so it's not worth worrying about.
1101  */
1102  effective_nargs = Max(pronargs, nargs);
1103  newResult = (FuncCandidateList)
1105  effective_nargs * sizeof(Oid));
1106  newResult->pathpos = pathpos;
1107  newResult->oid = procform->oid;
1108  newResult->nargs = effective_nargs;
1109  newResult->argnumbers = argnumbers;
1110  if (argnumbers)
1111  {
1112  /* Re-order the argument types into call's logical order */
1113  Oid *proargtypes = procform->proargtypes.values;
1114  int i;
1115 
1116  for (i = 0; i < pronargs; i++)
1117  newResult->args[i] = proargtypes[argnumbers[i]];
1118  }
1119  else
1120  {
1121  /* Simple positional case, just copy proargtypes as-is */
1122  memcpy(newResult->args, procform->proargtypes.values,
1123  pronargs * sizeof(Oid));
1124  }
1125  if (variadic)
1126  {
1127  int i;
1128 
1129  newResult->nvargs = effective_nargs - pronargs + 1;
1130  /* Expand variadic argument into N copies of element type */
1131  for (i = pronargs - 1; i < effective_nargs; i++)
1132  newResult->args[i] = va_elem_type;
1133  }
1134  else
1135  newResult->nvargs = 0;
1136  newResult->ndargs = use_defaults ? pronargs - nargs : 0;
1137 
1138  /*
1139  * Does it have the same arguments as something we already accepted?
1140  * If so, decide what to do to avoid returning duplicate argument
1141  * lists. We can skip this check for the single-namespace case if no
1142  * special (named, variadic or defaults) match has been made, since
1143  * then the unique index on pg_proc guarantees all the matches have
1144  * different argument lists.
1145  */
1146  if (resultList != NULL &&
1147  (any_special || !OidIsValid(namespaceId)))
1148  {
1149  /*
1150  * If we have an ordered list from SearchSysCacheList (the normal
1151  * case), then any conflicting proc must immediately adjoin this
1152  * one in the list, so we only need to look at the newest result
1153  * item. If we have an unordered list, we have to scan the whole
1154  * result list. Also, if either the current candidate or any
1155  * previous candidate is a special match, we can't assume that
1156  * conflicts are adjacent.
1157  *
1158  * We ignore defaulted arguments in deciding what is a match.
1159  */
1160  FuncCandidateList prevResult;
1161 
1162  if (catlist->ordered && !any_special)
1163  {
1164  /* ndargs must be 0 if !any_special */
1165  if (effective_nargs == resultList->nargs &&
1166  memcmp(newResult->args,
1167  resultList->args,
1168  effective_nargs * sizeof(Oid)) == 0)
1169  prevResult = resultList;
1170  else
1171  prevResult = NULL;
1172  }
1173  else
1174  {
1175  int cmp_nargs = newResult->nargs - newResult->ndargs;
1176 
1177  for (prevResult = resultList;
1178  prevResult;
1179  prevResult = prevResult->next)
1180  {
1181  if (cmp_nargs == prevResult->nargs - prevResult->ndargs &&
1182  memcmp(newResult->args,
1183  prevResult->args,
1184  cmp_nargs * sizeof(Oid)) == 0)
1185  break;
1186  }
1187  }
1188 
1189  if (prevResult)
1190  {
1191  /*
1192  * We have a match with a previous result. Decide which one
1193  * to keep, or mark it ambiguous if we can't decide. The
1194  * logic here is preference > 0 means prefer the old result,
1195  * preference < 0 means prefer the new, preference = 0 means
1196  * ambiguous.
1197  */
1198  int preference;
1199 
1200  if (pathpos != prevResult->pathpos)
1201  {
1202  /*
1203  * Prefer the one that's earlier in the search path.
1204  */
1205  preference = pathpos - prevResult->pathpos;
1206  }
1207  else if (variadic && prevResult->nvargs == 0)
1208  {
1209  /*
1210  * With variadic functions we could have, for example,
1211  * both foo(numeric) and foo(variadic numeric[]) in the
1212  * same namespace; if so we prefer the non-variadic match
1213  * on efficiency grounds.
1214  */
1215  preference = 1;
1216  }
1217  else if (!variadic && prevResult->nvargs > 0)
1218  {
1219  preference = -1;
1220  }
1221  else
1222  {
1223  /*----------
1224  * We can't decide. This can happen with, for example,
1225  * both foo(numeric, variadic numeric[]) and
1226  * foo(variadic numeric[]) in the same namespace, or
1227  * both foo(int) and foo (int, int default something)
1228  * in the same namespace, or both foo(a int, b text)
1229  * and foo(b text, a int) in the same namespace.
1230  *----------
1231  */
1232  preference = 0;
1233  }
1234 
1235  if (preference > 0)
1236  {
1237  /* keep previous result */
1238  pfree(newResult);
1239  continue;
1240  }
1241  else if (preference < 0)
1242  {
1243  /* remove previous result from the list */
1244  if (prevResult == resultList)
1245  resultList = prevResult->next;
1246  else
1247  {
1248  FuncCandidateList prevPrevResult;
1249 
1250  for (prevPrevResult = resultList;
1251  prevPrevResult;
1252  prevPrevResult = prevPrevResult->next)
1253  {
1254  if (prevResult == prevPrevResult->next)
1255  {
1256  prevPrevResult->next = prevResult->next;
1257  break;
1258  }
1259  }
1260  Assert(prevPrevResult); /* assert we found it */
1261  }
1262  pfree(prevResult);
1263  /* fall through to add newResult to list */
1264  }
1265  else
1266  {
1267  /* mark old result as ambiguous, discard new */
1268  prevResult->oid = InvalidOid;
1269  pfree(newResult);
1270  continue;
1271  }
1272  }
1273  }
1274 
1275  /*
1276  * Okay to add it to result list
1277  */
1278  newResult->next = resultList;
1279  resultList = newResult;
1280  }
1281 
1282  ReleaseSysCacheList(catlist);
1283 
1284  return resultList;
1285 }
#define NIL
Definition: pg_list.h:65
int n_members
Definition: catcache.h:176
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
static Oid myTempNamespace
Definition: namespace.c:188
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
int16 pronargs
Definition: pg_proc.h:81
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:37
void pfree(void *pointer)
Definition: mcxt.c:1057
struct _FuncCandidateList * FuncCandidateList
#define CStringGetDatum(X)
Definition: postgres.h:578
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:210
struct _FuncCandidateList * next
Definition: namespace.h:30
#define ReleaseSysCacheList(x)
Definition: syscache.h:217
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:133
#define InvalidOid
Definition: postgres_ext.h:36
#define Max(x, y)
Definition: c.h:922
#define Assert(condition)
Definition: c.h:746
static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, int **argnumbers)
Definition: namespace.c:1305
static List * activeSearchPath
Definition: namespace.c:138
bool ordered
Definition: catcache.h:174
void * palloc(Size size)
Definition: mcxt.c:950
int i
HeapTupleData tuple
Definition: catcache.h:121
#define offsetof(type, field)
Definition: c.h:669
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1413 of file namespace.c.

References _FuncCandidateList::args, elog, ERROR, FuncnameGetCandidates(), GETSTRUCT, HeapTupleIsValid, list_make1, list_member_oid(), makeString(), NameStr, _FuncCandidateList::next, NIL, ObjectIdGetDatum, _FuncCandidateList::oid, PROCOID, proname, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1().

Referenced by format_procedure_extended(), and pg_function_is_visible().

1414 {
1415  HeapTuple proctup;
1416  Form_pg_proc procform;
1417  Oid pronamespace;
1418  bool visible;
1419 
1420  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1421  if (!HeapTupleIsValid(proctup))
1422  elog(ERROR, "cache lookup failed for function %u", funcid);
1423  procform = (Form_pg_proc) GETSTRUCT(proctup);
1424 
1426 
1427  /*
1428  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1429  * the system namespace are surely in the path and so we needn't even do
1430  * list_member_oid() for them.
1431  */
1432  pronamespace = procform->pronamespace;
1433  if (pronamespace != PG_CATALOG_NAMESPACE &&
1434  !list_member_oid(activeSearchPath, pronamespace))
1435  visible = false;
1436  else
1437  {
1438  /*
1439  * If it is in the path, it might still not be visible; it could be
1440  * hidden by another proc of the same name and arguments earlier in
1441  * the path. So we must do a slow check to see if this is the same
1442  * proc that would be found by FuncnameGetCandidates.
1443  */
1444  char *proname = NameStr(procform->proname);
1445  int nargs = procform->pronargs;
1446  FuncCandidateList clist;
1447 
1448  visible = false;
1449 
1450  clist = FuncnameGetCandidates(list_make1(makeString(proname)),
1451  nargs, NIL, false, false, false);
1452 
1453  for (; clist; clist = clist->next)
1454  {
1455  if (memcmp(clist->args, procform->proargtypes.values,
1456  nargs * sizeof(Oid)) == 0)
1457  {
1458  /* Found the expected entry; is it the right proc? */
1459  visible = (clist->oid == funcid);
1460  break;
1461  }
1462  }
1463  }
1464 
1465  ReleaseSysCache(proctup);
1466 
1467  return visible;
1468 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:65
NameData proname
Definition: pg_proc.h:35
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define list_make1(x1)
Definition: pg_list.h:206
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:37
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool missing_ok)
Definition: namespace.c:942
struct _FuncCandidateList * next
Definition: namespace.h:30
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:133
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3600 of file namespace.c.

References 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(), regcollationin(), and to_regcollation().

3601 {
3602  char *schemaname;
3603  char *collation_name;
3604  int32 dbencoding = GetDatabaseEncoding();
3605  Oid namespaceId;
3606  Oid colloid;
3607  ListCell *l;
3608 
3609  /* deconstruct the name list */
3610  DeconstructQualifiedName(name, &schemaname, &collation_name);
3611 
3612  if (schemaname)
3613  {
3614  /* use exact schema given */
3615  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3616  if (missing_ok && !OidIsValid(namespaceId))
3617  return InvalidOid;
3618 
3619  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3620  if (OidIsValid(colloid))
3621  return colloid;
3622  }
3623  else
3624  {
3625  /* search for it in search path */
3627 
3628  foreach(l, activeSearchPath)
3629  {
3630  namespaceId = lfirst_oid(l);
3631 
3632  if (namespaceId == myTempNamespace)
3633  continue; /* do not look in temp namespace */
3634 
3635  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3636  if (OidIsValid(colloid))
3637  return colloid;
3638  }
3639  }
3640 
3641  /* Not found in path */
3642  if (!missing_ok)
3643  ereport(ERROR,
3644  (errcode(ERRCODE_UNDEFINED_OBJECT),
3645  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3647  return InvalidOid;
3648 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
signed int int32
Definition: c.h:363
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1962
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3101
int GetDatabaseEncoding(void)
Definition: mbutils.c:1151
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1157
const char * name
Definition: encode.c:561
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 3654 of file namespace.c.

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

Referenced by get_object_address().

3655 {
3656  char *schemaname;
3657  char *conversion_name;
3658  Oid namespaceId;
3659  Oid conoid = InvalidOid;
3660  ListCell *l;
3661 
3662  /* deconstruct the name list */
3663  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3664 
3665  if (schemaname)
3666  {
3667  /* use exact schema given */
3668  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3669  if (missing_ok && !OidIsValid(namespaceId))
3670  conoid = InvalidOid;
3671  else
3672  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3673  PointerGetDatum(conversion_name),
3674  ObjectIdGetDatum(namespaceId));
3675  }
3676  else
3677  {
3678  /* search for it in search path */
3680 
3681  foreach(l, activeSearchPath)
3682  {
3683  namespaceId = lfirst_oid(l);
3684 
3685  if (namespaceId == myTempNamespace)
3686  continue; /* do not look in temp namespace */
3687 
3688  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3689  PointerGetDatum(conversion_name),
3690  ObjectIdGetDatum(namespaceId));
3691  if (OidIsValid(conoid))
3692  return conoid;
3693  }
3694  }
3695 
3696  /* Not found in path */
3697  if (!OidIsValid(conoid) && !missing_ok)
3698  ereport(ERROR,
3699  (errcode(ERRCODE_UNDEFINED_OBJECT),
3700  errmsg("conversion \"%s\" does not exist",
3701  NameListToString(name))));
3702  return conoid;
3703 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3101
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
const char * name
Definition: encode.c:561
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

Definition at line 3042 of file namespace.c.

References CStringGetDatum, ereport, errcode(), errmsg(), ERROR, GetSysCacheOid1, NAMESPACENAME, and OidIsValid.

Referenced by binary_upgrade_create_empty_extension(), convert_schema_name(), CreateExtensionInternal(), get_object_address_defacl(), get_object_address_unqualified(), InitTempTableNamespace(), LookupCreationNamespace(), LookupExplicitNamespace(), LookupNamespaceNoError(), objectNamesToOids(), QualifiedNameGetCreationNamespace(), RangeVarGetCreationNamespace(), recomputeNamespacePath(), regnamespacein(), ReindexMultipleTables(), RenameSchema(), SetDefaultACLsInSchemas(), and to_regnamespace().

3043 {
3044  Oid oid;
3045 
3046  oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid,
3047  CStringGetDatum(nspname));
3048  if (!OidIsValid(oid) && !missing_ok)
3049  ereport(ERROR,
3050  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3051  errmsg("schema \"%s\" does not exist", nspname)));
3052 
3053  return oid;
3054 }
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:192
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:821

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2177 of file namespace.c.

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

Referenced by AlterStatistics(), and get_object_address().

2178 {
2179  char *schemaname;
2180  char *stats_name;
2181  Oid namespaceId;
2182  Oid stats_oid = InvalidOid;
2183  ListCell *l;
2184 
2185  /* deconstruct the name list */
2186  DeconstructQualifiedName(names, &schemaname, &stats_name);
2187 
2188  if (schemaname)
2189  {
2190  /* use exact schema given */
2191  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2192  if (missing_ok && !OidIsValid(namespaceId))
2193  stats_oid = InvalidOid;
2194  else
2195  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2196  PointerGetDatum(stats_name),
2197  ObjectIdGetDatum(namespaceId));
2198  }
2199  else
2200  {
2201  /* search for it in search path */
2203 
2204  foreach(l, activeSearchPath)
2205  {
2206  namespaceId = lfirst_oid(l);
2207 
2208  if (namespaceId == myTempNamespace)
2209  continue; /* do not look in temp namespace */
2210  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2211  PointerGetDatum(stats_name),
2212  ObjectIdGetDatum(namespaceId));
2213  if (OidIsValid(stats_oid))
2214  break;
2215  }
2216  }
2217 
2218  if (!OidIsValid(stats_oid) && !missing_ok)
2219  ereport(ERROR,
2220  (errcode(ERRCODE_UNDEFINED_OBJECT),
2221  errmsg("statistics object \"%s\" does not exist",
2222  NameListToString(names))));
2223 
2224  return stats_oid;
2225 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3101
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2678 of file namespace.c.

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

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

2679 {
2680  char *schemaname;
2681  char *config_name;
2682  Oid namespaceId;
2683  Oid cfgoid = InvalidOid;
2684  ListCell *l;
2685 
2686  /* deconstruct the name list */
2687  DeconstructQualifiedName(names, &schemaname, &config_name);
2688 
2689  if (schemaname)
2690  {
2691  /* use exact schema given */
2692  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2693  if (missing_ok && !OidIsValid(namespaceId))
2694  cfgoid = InvalidOid;
2695  else
2696  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2697  PointerGetDatum(config_name),
2698  ObjectIdGetDatum(namespaceId));
2699  }
2700  else
2701  {
2702  /* search for it in search path */
2704 
2705  foreach(l, activeSearchPath)
2706  {
2707  namespaceId = lfirst_oid(l);
2708 
2709  if (namespaceId == myTempNamespace)
2710  continue; /* do not look in temp namespace */
2711 
2712  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2713  PointerGetDatum(config_name),
2714  ObjectIdGetDatum(namespaceId));
2715  if (OidIsValid(cfgoid))
2716  break;
2717  }
2718  }
2719 
2720  if (!OidIsValid(cfgoid) && !missing_ok)
2721  ereport(ERROR,
2722  (errcode(ERRCODE_UNDEFINED_OBJECT),
2723  errmsg("text search configuration \"%s\" does not exist",
2724  NameListToString(names))));
2725 
2726  return cfgoid;
2727 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3101
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2425 of file namespace.c.

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

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

2426 {
2427  char *schemaname;
2428  char *dict_name;
2429  Oid namespaceId;
2430  Oid dictoid = InvalidOid;
2431  ListCell *l;
2432 
2433  /* deconstruct the name list */
2434  DeconstructQualifiedName(names, &schemaname, &dict_name);
2435 
2436  if (schemaname)
2437  {
2438  /* use exact schema given */
2439  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2440  if (missing_ok && !OidIsValid(namespaceId))
2441  dictoid = InvalidOid;
2442  else
2443  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2444  PointerGetDatum(dict_name),
2445  ObjectIdGetDatum(namespaceId));
2446  }
2447  else
2448  {
2449  /* search for it in search path */
2451 
2452  foreach(l, activeSearchPath)
2453  {
2454  namespaceId = lfirst_oid(l);
2455 
2456  if (namespaceId == myTempNamespace)
2457  continue; /* do not look in temp namespace */
2458 
2459  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2460  PointerGetDatum(dict_name),
2461  ObjectIdGetDatum(namespaceId));
2462  if (OidIsValid(dictoid))
2463  break;
2464  }
2465  }
2466 
2467  if (!OidIsValid(dictoid) && !missing_ok)
2468  ereport(ERROR,
2469  (errcode(ERRCODE_UNDEFINED_OBJECT),
2470  errmsg("text search dictionary \"%s\" does not exist",
2471  NameListToString(names))));
2472 
2473  return dictoid;
2474 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3101
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2299 of file namespace.c.

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

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

2300 {
2301  char *schemaname;
2302  char *parser_name;
2303  Oid namespaceId;
2304  Oid prsoid = InvalidOid;
2305  ListCell *l;
2306 
2307  /* deconstruct the name list */
2308  DeconstructQualifiedName(names, &schemaname, &parser_name);
2309 
2310  if (schemaname)
2311  {
2312  /* use exact schema given */
2313  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2314  if (missing_ok && !OidIsValid(namespaceId))
2315  prsoid = InvalidOid;
2316  else
2317  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2318  PointerGetDatum(parser_name),
2319  ObjectIdGetDatum(namespaceId));
2320  }
2321  else
2322  {
2323  /* search for it in search path */
2325 
2326  foreach(l, activeSearchPath)
2327  {
2328  namespaceId = lfirst_oid(l);
2329 
2330  if (namespaceId == myTempNamespace)
2331  continue; /* do not look in temp namespace */
2332 
2333  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2334  PointerGetDatum(parser_name),
2335  ObjectIdGetDatum(namespaceId));
2336  if (OidIsValid(prsoid))
2337  break;
2338  }
2339  }
2340 
2341  if (!OidIsValid(prsoid) && !missing_ok)
2342  ereport(ERROR,
2343  (errcode(ERRCODE_UNDEFINED_OBJECT),
2344  errmsg("text search parser \"%s\" does not exist",
2345  NameListToString(names))));
2346 
2347  return prsoid;
2348 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3101
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2552 of file namespace.c.

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

Referenced by DefineTSDictionary(), and get_object_address().

2553 {
2554  char *schemaname;
2555  char *template_name;
2556  Oid namespaceId;
2557  Oid tmploid = InvalidOid;
2558  ListCell *l;
2559 
2560  /* deconstruct the name list */
2561  DeconstructQualifiedName(names, &schemaname, &template_name);
2562 
2563  if (schemaname)
2564  {
2565  /* use exact schema given */
2566  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2567  if (missing_ok && !OidIsValid(namespaceId))
2568  tmploid = InvalidOid;
2569  else
2570  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2571  PointerGetDatum(template_name),
2572  ObjectIdGetDatum(namespaceId));
2573  }
2574  else
2575  {
2576  /* search for it in search path */
2578 
2579  foreach(l, activeSearchPath)
2580  {
2581  namespaceId = lfirst_oid(l);
2582 
2583  if (namespaceId == myTempNamespace)
2584  continue; /* do not look in temp namespace */
2585 
2586  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2587  PointerGetDatum(template_name),
2588  ObjectIdGetDatum(namespaceId));
2589  if (OidIsValid(tmploid))
2590  break;
2591  }
2592  }
2593 
2594  if (!OidIsValid(tmploid) && !missing_ok)
2595  ereport(ERROR,
2596  (errcode(ERRCODE_UNDEFINED_OBJECT),
2597  errmsg("text search template \"%s\" does not exist",
2598  NameListToString(names))));
2599 
2600  return tmploid;
2601 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3101
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3359 of file namespace.c.

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

Referenced by CompleteCachedPlan(), CreateSchemaCommand(), and RevalidateCachedQuery().

3360 {
3361  OverrideSearchPath *result;
3362  List *schemas;
3363  MemoryContext oldcxt;
3364 
3366 
3367  oldcxt = MemoryContextSwitchTo(context);
3368 
3369  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3370  schemas = list_copy(activeSearchPath);
3371  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3372  {
3373  if (linitial_oid(schemas) == myTempNamespace)
3374  result->addTemp = true;
3375  else
3376  {
3377  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3378  result->addCatalog = true;
3379  }
3380  schemas = list_delete_first(schemas);
3381  }
3382  result->schemas = schemas;
3383  result->generation = activePathGeneration;
3384 
3385  MemoryContextSwitchTo(oldcxt);
3386 
3387  return result;
3388 }
static Oid myTempNamespace
Definition: namespace.c:188
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * list_copy(const List *oldlist)
Definition: list.c:1403
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
void * palloc0(Size size)
Definition: mcxt.c:981
#define Assert(condition)
Definition: c.h:746
#define linitial_oid(l)
Definition: pg_list.h:176
static List * activeSearchPath
Definition: namespace.c:138
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:860

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3273 of file namespace.c.

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

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

3274 {
3275  int result;
3276  char *nspname;
3277 
3278  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3279  nspname = get_namespace_name(namespaceId);
3280  if (!nspname)
3281  return InvalidBackendId; /* no such namespace? */
3282  if (strncmp(nspname, "pg_temp_", 8) == 0)
3283  result = atoi(nspname + 8);
3284  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3285  result = atoi(nspname + 14);
3286  else
3287  result = InvalidBackendId;
3288  pfree(nspname);
3289  return result;
3290 }
void pfree(void *pointer)
Definition: mcxt.c:1057
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3191
#define InvalidBackendId
Definition: backendid.h:23

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3312 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3313 {
3314  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3315  *tempNamespaceId = myTempNamespace;
3316  *tempToastNamespaceId = myTempToastNamespace;
3317 }
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3298 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3299 {
3301  return myTempToastNamespace;
3302 }
static Oid myTempToastNamespace
Definition: namespace.c:190
#define OidIsValid(objectId)
Definition: c.h:652
#define Assert(condition)
Definition: c.h:746

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4323 of file namespace.c.

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

Referenced by InitPostgres().

4324 {
4326  {
4327  /*
4328  * In bootstrap mode, the search path must be 'pg_catalog' so that
4329  * tables are created in the proper namespace; ignore the GUC setting.
4330  */
4331  MemoryContext oldcxt;
4332 
4334  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4335  MemoryContextSwitchTo(oldcxt);
4336  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4337  baseTempCreationPending = false;
4338  baseSearchPathValid = true;
4343  activePathGeneration++; /* pro forma */
4344  }
4345  else
4346  {
4347  /*
4348  * In normal mode, arrange for a callback on any syscache invalidation
4349  * of pg_namespace rows.
4350  */
4353  (Datum) 0);
4354  /* Force search path to be recomputed on next use */
4355  baseSearchPathValid = false;
4356  }
4357 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid GetUserId(void)
Definition: miscinit.c:476
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static Oid namespaceUser
Definition: namespace.c:157
static Oid activeCreationNamespace
Definition: namespace.c:141
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4364
static bool activeTempCreationPending
Definition: namespace.c:144
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static Oid baseCreationNamespace
Definition: namespace.c:153
static List * baseSearchPath
Definition: namespace.c:151
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1434
uintptr_t Datum
Definition: postgres.h:367
#define list_make1_oid(x1)
Definition: pg_list.h:228
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:393
static List * activeSearchPath
Definition: namespace.c:138

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3194 of file namespace.c.

References get_namespace_name(), and pfree().

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

3195 {
3196  bool result;
3197  char *nspname;
3198 
3199  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3200  nspname = get_namespace_name(namespaceId);
3201  if (!nspname)
3202  return false; /* no such namespace? */
3203  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3204  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3205  pfree(nspname);
3206  return result;
3207 }
void pfree(void *pointer)
Definition: mcxt.c:1057
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3191

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3217 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

3218 {
3219  /* If it's my own temp namespace, say "false" */
3220  if (isTempOrTempToastNamespace(namespaceId))
3221  return false;
3222  /* Else, if it's any temp namespace, say "true" */
3223  return isAnyTempNamespace(namespaceId);
3224 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3180
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3194

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3156 of file namespace.c.

References myTempNamespace, and OidIsValid.

Referenced by CreateExtensionInternal(), EventTriggerSQLDropAddObject(), ExecCheckXactReadOnly(), get_namespace_name_or_temp(), pg_namespace_aclmask(), ReindexMultipleTables(), and RemoveObjects().

3157 {
3158  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3159  return true;
3160  return false;
3161 }
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:652

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3180 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

3181 {
3182  if (OidIsValid(myTempNamespace) &&
3183  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3184  return true;
3185  return false;
3186 }
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:652

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3168 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

3169 {
3170  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3171  return true;
3172  return false;
3173 }
static Oid myTempToastNamespace
Definition: namespace.c:190
#define OidIsValid(objectId)
Definition: c.h:652

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2935 of file namespace.c.

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

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

2936 {
2937  Oid namespaceId;
2938  AclResult aclresult;
2939 
2940  /* check for pg_temp alias */
2941  if (strcmp(nspname, "pg_temp") == 0)
2942  {
2943  /* Initialize temp namespace */
2944  AccessTempTableNamespace(false);
2945  return myTempNamespace;
2946  }
2947 
2948  namespaceId = get_namespace_oid(nspname, false);
2949 
2950  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2951  if (aclresult != ACLCHECK_OK)
2952  aclcheck_error(aclresult, OBJECT_SCHEMA,
2953  nspname);
2954 
2955  return namespaceId;
2956 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3042
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3914
Oid GetUserId(void)
Definition: miscinit.c:476
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4625
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
#define ACL_CREATE
Definition: parsenodes.h:84
AclResult
Definition: acl.h:177

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2892 of file namespace.c.

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

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().

2893 {
2894  Oid namespaceId;
2895  AclResult aclresult;
2896 
2897  /* check for pg_temp alias */
2898  if (strcmp(nspname, "pg_temp") == 0)
2899  {
2901  return myTempNamespace;
2902 
2903  /*
2904  * Since this is used only for looking up existing objects, there is
2905  * no point in trying to initialize the temp namespace here; and doing
2906  * so might create problems for some callers --- just fall through.
2907  */
2908  }
2909 
2910  namespaceId = get_namespace_oid(nspname, missing_ok);
2911  if (missing_ok && !OidIsValid(namespaceId))
2912  return InvalidOid;
2913 
2914  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
2915  if (aclresult != ACLCHECK_OK)
2916  aclcheck_error(aclresult, OBJECT_SCHEMA,
2917  nspname);
2918  /* Schema search hook for this lookup */
2919  InvokeNamespaceSearchHook(namespaceId, true);
2920 
2921  return namespaceId;
2922 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3042
Oid GetUserId(void)
Definition: miscinit.c:476
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4625
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:186
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
#define ACL_USAGE
Definition: parsenodes.h:82
AclResult
Definition: acl.h:177
#define InvalidOid
Definition: postgres_ext.h:36

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2862 of file namespace.c.

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

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

2863 {
2864  /* check for pg_temp alias */
2865  if (strcmp(nspname, "pg_temp") == 0)
2866  {
2868  {
2870  return myTempNamespace;
2871  }
2872 
2873  /*
2874  * Since this is used only for looking up existing objects, there is
2875  * no point in trying to initialize the temp namespace here; and doing
2876  * so might create problems for some callers. Just report "not found".
2877  */
2878  return InvalidOid;
2879  }
2880 
2881  return get_namespace_oid(nspname, true);
2882 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3042
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:652
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:186
#define InvalidOid
Definition: postgres_ext.h:36

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 3061 of file namespace.c.

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_page_items(), bt_page_stats(), 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(), process_owned_by(), regclassin(), RelationNameGetTupleDesc(), RemoveRelations(), row_security_active_name(), schema_does_not_exist_skipping(), text_regclass(), and to_regclass().

3062 {
3063  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3064 
3065  switch (list_length(names))
3066  {
3067  case 1:
3068  rel->relname = strVal(linitial(names));
3069  break;
3070  case 2:
3071  rel->schemaname = strVal(linitial(names));
3072  rel->relname = strVal(lsecond(names));
3073  break;
3074  case 3:
3075  rel->catalogname = strVal(linitial(names));
3076  rel->schemaname = strVal(lsecond(names));
3077  rel->relname = strVal(lthird(names));
3078  break;
3079  default:
3080  ereport(ERROR,
3081  (errcode(ERRCODE_SYNTAX_ERROR),
3082  errmsg("improper relation name (too many dotted names): %s",
3083  NameListToString(names))));
3084  break;
3085  }
3086 
3087  return rel;
3088 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:610
#define lsecond(l)
Definition: pg_list.h:179
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3101
#define ereport(elevel,...)
Definition: elog.h:144
static int list_length(const List *l)
Definition: pg_list.h:149
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define lthird(l)
Definition: pg_list.h:184
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:422
char * catalogname
Definition: primnodes.h:66

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3135 of file namespace.c.

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

3136 {
3138  ListCell *l;
3139 
3140  initStringInfo(&string);
3141 
3142  foreach(l, names)
3143  {
3144  if (l != list_head(names))
3145  appendStringInfoChar(&string, '.');
3147  }
3148 
3149  return string.data;
3150 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10709
#define strVal(v)
Definition: value.h:54
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define lfirst(lc)
Definition: pg_list.h:169

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3101 of file namespace.c.

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(), CreateTrigger(), DeconstructQualifiedName(), defGetString(), DefineOperator(), DefineType(), does_not_exist_skipping(), dropOperators(), dropProcedures(), ExpandColumnRefStar(), findRangeSubOpclass(), findTypeAnalyzeFunction(), findTypeInputFunction(), findTypeOutputFunction(), findTypeReceiveFunction(), findTypeSendFunction(), 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(), RemoveObjects(), ResolveOpClass(), storeOperators(), storeProcedures(), transformColumnRef(), transformRangeTableSample(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

3102 {
3104  ListCell *l;
3105 
3106  initStringInfo(&string);
3107 
3108  foreach(l, names)
3109  {
3110  Node *name = (Node *) lfirst(l);
3111 
3112  if (l != list_head(names))
3113  appendStringInfoChar(&string, '.');
3114 
3115  if (IsA(name, String))
3116  appendStringInfoString(&string, strVal(name));
3117  else if (IsA(name, A_Star))
3118  appendStringInfoChar(&string, '*');
3119  else
3120  elog(ERROR, "unexpected node type in name list: %d",
3121  (int) nodeTag(name));
3122  }
3123 
3124  return string.data;
3125 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:579
Definition: nodes.h:528
#define strVal(v)
Definition: value.h:54
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define lfirst(lc)
Definition: pg_list.h:169
const char * name
Definition: encode.c:561
#define nodeTag(nodeptr)
Definition: nodes.h:533
#define elog(elevel,...)
Definition: elog.h:214

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1832 of file namespace.c.

References CLAOID, elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, OpclassnameGetOpcid(), recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1().

Referenced by get_opclass_name(), getObjectDescription(), and pg_opclass_is_visible().

1833 {
1834  HeapTuple opctup;
1835  Form_pg_opclass opcform;
1836  Oid opcnamespace;
1837  bool visible;
1838 
1839  opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
1840  if (!HeapTupleIsValid(opctup))
1841  elog(ERROR, "cache lookup failed for opclass %u", opcid);
1842  opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1843 
1845 
1846  /*
1847  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1848  * the system namespace are surely in the path and so we needn't even do
1849  * list_member_oid() for them.
1850  */
1851  opcnamespace = opcform->opcnamespace;
1852  if (opcnamespace != PG_CATALOG_NAMESPACE &&
1853  !list_member_oid(activeSearchPath, opcnamespace))
1854  visible = false;
1855  else
1856  {
1857  /*
1858  * If it is in the path, it might still not be visible; it could be
1859  * hidden by another opclass of the same name earlier in the path. So
1860  * we must do a slow check to see if this opclass would be found by
1861  * OpclassnameGetOpcid.
1862  */
1863  char *opcname = NameStr(opcform->opcname);
1864 
1865  visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1866  }
1867 
1868  ReleaseSysCache(opctup);
1869 
1870  return visible;
1871 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
Definition: namespace.c:1799
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1799 of file namespace.c.

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

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

1800 {
1801  Oid opcid;
1802  ListCell *l;
1803 
1805 
1806  foreach(l, activeSearchPath)
1807  {
1808  Oid namespaceId = lfirst_oid(l);
1809 
1810  if (namespaceId == myTempNamespace)
1811  continue; /* do not look in temp namespace */
1812 
1813  opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
1814  ObjectIdGetDatum(amid),
1815  PointerGetDatum(opcname),
1816  ObjectIdGetDatum(namespaceId));
1817  if (OidIsValid(opcid))
1818  return opcid;
1819  }
1820 
1821  /* Not found in path */
1822  return InvalidOid;
1823 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:196
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1746 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_make1, list_member_oid(), makeString(), NameStr, ObjectIdGetDatum, OpernameGetOprid(), OPEROID, oprid(), recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1().

Referenced by format_operator_extended(), and pg_operator_is_visible().

1747 {
1748  HeapTuple oprtup;
1749  Form_pg_operator oprform;
1750  Oid oprnamespace;
1751  bool visible;
1752 
1754  if (!HeapTupleIsValid(oprtup))
1755  elog(ERROR, "cache lookup failed for operator %u", oprid);
1756  oprform = (Form_pg_operator) GETSTRUCT(oprtup);
1757 
1759 
1760  /*
1761  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1762  * the system namespace are surely in the path and so we needn't even do
1763  * list_member_oid() for them.
1764  */
1765  oprnamespace = oprform->oprnamespace;
1766  if (oprnamespace != PG_CATALOG_NAMESPACE &&
1767  !list_member_oid(activeSearchPath, oprnamespace))
1768  visible = false;
1769  else
1770  {
1771  /*
1772  * If it is in the path, it might still not be visible; it could be
1773  * hidden by another operator of the same name and arguments earlier
1774  * in the path. So we must do a slow check to see if this is the same
1775  * operator that would be found by OpernameGetOprid.
1776  */
1777  char *oprname = NameStr(oprform->oprname);
1778 
1779  visible = (OpernameGetOprid(list_make1(makeString(oprname)),
1780  oprform->oprleft, oprform->oprright)
1781  == oprid);
1782  }
1783 
1784  ReleaseSysCache(oprtup);
1785 
1786  return visible;
1787 }
Value * makeString(char *str)
Definition: value.c:53
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid oprid(Operator op)
Definition: parse_oper.c:250
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define list_make1(x1)
Definition: pg_list.h:206
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1483
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623

◆ OpernameGetCandidates()

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

Definition at line 1586 of file namespace.c.

References _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::nvargs, _FuncCandidateList::oid, OidIsValid, OPERNAMENSP, catclist::ordered, palloc(), _FuncCandidateList::pathpos, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, SPACE_PER_OP, and catctup::tuple.

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

1587 {
1588  FuncCandidateList resultList = NULL;
1589  char *resultSpace = NULL;
1590  int nextResult = 0;
1591  char *schemaname;
1592  char *opername;
1593  Oid namespaceId;
1594  CatCList *catlist;
1595  int i;
1596 
1597  /* deconstruct the name list */
1598  DeconstructQualifiedName(names, &schemaname, &opername);
1599 
1600  if (schemaname)
1601  {
1602  /* use exact schema given */
1603  namespaceId = LookupExplicitNamespace(schemaname, missing_schema_ok);
1604  if (missing_schema_ok && !OidIsValid(namespaceId))
1605  return NULL;
1606  }
1607  else
1608  {
1609  /* flag to indicate we need namespace search */
1610  namespaceId = InvalidOid;
1612  }
1613 
1614  /* Search syscache by name only */
1615  catlist = SearchSysCacheList1(OPERNAMENSP, CStringGetDatum(opername));
1616 
1617  /*
1618  * In typical scenarios, most if not all of the operators found by the
1619  * catcache search will end up getting returned; and there can be quite a
1620  * few, for common operator names such as '=' or '+'. To reduce the time
1621  * spent in palloc, we allocate the result space as an array large enough
1622  * to hold all the operators. The original coding of this routine did a
1623  * separate palloc for each operator, but profiling revealed that the
1624  * pallocs used an unreasonably large fraction of parsing time.
1625  */
1626 #define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
1627  2 * sizeof(Oid))
1628 
1629  if (catlist->n_members > 0)
1630  resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
1631 
1632  for (i = 0; i < catlist->n_members; i++)
1633  {
1634  HeapTuple opertup = &catlist->members[i]->tuple;
1635  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1636  int pathpos = 0;
1637  FuncCandidateList newResult;
1638 
1639  /* Ignore operators of wrong kind, if specific kind requested */
1640  if (oprkind && operform->oprkind != oprkind)
1641  continue;
1642 
1643  if (OidIsValid(namespaceId))
1644  {
1645  /* Consider only opers in specified namespace */
1646  if (operform->oprnamespace != namespaceId)
1647  continue;
1648  /* No need to check args, they must all be different */
1649  }
1650  else
1651  {
1652  /*
1653  * Consider only opers that are in the search path and are not in
1654  * the temp namespace.
1655  */
1656  ListCell *nsp;
1657 
1658  foreach(nsp, activeSearchPath)
1659  {
1660  if (operform->oprnamespace == lfirst_oid(nsp) &&
1661  operform->oprnamespace != myTempNamespace)
1662  break;
1663  pathpos++;
1664  }
1665  if (nsp == NULL)
1666  continue; /* oper is not in search path */
1667 
1668  /*
1669  * Okay, it's in the search path, but does it have the same
1670  * arguments as something we already accepted? If so, keep only
1671  * the one that appears earlier in the search path.
1672  *
1673  * If we have an ordered list from SearchSysCacheList (the normal
1674  * case), then any conflicting oper must immediately adjoin this
1675  * one in the list, so we only need to look at the newest result
1676  * item. If we have an unordered list, we have to scan the whole
1677  * result list.
1678  */
1679  if (resultList)
1680  {
1681  FuncCandidateList prevResult;
1682 
1683  if (catlist->ordered)
1684  {
1685  if (operform->oprleft == resultList->args[0] &&
1686  operform->oprright == resultList->args[1])
1687  prevResult = resultList;
1688  else
1689  prevResult = NULL;
1690  }
1691  else
1692  {
1693  for (prevResult = resultList;
1694  prevResult;
1695  prevResult = prevResult->next)
1696  {
1697  if (operform->oprleft == prevResult->args[0] &&
1698  operform->oprright == prevResult->args[1])
1699  break;
1700  }
1701  }
1702  if (prevResult)
1703  {
1704  /* We have a match with a previous result */
1705  Assert(pathpos != prevResult->pathpos);
1706  if (pathpos > prevResult->pathpos)
1707  continue; /* keep previous result */
1708  /* replace previous result */
1709  prevResult->pathpos = pathpos;
1710  prevResult->oid = operform->oid;
1711  continue; /* args are same, of course */
1712  }
1713  }
1714  }
1715 
1716  /*
1717  * Okay to add it to result list
1718  */
1719  newResult = (FuncCandidateList) (resultSpace + nextResult);
1720  nextResult += SPACE_PER_OP;
1721 
1722  newResult->pathpos = pathpos;
1723  newResult->oid = operform->oid;
1724  newResult->nargs = 2;
1725  newResult->nvargs = 0;
1726  newResult->ndargs = 0;
1727  newResult->argnumbers = NULL;
1728  newResult->args[0] = operform->oprleft;
1729  newResult->args[1] = operform->oprright;
1730  newResult->next = resultList;
1731  resultList = newResult;
1732  }
1733 
1734  ReleaseSysCacheList(catlist);
1735 
1736  return resultList;
1737 }
int n_members
Definition: catcache.h:176
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
static Oid myTempNamespace
Definition: namespace.c:188
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:37
struct _FuncCandidateList * FuncCandidateList
#define CStringGetDatum(X)
Definition: postgres.h:578
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:210
#define SPACE_PER_OP
struct _FuncCandidateList * next
Definition: namespace.h:30
#define ReleaseSysCacheList(x)
Definition: syscache.h:217
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:746
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
static List * activeSearchPath
Definition: namespace.c:138
bool ordered
Definition: catcache.h:174
void * palloc(Size size)
Definition: mcxt.c:950
int i
HeapTupleData tuple
Definition: catcache.h:121
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OpernameGetOprid()

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

Definition at line 1483 of file namespace.c.

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

Referenced by binary_oper_exact(), left_oper(), LookupOperName(), OperatorIsVisible(), regoperatorin(), and to_regoperator().

1484 {
1485  char *schemaname;
1486  char *opername;
1487  CatCList *catlist;
1488  ListCell *l;
1489 
1490  /* deconstruct the name list */
1491  DeconstructQualifiedName(names, &schemaname, &opername);
1492 
1493  if (schemaname)
1494  {
1495  /* search only in exact schema given */
1496  Oid namespaceId;
1497 
1498  namespaceId = LookupExplicitNamespace(schemaname, true);
1499  if (OidIsValid(namespaceId))
1500  {
1501  HeapTuple opertup;
1502 
1503  opertup = SearchSysCache4(OPERNAMENSP,
1504  CStringGetDatum(opername),
1505  ObjectIdGetDatum(oprleft),
1506  ObjectIdGetDatum(oprright),
1507  ObjectIdGetDatum(namespaceId));
1508  if (HeapTupleIsValid(opertup))
1509  {
1510  Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup);
1511  Oid result = operclass->oid;
1512 
1513  ReleaseSysCache(opertup);
1514  return result;
1515  }
1516  }
1517 
1518  return InvalidOid;
1519  }
1520 
1521  /* Search syscache by name and argument types */
1522  catlist = SearchSysCacheList3(OPERNAMENSP,
1523  CStringGetDatum(opername),
1524  ObjectIdGetDatum(oprleft),
1525  ObjectIdGetDatum(oprright));
1526 
1527  if (catlist->n_members == 0)
1528  {
1529  /* no hope, fall out early */
1530  ReleaseSysCacheList(catlist);
1531  return InvalidOid;
1532  }
1533 
1534  /*
1535  * We have to find the list member that is first in the search path, if
1536  * there's more than one. This doubly-nested loop looks ugly, but in
1537  * practice there should usually be few catlist members.
1538  */
1540 
1541  foreach(l, activeSearchPath)
1542  {
1543  Oid namespaceId = lfirst_oid(l);
1544  int i;
1545 
1546  if (namespaceId == myTempNamespace)
1547  continue; /* do not look in temp namespace */
1548 
1549  for (i = 0; i < catlist->n_members; i++)
1550  {
1551  HeapTuple opertup = &catlist->members[i]->tuple;
1552  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1553 
1554  if (operform->oprnamespace == namespaceId)
1555  {
1556  Oid result = operform->oid;
1557 
1558  ReleaseSysCacheList(catlist);
1559  return result;
1560  }
1561  }
1562  }
1563 
1564  ReleaseSysCacheList(catlist);
1565  return InvalidOid;
1566 }
int n_members
Definition: catcache.h:176
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
static Oid myTempNamespace
Definition: namespace.c:188
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define CStringGetDatum(X)
Definition: postgres.h:578
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1149
#define ReleaseSysCacheList(x)
Definition: syscache.h:217
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
static List * activeSearchPath
Definition: namespace.c:138
#define SearchSysCacheList3(cacheId, key1, key2, key3)
Definition: syscache.h:214
int i
HeapTupleData tuple
Definition: catcache.h:121
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1915 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, OpfamilynameGetOpfid(), OPFAMILYOID, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1().

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

1916 {
1917  HeapTuple opftup;
1918  Form_pg_opfamily opfform;
1919  Oid opfnamespace;
1920  bool visible;
1921 
1922  opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
1923  if (!HeapTupleIsValid(opftup))
1924  elog(ERROR, "cache lookup failed for opfamily %u", opfid);
1925  opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
1926 
1928 
1929  /*
1930  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1931  * the system namespace are surely in the path and so we needn't even do
1932  * list_member_oid() for them.
1933  */
1934  opfnamespace = opfform->opfnamespace;
1935  if (opfnamespace != PG_CATALOG_NAMESPACE &&
1936  !list_member_oid(activeSearchPath, opfnamespace))
1937  visible = false;
1938  else
1939  {
1940  /*
1941  * If it is in the path, it might still not be visible; it could be
1942  * hidden by another opfamily of the same name earlier in the path. So
1943  * we must do a slow check to see if this opfamily would be found by
1944  * OpfamilynameGetOpfid.
1945  */
1946  char *opfname = NameStr(opfform->opfname);
1947 
1948  visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
1949  }
1950 
1951  ReleaseSysCache(opftup);
1952 
1953  return visible;
1954 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
Definition: namespace.c:1882
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1882 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

1883 {
1884  Oid opfid;
1885  ListCell *l;
1886 
1888 
1889  foreach(l, activeSearchPath)
1890  {
1891  Oid namespaceId = lfirst_oid(l);
1892 
1893  if (namespaceId == myTempNamespace)
1894  continue; /* do not look in temp namespace */
1895 
1896  opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
1897  ObjectIdGetDatum(amid),
1898  PointerGetDatum(opfname),
1899  ObjectIdGetDatum(namespaceId));
1900  if (OidIsValid(opfid))
1901  return opfid;
1902  }
1903 
1904  /* Not found in path */
1905  return InvalidOid;
1906 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:196
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3418 of file namespace.c.

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

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

3419 {
3420  ListCell *lc,
3421  *lcp;
3422 
3424 
3425  /* Quick out if already known equal to active path. */
3426  if (path->generation == activePathGeneration)
3427  return true;
3428 
3429  /* We scan down the activeSearchPath to see if it matches the input. */
3431 
3432  /* If path->addTemp, first item should be my temp namespace. */
3433  if (path->addTemp)
3434  {
3435  if (lc && lfirst_oid(lc) == myTempNamespace)
3436  lc = lnext(activeSearchPath, lc);
3437  else
3438  return false;
3439  }
3440  /* If path->addCatalog, next item should be pg_catalog. */
3441  if (path->addCatalog)
3442  {
3443  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3444  lc = lnext(activeSearchPath, lc);
3445  else
3446  return false;
3447  }
3448  /* We should now be looking at the activeCreationNamespace. */
3449  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3450  return false;
3451  /* The remainder of activeSearchPath should match path->schemas. */
3452  foreach(lcp, path->schemas)
3453  {
3454  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3455  lc = lnext(activeSearchPath, lc);
3456  else
3457  return false;
3458  }
3459  if (lc)
3460  return false;
3461 
3462  /*
3463  * Update path->generation so that future tests will return quickly, so
3464  * long as the active search path doesn't change.
3465  */
3467 
3468  return true;
3469 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:310
static Oid myTempNamespace
Definition: namespace.c:188
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3556 of file namespace.c.

References activeCreationNamespace, activePathGeneration, activeTempCreationPending, baseCreationNamespace, baseSearchPath, baseTempCreationPending, OverrideStackEntry::creationNamespace, elog, ERROR, GetCurrentTransactionNestLevel(), linitial, list_delete_first(), list_free(), OverrideStackEntry::nestLevel, NIL, pfree(), and OverrideStackEntry::searchPath.

Referenced by CreateSchemaCommand().

3557 {
3558  OverrideStackEntry *entry;
3559 
3560  /* Sanity checks. */
3561  if (overrideStack == NIL)
3562  elog(ERROR, "bogus PopOverrideSearchPath call");
3564  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3565  elog(ERROR, "bogus PopOverrideSearchPath call");
3566 
3567  /* Pop the stack and free storage. */
3569  list_free(entry->searchPath);
3570  pfree(entry);
3571 
3572  /* Activate the next level down. */
3573  if (overrideStack)
3574  {
3576  activeSearchPath = entry->searchPath;
3578  activeTempCreationPending = false; /* XXX is this OK? */
3579  }
3580  else
3581  {
3582  /* If not baseSearchPathValid, this is useless but harmless */
3586  }
3587 
3588  /* As above, the generation always increments. */
3590 }
#define NIL
Definition: pg_list.h:65
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1057
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:43
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
static List * baseSearchPath
Definition: namespace.c:151
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1376
#define elog(elevel,...)
Definition: elog.h:214
List * list_delete_first(List *list)
Definition: list.c:860

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3489 of file namespace.c.

References activeCreationNamespace, activePathGeneration, activeTempCreationPending, OverrideSearchPath::addCatalog, OverrideSearchPath::addTemp, OverrideStackEntry::creationNamespace, GetCurrentTransactionNestLevel(), InvalidOid, lcons(), lcons_oid(), linitial_oid, list_copy(), MemoryContextSwitchTo(), myTempNamespace, OverrideStackEntry::nestLevel, NIL, OidIsValid, palloc(), OverrideSearchPath::schemas, OverrideStackEntry::searchPath, and TopMemoryContext.

Referenced by CreateSchemaCommand().

3490 {
3491  OverrideStackEntry *entry;
3492  List *oidlist;
3493  Oid firstNS;
3494  MemoryContext oldcxt;
3495 
3496  /*
3497  * Copy the list for safekeeping, and insert implicitly-searched
3498  * namespaces as needed. This code should track recomputeNamespacePath.
3499  */
3501 
3502  oidlist = list_copy(newpath->schemas);
3503 
3504  /*
3505  * Remember the first member of the explicit list.
3506  */
3507  if (oidlist == NIL)
3508  firstNS = InvalidOid;
3509  else
3510  firstNS = linitial_oid(oidlist);
3511 
3512  /*
3513  * Add any implicitly-searched namespaces to the list. Note these go on
3514  * the front, not the back; also notice that we do not check USAGE
3515  * permissions for these.
3516  */
3517  if (newpath->addCatalog)
3518  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3519 
3520  if (newpath->addTemp && OidIsValid(myTempNamespace))
3521  oidlist = lcons_oid(myTempNamespace, oidlist);
3522 
3523  /*
3524  * Build the new stack entry, then insert it at the head of the list.
3525  */
3526  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3527  entry->searchPath = oidlist;
3528  entry->creationNamespace = firstNS;
3530 
3531  overrideStack = lcons(entry, overrideStack);
3532 
3533  /* And make it active. */
3534  activeSearchPath = entry->searchPath;
3536  activeTempCreationPending = false; /* XXX is this OK? */
3537 
3538  /*
3539  * We always increment activePathGeneration when pushing/popping an
3540  * override path. In current usage, these actions always change the
3541  * effective path state, so there's no value in checking to see if it
3542  * didn't change.
3543  */
3545 
3546  MemoryContextSwitchTo(oldcxt);
3547 }
#define NIL
Definition: pg_list.h:65
static Oid myTempNamespace
Definition: namespace.c:188
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static List * overrideStack
Definition: namespace.c:171
List * list_copy(const List *oldlist)
Definition: list.c:1403
List * lcons_oid(Oid datum, List *list)
Definition: list.c:489
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:144
MemoryContext TopMemoryContext
Definition: mcxt.c:44
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
List * lcons(void *datum, List *list)
Definition: list.c:453
#define linitial_oid(l)
Definition: pg_list.h:176
static List * activeSearchPath
Definition: namespace.c:138
void * palloc(Size size)
Definition: mcxt.c:950
Definition: pg_list.h:50

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 2994 of file namespace.c.

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().

2995 {
2996  char *schemaname;
2997  Oid namespaceId;
2998 
2999  /* deconstruct the name list */
3000  DeconstructQualifiedName(names, &schemaname, objname_p);
3001 
3002  if (schemaname)
3003  {
3004  /* check for pg_temp alias */
3005  if (strcmp(schemaname, "pg_temp") == 0)
3006  {
3007  /* Initialize temp namespace */
3008  AccessTempTableNamespace(false);
3009  return myTempNamespace;
3010  }
3011  /* use exact schema given */
3012  namespaceId = get_namespace_oid(schemaname, false);
3013  /* we do not check for USAGE rights here! */
3014  }
3015  else
3016  {
3017  /* use the default creation namespace */
3020  {
3021  /* Need to initialize temp namespace */
3023  return myTempNamespace;
3024  }
3025  namespaceId = activeCreationNamespace;
3026  if (!OidIsValid(namespaceId))
3027  ereport(ERROR,
3028  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3029  errmsg("no schema has been selected to create in")));
3030  }
3031 
3032  return namespaceId;
3033 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3042
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3914
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2808
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
static Oid activeCreationNamespace
Definition: namespace.c:141
#define ERROR
Definition: elog.h:43
static bool activeTempCreationPending
Definition: namespace.c:144
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:821

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 641 of file namespace.c.

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

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

642 {
643  switch (newRelation->relpersistence)
644  {
645  case RELPERSISTENCE_TEMP:
646  if (!isTempOrTempToastNamespace(nspid))
647  {
648  if (isAnyTempNamespace(nspid))
649  ereport(ERROR,
650  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
651  errmsg("cannot create relations in temporary schemas of other sessions")));
652  else
653  ereport(ERROR,
654  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
655  errmsg("cannot create temporary relation in non-temporary schema")));
656  }
657  break;
658  case RELPERSISTENCE_PERMANENT:
659  if (isTempOrTempToastNamespace(nspid))
660  newRelation->relpersistence = RELPERSISTENCE_TEMP;
661  else if (isAnyTempNamespace(nspid))
662  ereport(ERROR,
663  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
664  errmsg("cannot create relations in temporary schemas of other sessions")));
665  break;
666  default:
667  if (isAnyTempNamespace(nspid))
668  ereport(ERROR,
669  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
670  errmsg("only temporary relations may be created in temporary schemas")));
671  }
672 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3180
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:821
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3194

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 534 of file namespace.c.

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, OBJECT_SCHEMA, OidIsValid, pg_class_ownercheck(), pg_namespace_aclcheck(), RangeVarAdjustRelationPersistence(), RangeVarGetCreationNamespace(), RangeVar::relname, RangeVar::schemaname, SharedInvalidMessageCounter, UnlockDatabaseObject(), and UnlockRelationOid().

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

537 {
538  uint64 inval_count;
539  Oid relid;
540  Oid oldrelid = InvalidOid;
541  Oid nspid;
542  Oid oldnspid = InvalidOid;
543  bool retry = false;
544 
545  /*
546  * We check the catalog name and then ignore it.
547  */
548  if (relation->catalogname)
549  {
550  if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
551  ereport(ERROR,
552  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
553  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
554  relation->catalogname, relation->schemaname,
555  relation->relname)));
556  }
557 
558  /*
559  * As in RangeVarGetRelidExtended(), we guard against concurrent DDL
560  * operations by tracking whether any invalidation messages are processed
561  * while we're doing the name lookups and acquiring locks. See comments
562  * in that function for a more detailed explanation of this logic.
563  */
564  for (;;)
565  {
566  AclResult aclresult;
567 
568  inval_count = SharedInvalidMessageCounter;
569 
570  /* Look up creation namespace and check for existing relation. */
571  nspid = RangeVarGetCreationNamespace(relation);
572  Assert(OidIsValid(nspid));
573  if (existing_relation_id != NULL)
574  relid = get_relname_relid(relation->relname, nspid);
575  else
576  relid = InvalidOid;
577 
578  /*
579  * In bootstrap processing mode, we don't bother with permissions or
580  * locking. Permissions might not be working yet, and locking is
581  * unnecessary.
582  */
584  break;
585 
586  /* Check namespace permissions. */
587  aclresult = pg_namespace_aclcheck(nspid, GetUserId(), ACL_CREATE);
588  if (aclresult != ACLCHECK_OK)
589  aclcheck_error(aclresult, OBJECT_SCHEMA,
590  get_namespace_name(nspid));
591 
592  if (retry)
593  {
594  /* If nothing changed, we're done. */
595  if (relid == oldrelid && nspid == oldnspid)
596  break;
597  /* If creation namespace has changed, give up old lock. */
598  if (nspid != oldnspid)
599  UnlockDatabaseObject(NamespaceRelationId, oldnspid, 0,
601  /* If name points to something different, give up old lock. */
602  if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock)
603  UnlockRelationOid(oldrelid, lockmode);
604  }
605 
606  /* Lock namespace. */
607  if (nspid != oldnspid)
608  LockDatabaseObject(NamespaceRelationId, nspid, 0, AccessShareLock);
609 
610  /* Lock relation, if required if and we have permission. */
611  if (lockmode != NoLock && OidIsValid(relid))
612  {
613  if (!pg_class_ownercheck(relid, GetUserId()))
615  relation->relname);
616  if (relid != oldrelid)
617  LockRelationOid(relid, lockmode);
618  }
619 
620  /* If no invalidation message were processed, we're done! */
621  if (inval_count == SharedInvalidMessageCounter)
622  break;
623 
624  /* Something may have changed, so recheck our work. */
625  retry = true;
626  oldrelid = relid;
627  oldnspid = nspid;
628  }
629 
630  RangeVarAdjustRelationPersistence(relation, nspid);
631  if (existing_relation_id != NULL)
632  *existing_relation_id = relid;
633  return nspid;
634 }
Oid GetUserId(void)
Definition: miscinit.c:476
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:199
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1915
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4625
void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
Definition: namespace.c:641
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:84
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1797
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3191
#define NoLock
Definition: lockdefs.h:34
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:976
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:997
AclResult
Definition: acl.h:177
Oid MyDatabaseId
Definition: globals.c:85
uint64 SharedInvalidMessageCounter
Definition: sinval.c:26
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:746
bool pg_class_ownercheck(Oid class_oid, Oid roleid)
Definition: aclchk.c:4687
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:393
int errmsg(const char *fmt,...)
Definition: elog.c:821
ObjectType get_relkind_objtype(char relkind)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:108
Oid RangeVarGetCreationNamespace(const RangeVar *newRelation)
Definition: namespace.c:449

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 449 of file namespace.c.

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 ExecCreateTableAs(), generateSerialExtraStmts(), and RangeVarGetAndCheckCreationNamespace().

450 {
451  Oid namespaceId;
452 
453  /*
454  * We check the catalog name and then ignore it.
455  */
456  if (newRelation->catalogname)
457  {
458  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
459  ereport(ERROR,
460  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
461  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
462  newRelation->catalogname, newRelation->schemaname,
463  newRelation->relname)));
464  }
465 
466  if (newRelation->schemaname)
467  {
468  /* check for pg_temp alias */
469  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
470  {
471  /* Initialize temp namespace */
473  return myTempNamespace;
474  }
475  /* use exact schema given */
476  namespaceId = get_namespace_oid(newRelation->schemaname, false);
477  /* we do not check for USAGE rights here! */
478  }
479  else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
480  {
481  /* Initialize temp namespace */
483  return myTempNamespace;
484  }
485  else
486  {
487  /* use the default creation namespace */
490  {
491  /* Need to initialize temp namespace */
493  return myTempNamespace;
494  }
495  namespaceId = activeCreationNamespace;
496  if (!OidIsValid(namespaceId))
497  ereport(ERROR,
498  (errcode(ERRCODE_UNDEFINED_SCHEMA),
499  errmsg("no schema has been selected to create in")));
500  }
501 
502  /* Note: callers will check for CREATE rights when appropriate */
503 
504  return namespaceId;
505 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3042
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3914
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
static Oid activeCreationNamespace
Definition: namespace.c:141
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
static bool activeTempCreationPending
Definition: namespace.c:144
Oid MyDatabaseId
Definition: globals.c:85
#define ereport(elevel,...)
Definition: elog.h:144
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:821
char * catalogname
Definition: primnodes.h:66

◆ RangeVarGetRelidExtended()

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

Definition at line 236 of file namespace.c.

References AcceptInvalidationMessages(), Assert, callback(), RangeVar::catalogname, ConditionalLockRelationOid(), DEBUG1, elevel, 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().

239 {
240  uint64 inval_count;
241  Oid relId;
242  Oid oldRelId = InvalidOid;
243  bool retry = false;
244  bool missing_ok = (flags & RVR_MISSING_OK) != 0;
245 
246  /* verify that flags do no conflict */
247  Assert(!((flags & RVR_NOWAIT) && (flags & RVR_SKIP_LOCKED)));
248 
249  /*
250  * We check the catalog name and then ignore it.
251  */
252  if (relation->catalogname)
253  {
254  if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
255  ereport(ERROR,
256  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
257  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
258  relation->catalogname, relation->schemaname,
259  relation->relname)));
260  }
261 
262  /*
263  * DDL operations can change the results of a name lookup. Since all such
264  * operations will generate invalidation messages, we keep track of
265  * whether any such messages show up while we're performing the operation,
266  * and retry until either (1) no more invalidation messages show up or (2)
267  * the answer doesn't change.
268  *
269  * But if lockmode = NoLock, then we assume that either the caller is OK
270  * with the answer changing under them, or that they already hold some
271  * appropriate lock, and therefore return the first answer we get without
272  * checking for invalidation messages. Also, if the requested lock is
273  * already held, LockRelationOid will not AcceptInvalidationMessages, so
274  * we may fail to notice a change. We could protect against that case by
275  * calling AcceptInvalidationMessages() before beginning this loop, but
276  * that would add a significant amount overhead, so for now we don't.
277  */
278  for (;;)
279  {
280  /*
281  * Remember this value, so that, after looking up the relation name
282  * and locking its OID, we can check whether any invalidation messages
283  * have been processed that might require a do-over.
284  */
285  inval_count = SharedInvalidMessageCounter;
286 
287  /*
288  * Some non-default relpersistence value may have been specified. The
289  * parser never generates such a RangeVar in simple DML, but it can
290  * happen in contexts such as "CREATE TEMP TABLE foo (f1 int PRIMARY
291  * KEY)". Such a command will generate an added CREATE INDEX
292  * operation, which must be careful to find the temp table, even when
293  * pg_temp is not first in the search path.
294  */
295  if (relation->relpersistence == RELPERSISTENCE_TEMP)
296  {
298  relId = InvalidOid; /* this probably can't happen? */
299  else
300  {
301  if (relation->schemaname)
302  {
303  Oid namespaceId;
304 
305  namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
306 
307  /*
308  * For missing_ok, allow a non-existent schema name to
309  * return InvalidOid.
310  */
311  if (namespaceId != myTempNamespace)
312  ereport(ERROR,
313  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
314  errmsg("temporary tables cannot specify a schema name")));
315  }
316 
317  relId = get_relname_relid(relation->relname, myTempNamespace);
318  }
319  }
320  else if (relation->schemaname)
321  {
322  Oid namespaceId;
323 
324  /* use exact schema given */
325  namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
326  if (missing_ok && !OidIsValid(namespaceId))
327  relId = InvalidOid;
328  else
329  relId = get_relname_relid(relation->relname, namespaceId);
330  }
331  else
332  {
333  /* search the namespace path */
334  relId = RelnameGetRelid(relation->relname);
335  }
336 
337  /*
338  * Invoke caller-supplied callback, if any.
339  *
340  * This callback is a good place to check permissions: we haven't
341  * taken the table lock yet (and it's really best to check permissions
342  * before locking anything!), but we've gotten far enough to know what
343  * OID we think we should lock. Of course, concurrent DDL might
344  * change things while we're waiting for the lock, but in that case
345  * the callback will be invoked again for the new OID.
346  */
347  if (callback)
348  callback(relation, relId, oldRelId, callback_arg);
349 
350  /*
351  * If no lock requested, we assume the caller knows what they're
352  * doing. They should have already acquired a heavyweight lock on
353  * this relation earlier in the processing of this same statement, so
354  * it wouldn't be appropriate to AcceptInvalidationMessages() here, as
355  * that might pull the rug out from under them.
356  */
357  if (lockmode == NoLock)
358  break;
359 
360  /*
361  * If, upon retry, we get back the same OID we did last time, then the
362  * invalidation messages we processed did not change the final answer.
363  * So we're done.
364  *
365  * If we got a different OID, we've locked the relation that used to
366  * have this name rather than the one that does now. So release the
367  * lock.
368  */
369  if (retry)
370  {
371  if (relId == oldRelId)
372  break;
373  if (OidIsValid(oldRelId))
374  UnlockRelationOid(oldRelId, lockmode);
375  }
376 
377  /*
378  * Lock relation. This will also accept any pending invalidation
379  * messages. If we got back InvalidOid, indicating not found, then
380  * there's nothing to lock, but we accept invalidation messages
381  * anyway, to flush any negative catcache entries that may be
382  * lingering.
383  */
384  if (!OidIsValid(relId))
386  else if (!(flags & (RVR_NOWAIT | RVR_SKIP_LOCKED)))
387  LockRelationOid(relId, lockmode);
388  else if (!ConditionalLockRelationOid(relId, lockmode))
389  {
390  int elevel = (flags & RVR_SKIP_LOCKED) ? DEBUG1 : ERROR;
391 
392  if (relation->schemaname)
393  ereport(elevel,
394  (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
395  errmsg("could not obtain lock on relation \"%s.%s\"",
396  relation->schemaname, relation->relname)));
397  else
398  ereport(elevel,
399  (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
400  errmsg("could not obtain lock on relation \"%s\"",
401  relation->relname)));
402 
403  return InvalidOid;
404  }
405 
406  /*
407  * If no invalidation message were processed, we're done!
408  */
409  if (inval_count == SharedInvalidMessageCounter)
410  break;
411 
412  /*
413  * Something may have changed. Let's repeat the name lookup, to make
414  * sure this name still references the same relation it did
415  * previously.
416  */
417  retry = true;
418  oldRelId = relId;
419  }
420 
421  if (!OidIsValid(relId))
422  {
423  int elevel = missing_ok ? DEBUG1 : ERROR;
424 
425  if (relation->schemaname)
426  ereport(elevel,
428  errmsg("relation \"%s.%s\" does not exist",
429  relation->schemaname, relation->relname)));
430  else
431  ereport(elevel,
433  errmsg("relation \"%s\" does not exist",
434  relation->relname)));
435  }
436  return relId;
437 }
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:151
#define DEBUG1
Definition: elog.h:25
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2892
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:74
void AcceptInvalidationMessages(void)
Definition: inval.c:684
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:199
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:680
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
#define ERROR
Definition: elog.h:43
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1797
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
#define NoLock
Definition: lockdefs.h:34
static int elevel
Definition: vacuumlazy.c:333
Oid MyDatabaseId
Definition: globals.c:85
uint64 SharedInvalidMessageCounter
Definition: sinval.c:26
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:746
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:821
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:108
char * catalogname
Definition: primnodes.h:66

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 708 of file namespace.c.

References elog, ERROR, get_relname_relid(), GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), NameStr, ObjectIdGetDatum, OidIsValid, recomputeNamespacePath(), ReleaseSysCache(), relname, RELOID, and SearchSysCache1().

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

709 {
710  HeapTuple reltup;
711  Form_pg_class relform;
712  Oid relnamespace;
713  bool visible;
714 
715  reltup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
716  if (!HeapTupleIsValid(reltup))
717  elog(ERROR, "cache lookup failed for relation %u", relid);
718  relform = (Form_pg_class) GETSTRUCT(reltup);
719 
721 
722  /*
723  * Quick check: if it ain't in the path at all, it ain't visible. Items in
724  * the system namespace are surely in the path and so we needn't even do
725  * list_member_oid() for them.
726  */
727  relnamespace = relform->relnamespace;
728  if (relnamespace != PG_CATALOG_NAMESPACE &&
729  !list_member_oid(activeSearchPath, relnamespace))
730  visible = false;
731  else
732  {
733  /*
734  * If it is in the path, it might still not be visible; it could be
735  * hidden by another relation of the same name earlier in the path. So
736  * we must do a slow check for conflicting relations.
737  */
738  char *relname = NameStr(relform->relname);
739  ListCell *l;
740 
741  visible = false;
742  foreach(l, activeSearchPath)
743  {
744  Oid namespaceId = lfirst_oid(l);
745 
746  if (namespaceId == relnamespace)
747  {
748  /* Found it first in path */
749  visible = true;
750  break;
751  }
752  if (OidIsValid(get_relname_relid(relname, namespaceId)))
753  {
754  /* Found something else first in path */
755  break;
756  }
757  }
758  }
759 
760  ReleaseSysCache(reltup);
761 
762  return visible;
763 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
NameData relname
Definition: pg_class.h:38
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1797
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 680 of file namespace.c.

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

Referenced by plpgsql_parse_cwordtype(), plpgsql_parse_wordrowtype(), and RangeVarGetRelidExtended().

681 {
682  Oid relid;
683  ListCell *l;
684 
686 
687  foreach(l, activeSearchPath)
688  {
689  Oid namespaceId = lfirst_oid(l);
690 
691  relid = get_relname_relid(relname, namespaceId);
692  if (OidIsValid(relid))
693  return relid;
694  }
695 
696  /* Not found in path */
697  return InvalidOid;
698 }
NameData relname
Definition: pg_class.h:38
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1797
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4260 of file namespace.c.

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

4261 {
4264 }
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:652
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4216

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3328 of file namespace.c.

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

Referenced by ParallelWorkerMain().

3329 {
3330  /* Worker should not have created its own namespaces ... */
3334 
3335  /* Assign same namespace OIDs that leader has */
3336  myTempNamespace = tempNamespaceId;
3337  myTempToastNamespace = tempToastNamespaceId;
3338 
3339  /*
3340  * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
3341  * Even if the namespace is new so far as the leader is concerned, it's
3342  * not new to the worker, and we certainly wouldn't want the worker trying
3343  * to destroy it.
3344  */
3345 
3346  baseSearchPathValid = false; /* may need to rebuild list */
3347 }
static bool baseSearchPathValid
Definition: namespace.c:160
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:746
#define InvalidSubTransactionId
Definition: c.h:527

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  relid)

Definition at line 2234 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), NameStr, ObjectIdGetDatum, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1(), SearchSysCacheExists2, STATEXTNAMENSP, and STATEXTOID.

Referenced by getObjectDescription(), and pg_statistics_obj_is_visible().

2235 {
2236  HeapTuple stxtup;
2237  Form_pg_statistic_ext stxform;
2238  Oid stxnamespace;
2239  bool visible;
2240 
2241  stxtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(relid));
2242  if (!HeapTupleIsValid(stxtup))
2243  elog(ERROR, "cache lookup failed for statistics object %u", relid);
2244  stxform = (Form_pg_statistic_ext) GETSTRUCT(stxtup);
2245 
2247 
2248  /*
2249  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2250  * the system namespace are surely in the path and so we needn't even do
2251  * list_member_oid() for them.
2252  */
2253  stxnamespace = stxform->stxnamespace;
2254  if (stxnamespace != PG_CATALOG_NAMESPACE &&
2255  !list_member_oid(activeSearchPath, stxnamespace))
2256  visible = false;
2257  else
2258  {
2259  /*
2260  * If it is in the path, it might still not be visible; it could be
2261  * hidden by another statistics object of the same name earlier in the
2262  * path. So we must do a slow check for conflicting objects.
2263  */
2264  char *stxname = NameStr(stxform->stxname);
2265  ListCell *l;
2266 
2267  visible = false;
2268  foreach(l, activeSearchPath)
2269  {
2270  Oid namespaceId = lfirst_oid(l);
2271 
2272  if (namespaceId == stxnamespace)
2273  {
2274  /* Found it first in path */
2275  visible = true;
2276  break;
2277  }
2279  PointerGetDatum(stxname),
2280  ObjectIdGetDatum(namespaceId)))
2281  {
2282  /* Found something else first in path */
2283  break;
2284  }
2285  }
2286  }
2287 
2288  ReleaseSysCache(stxtup);
2289 
2290  return visible;
2291 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define PointerGetDatum(X)
Definition: postgres.h:556
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:185
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623
FormData_pg_statistic_ext * Form_pg_statistic_ext
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 2736 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1(), SearchSysCacheExists2, TSCONFIGNAMENSP, and TSCONFIGOID.

Referenced by getObjectDescription(), pg_ts_config_is_visible(), and regconfigout().

2737 {
2738  HeapTuple tup;
2739  Form_pg_ts_config form;
2740  Oid namespace;
2741  bool visible;
2742 
2744  if (!HeapTupleIsValid(tup))
2745  elog(ERROR, "cache lookup failed for text search configuration %u",
2746  cfgid);
2747  form = (Form_pg_ts_config) GETSTRUCT(tup);
2748 
2750 
2751  /*
2752  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2753  * the system namespace are surely in the path and so we needn't even do
2754  * list_member_oid() for them.
2755  */
2756  namespace = form->cfgnamespace;
2757  if (namespace != PG_CATALOG_NAMESPACE &&
2758  !list_member_oid(activeSearchPath, namespace))
2759  visible = false;
2760  else
2761  {
2762  /*
2763  * If it is in the path, it might still not be visible; it could be
2764  * hidden by another configuration of the same name earlier in the
2765  * path. So we must do a slow check for conflicting configurations.
2766  */
2767  char *name = NameStr(form->cfgname);
2768  ListCell *l;
2769 
2770  visible = false;
2771  foreach(l, activeSearchPath)
2772  {
2773  Oid namespaceId = lfirst_oid(l);
2774 
2775  if (namespaceId == myTempNamespace)
2776  continue; /* do not look in temp namespace */
2777 
2778  if (namespaceId == namespace)
2779  {
2780  /* Found it first in path */
2781  visible = true;
2782  break;
2783  }
2785  PointerGetDatum(name),
2786  ObjectIdGetDatum(namespaceId)))
2787  {
2788  /* Found something else first in path */
2789  break;
2790  }
2791  }
2792  }
2793 
2794  ReleaseSysCache(tup);
2795 
2796  return visible;
2797 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:185
const char * name
Definition: encode.c:561
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2483 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1(), SearchSysCacheExists2, TSDICTNAMENSP, and TSDICTOID.

Referenced by getObjectDescription(), pg_ts_dict_is_visible(), and regdictionaryout().

2484 {
2485  HeapTuple tup;
2486  Form_pg_ts_dict form;
2487  Oid namespace;
2488  bool visible;
2489 
2490  tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
2491  if (!HeapTupleIsValid(tup))
2492  elog(ERROR, "cache lookup failed for text search dictionary %u",
2493  dictId);
2494  form = (Form_pg_ts_dict) GETSTRUCT(tup);
2495 
2497 
2498  /*
2499  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2500  * the system namespace are surely in the path and so we needn't even do
2501  * list_member_oid() for them.
2502  */
2503  namespace = form->dictnamespace;
2504  if (namespace != PG_CATALOG_NAMESPACE &&
2505  !list_member_oid(activeSearchPath, namespace))
2506  visible = false;
2507  else
2508  {
2509  /*
2510  * If it is in the path, it might still not be visible; it could be
2511  * hidden by another dictionary of the same name earlier in the path.
2512  * So we must do a slow check for conflicting dictionaries.
2513  */
2514  char *name = NameStr(form->dictname);
2515  ListCell *l;
2516 
2517  visible = false;
2518  foreach(l, activeSearchPath)
2519  {
2520  Oid namespaceId = lfirst_oid(l);
2521 
2522  if (namespaceId == myTempNamespace)
2523  continue; /* do not look in temp namespace */
2524 
2525  if (namespaceId == namespace)
2526  {
2527  /* Found it first in path */
2528  visible = true;
2529  break;
2530  }
2532  PointerGetDatum(name),
2533  ObjectIdGetDatum(namespaceId)))
2534  {
2535  /* Found something else first in path */
2536  break;
2537  }
2538  }
2539  }
2540 
2541  ReleaseSysCache(tup);
2542 
2543  return visible;
2544 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:52
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:185
const char * name
Definition: encode.c:561
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2357 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1(), SearchSysCacheExists2, TSPARSERNAMENSP, and TSPARSEROID.

Referenced by getObjectDescription(), and pg_ts_parser_is_visible().

2358 {
2359  HeapTuple tup;
2360  Form_pg_ts_parser form;
2361  Oid namespace;
2362  bool visible;
2363 
2365  if (!HeapTupleIsValid(tup))
2366  elog(ERROR, "cache lookup failed for text search parser %u", prsId);
2367  form = (Form_pg_ts_parser) GETSTRUCT(tup);
2368 
2370 
2371  /*
2372  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2373  * the system namespace are surely in the path and so we needn't even do
2374  * list_member_oid() for them.
2375  */
2376  namespace = form->prsnamespace;
2377  if (namespace != PG_CATALOG_NAMESPACE &&
2378  !list_member_oid(activeSearchPath, namespace))
2379  visible = false;
2380  else
2381  {
2382  /*
2383  * If it is in the path, it might still not be visible; it could be
2384  * hidden by another parser of the same name earlier in the path. So
2385  * we must do a slow check for conflicting parsers.
2386  */
2387  char *name = NameStr(form->prsname);
2388  ListCell *l;
2389 
2390  visible = false;
2391  foreach(l, activeSearchPath)
2392  {
2393  Oid namespaceId = lfirst_oid(l);
2394 
2395  if (namespaceId == myTempNamespace)
2396  continue; /* do not look in temp namespace */
2397 
2398  if (namespaceId == namespace)
2399  {
2400  /* Found it first in path */
2401  visible = true;
2402  break;
2403  }
2405  PointerGetDatum(name),
2406  ObjectIdGetDatum(namespaceId)))
2407  {
2408  /* Found something else first in path */
2409  break;
2410  }
2411  }
2412  }
2413 
2414  ReleaseSysCache(tup);
2415 
2416  return visible;
2417 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
FormData_pg_ts_parser * Form_pg_ts_parser
Definition: pg_ts_parser.h:55
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:185
const char * name
Definition: encode.c:561
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 2610 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1(), SearchSysCacheExists2, TSTEMPLATENAMENSP, and TSTEMPLATEOID.

Referenced by getObjectDescription(), and pg_ts_template_is_visible().

2611 {
2612  HeapTuple tup;
2613  Form_pg_ts_template form;
2614  Oid namespace;
2615  bool visible;
2616 
2618  if (!HeapTupleIsValid(tup))
2619  elog(ERROR, "cache lookup failed for text search template %u", tmplId);
2620  form = (Form_pg_ts_template) GETSTRUCT(tup);
2621 
2623 
2624  /*
2625  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2626  * the system namespace are surely in the path and so we needn't even do
2627  * list_member_oid() for them.
2628  */
2629  namespace = form->tmplnamespace;
2630  if (namespace != PG_CATALOG_NAMESPACE &&
2631  !list_member_oid(activeSearchPath, namespace))
2632  visible = false;
2633  else
2634  {
2635  /*
2636  * If it is in the path, it might still not be visible; it could be
2637  * hidden by another template of the same name earlier in the path. So
2638  * we must do a slow check for conflicting templates.
2639  */
2640  char *name = NameStr(form->tmplname);
2641  ListCell *l;
2642 
2643  visible = false;
2644  foreach(l, activeSearchPath)
2645  {
2646  Oid namespaceId = lfirst_oid(l);
2647 
2648  if (namespaceId == myTempNamespace)
2649  continue; /* do not look in temp namespace */
2650 
2651  if (namespaceId == namespace)
2652  {
2653  /* Found it first in path */
2654  visible = true;
2655  break;
2656  }
2658  PointerGetDatum(name),
2659  ObjectIdGetDatum(namespaceId)))
2660  {
2661  /* Found something else first in path */
2662  break;
2663  }
2664  }
2665  }
2666 
2667  ReleaseSysCache(tup);
2668 
2669  return visible;
2670 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:185
const char * name
Definition: encode.c:561
static List * activeSearchPath
Definition: namespace.c:138
FormData_pg_ts_template * Form_pg_ts_template
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:623
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 816 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), NameStr, ObjectIdGetDatum, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1(), SearchSysCacheExists2, TYPENAMENSP, TYPEOID, and typname.

Referenced by format_type_extended(), and pg_type_is_visible().

817 {
818  HeapTuple typtup;
819  Form_pg_type typform;
820  Oid typnamespace;
821  bool visible;
822 
823  typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
824  if (!HeapTupleIsValid(typtup))
825  elog(ERROR, "cache lookup failed for type %u", typid);
826  typform = (Form_pg_type) GETSTRUCT(typtup);
827 
829 
830  /*
831  * Quick check: if it ain't in the path at all, it ain't visible. Items in
832  * the system namespace are surely in the path and so we needn't even do
833  * list_member_oid() for them.
834  */
835  typnamespace = typform->typnamespace;
836  if (typnamespace != PG_CATALOG_NAMESPACE &&
837  !list_member_oid(activeSearchPath, typnamespace))
838  visible = false;
839  else
840  {
841  /*
842  * If it is in the path, it might still not be visible; it could be
843  * hidden by another type of the same name earlier in the path. So we
844  * must do a slow check for conflicting types.
845  */
846  char *typname = NameStr(typform->typname);
847  ListCell *l;
848 
849  visible = false;
850  foreach(l, activeSearchPath)
851  {
852  Oid namespaceId = lfirst_oid(l);
853 
854  if (namespaceId == typnamespace)
855  {
856  /* Found it first in path */
857  visible = true;
858  break;
859  }
861  PointerGetDatum(typname),
862  ObjectIdGetDatum(namespaceId)))
863  {
864  /* Found something else first in path */
865  break;
866  }
867  }
868  }
869 
870  ReleaseSysCache(typtup);
871 
872  return visible;
873 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define PointerGetDatum(X)
Definition: postgres.h:556
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3736
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
NameData typname
Definition: pg_type.h:41
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_type * Form_pg_type
Definition: pg_type.h:255
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:185
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214