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 include_out_arguments, bool missing_ok)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok)
 
bool OperatorIsVisible (Oid oprid)
 
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
 
bool OpclassIsVisible (Oid opcid)
 
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
 
bool OpfamilyIsVisible (Oid opfid)
 
Oid CollationGetCollid (const char *collname)
 
bool CollationIsVisible (Oid collid)
 
Oid ConversionGetConid (const char *conname)
 
bool ConversionIsVisible (Oid conid)
 
Oid get_statistics_object_oid (List *names, bool missing_ok)
 
bool StatisticsObjIsVisible (Oid 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

PGDLLIMPORT char * namespace_search_path
 

Macro Definition Documentation

◆ RangeVarGetRelid

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

Definition at line 79 of file namespace.h.

Typedef Documentation

◆ FuncCandidateList

◆ OverrideSearchPath

◆ RangeVarGetRelidCallback

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

Definition at line 76 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 69 of file namespace.h.

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

◆ TempNamespaceStatus

Enumerator
TEMP_NAMESPACE_NOT_TEMP 
TEMP_NAMESPACE_IDLE 
TEMP_NAMESPACE_IN_USE 

Definition at line 44 of file namespace.h.

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

Function Documentation

◆ AtEOSubXact_Namespace()

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

Definition at line 4178 of file namespace.c.

4180 {
4181  OverrideStackEntry *entry;
4182 
4183  if (myTempNamespaceSubID == mySubid)
4184  {
4185  if (isCommit)
4186  myTempNamespaceSubID = parentSubid;
4187  else
4188  {
4190  /* TEMP namespace creation failed, so reset state */
4193  baseSearchPathValid = false; /* need to rebuild list */
4194 
4195  /*
4196  * Reset the temporary namespace flag in MyProc. We assume that
4197  * this operation is atomic.
4198  *
4199  * Because this subtransaction is aborting, the pg_namespace row
4200  * is not visible to anyone else anyway, but that doesn't matter:
4201  * it's not a problem if objects contained in this namespace are
4202  * removed concurrently.
4203  */
4205  }
4206  }
4207 
4208  /*
4209  * Clean up if someone failed to do PopOverrideSearchPath
4210  */
4211  while (overrideStack)
4212  {
4215  break;
4216  if (isCommit)
4217  elog(WARNING, "leaked override search path");
4219  list_free(entry->searchPath);
4220  pfree(entry);
4221  /* Always bump generation --- see note in recomputeNamespacePath */
4223  }
4224 
4225  /* Activate the next level down. */
4226  if (overrideStack)
4227  {
4229  activeSearchPath = entry->searchPath;
4231  activeTempCreationPending = false; /* XXX is this OK? */
4232 
4233  /*
4234  * It's probably unnecessary to bump generation here, but this should
4235  * not be a performance-critical case, so better to be over-cautious.
4236  */
4238  }
4239  else
4240  {
4241  /* If not baseSearchPathValid, this is useless but harmless */
4245 
4246  /*
4247  * If we popped an override stack entry, then we already bumped the
4248  * generation above. If we did not, then the above assignments did
4249  * nothing and we need not bump the generation.
4250  */
4251  }
4252 }
#define InvalidSubTransactionId
Definition: c.h:604
#define WARNING
Definition: elog.h:30
List * list_delete_first(List *list)
Definition: list.c:942
void list_free(List *list)
Definition: list.c:1545
void pfree(void *pointer)
Definition: mcxt.c:1175
static bool baseTempCreationPending
Definition: namespace.c:156
static Oid baseCreationNamespace
Definition: namespace.c:154
static Oid activeCreationNamespace
Definition: namespace.c:142
static List * activeSearchPath
Definition: namespace.c:139
static bool baseSearchPathValid
Definition: namespace.c:161
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:193
static Oid myTempToastNamespace
Definition: namespace.c:191
static List * overrideStack
Definition: namespace.c:172
static Oid myTempNamespace
Definition: namespace.c:189
static bool activeTempCreationPending
Definition: namespace.c:145
static uint64 activePathGeneration
Definition: namespace.c:148
static List * baseSearchPath
Definition: namespace.c:152
#define linitial(l)
Definition: pg_list.h:176
#define InvalidOid
Definition: postgres_ext.h:36
PGPROC * MyProc
Definition: proc.c:68
Oid tempNamespaceId
Definition: proc.h:195
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:910

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4110 of file namespace.c.

4111 {
4112  /*
4113  * If we abort the transaction in which a temp namespace was selected,
4114  * we'll have to do any creation or cleanout work over again. So, just
4115  * forget the namespace entirely until next time. On the other hand, if
4116  * we commit then register an exit callback to clean out the temp tables
4117  * at backend shutdown. (We only want to register the callback once per
4118  * session, so this is a good place to do it.)
4119  */
4120  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
4121  {
4122  if (isCommit)
4124  else
4125  {
4128  baseSearchPathValid = false; /* need to rebuild list */
4129 
4130  /*
4131  * Reset the temporary namespace flag in MyProc. We assume that
4132  * this operation is atomic.
4133  *
4134  * Because this transaction is aborting, the pg_namespace row is
4135  * not visible to anyone else anyway, but that doesn't matter:
4136  * it's not a problem if objects contained in this namespace are
4137  * removed concurrently.
4138  */
4140  }
4142  }
4143 
4144  /*
4145  * Clean up if someone failed to do PopOverrideSearchPath
4146  */
4147  if (overrideStack)
4148  {
4149  if (isCommit)
4150  elog(WARNING, "leaked override search path");
4151  while (overrideStack)
4152  {
4153  OverrideStackEntry *entry;
4154 
4157  list_free(entry->searchPath);
4158  pfree(entry);
4159  }
4160  /* If not baseSearchPathValid, this is useless but harmless */
4164  /* Always bump generation --- see note in recomputeNamespacePath */
4166  }
4167 }
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4289

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

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

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 3013 of file namespace.c.

3014 {
3015  /* disallow renaming into or out of temp schemas */
3016  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
3017  ereport(ERROR,
3018  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3019  errmsg("cannot move objects into or out of temporary schemas")));
3020 
3021  /* same for TOAST schema */
3022  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
3023  ereport(ERROR,
3024  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3025  errmsg("cannot move objects into or out of TOAST schema")));
3026 }
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3241

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

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

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3283 of file namespace.c.

3284 {
3285  PGPROC *proc;
3286  int backendId;
3287 
3289 
3290  backendId = GetTempNamespaceBackendId(namespaceId);
3291 
3292  /* No such namespace, or its name shows it's not temp? */
3293  if (backendId == InvalidBackendId)
3294  return TEMP_NAMESPACE_NOT_TEMP;
3295 
3296  /* Is the backend alive? */
3297  proc = BackendIdGetProc(backendId);
3298  if (proc == NULL)
3299  return TEMP_NAMESPACE_IDLE;
3300 
3301  /* Is the backend connected to the same database we are looking at? */
3302  if (proc->databaseId != MyDatabaseId)
3303  return TEMP_NAMESPACE_IDLE;
3304 
3305  /* Does the backend own the temporary namespace? */
3306  if (proc->tempNamespaceId != namespaceId)
3307  return TEMP_NAMESPACE_IDLE;
3308 
3309  /* Yup, so namespace is busy */
3310  return TEMP_NAMESPACE_IN_USE;
3311 }
#define InvalidBackendId
Definition: backendid.h:23
#define OidIsValid(objectId)
Definition: c.h:721
Oid MyDatabaseId
Definition: globals.c:89
Assert(fmt[strlen(fmt) - 1] !='\n')
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3320
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:385
Definition: proc.h:160
Oid databaseId
Definition: proc.h:192

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

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2060 of file namespace.c.

2061 {
2062  int32 dbencoding = GetDatabaseEncoding();
2063  ListCell *l;
2064 
2066 
2067  foreach(l, activeSearchPath)
2068  {
2069  Oid namespaceId = lfirst_oid(l);
2070  Oid collid;
2071 
2072  if (namespaceId == myTempNamespace)
2073  continue; /* do not look in temp namespace */
2074 
2075  collid = lookup_collation(collname, namespaceId, dbencoding);
2076  if (OidIsValid(collid))
2077  return collid;
2078  }
2079 
2080  /* Not found in path */
2081  return InvalidOid;
2082 }
signed int int32
Definition: c.h:440
int GetDatabaseEncoding(void)
Definition: mbutils.c:1210
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:2009
static void recomputeNamespacePath(void)
Definition: namespace.c:3783
#define lfirst_oid(lc)
Definition: pg_list.h:172
unsigned int Oid
Definition: postgres_ext.h:31

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

Referenced by CollationIsVisible().

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2094 of file namespace.c.

2095 {
2096  HeapTuple colltup;
2097  Form_pg_collation collform;
2098  Oid collnamespace;
2099  bool visible;
2100 
2101  colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
2102  if (!HeapTupleIsValid(colltup))
2103  elog(ERROR, "cache lookup failed for collation %u", collid);
2104  collform = (Form_pg_collation) GETSTRUCT(colltup);
2105 
2107 
2108  /*
2109  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2110  * the system namespace are surely in the path and so we needn't even do
2111  * list_member_oid() for them.
2112  */
2113  collnamespace = collform->collnamespace;
2114  if (collnamespace != PG_CATALOG_NAMESPACE &&
2115  !list_member_oid(activeSearchPath, collnamespace))
2116  visible = false;
2117  else
2118  {
2119  /*
2120  * If it is in the path, it might still not be visible; it could be
2121  * hidden by another collation of the same name earlier in the path,
2122  * or it might not work with the current DB encoding. So we must do a
2123  * slow check to see if this collation would be found by
2124  * CollationGetCollid.
2125  */
2126  char *collname = NameStr(collform->collname);
2127 
2128  visible = (CollationGetCollid(collname) == collid);
2129  }
2130 
2131  ReleaseSysCache(colltup);
2132 
2133  return visible;
2134 }
#define NameStr(name)
Definition: c.h:692
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:721
Oid CollationGetCollid(const char *collname)
Definition: namespace.c:2060
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:57
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1221
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1173
@ COLLOID
Definition: syscache.h:50

References activeSearchPath, 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().

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2145 of file namespace.c.

2146 {
2147  Oid conid;
2148  ListCell *l;
2149 
2151 
2152  foreach(l, activeSearchPath)
2153  {
2154  Oid namespaceId = lfirst_oid(l);
2155 
2156  if (namespaceId == myTempNamespace)
2157  continue; /* do not look in temp namespace */
2158 
2159  conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2160  PointerGetDatum(conname),
2161  ObjectIdGetDatum(namespaceId));
2162  if (OidIsValid(conid))
2163  return conid;
2164  }
2165 
2166  /* Not found in path */
2167  return InvalidOid;
2168 }
#define PointerGetDatum(X)
Definition: postgres.h:600
@ CONNAMENSP
Definition: syscache.h:52
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:199

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

Referenced by ConversionIsVisible().

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2177 of file namespace.c.

2178 {
2179  HeapTuple contup;
2180  Form_pg_conversion conform;
2181  Oid connamespace;
2182  bool visible;
2183 
2184  contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
2185  if (!HeapTupleIsValid(contup))
2186  elog(ERROR, "cache lookup failed for conversion %u", conid);
2187  conform = (Form_pg_conversion) GETSTRUCT(contup);
2188 
2190 
2191  /*
2192  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2193  * the system namespace are surely in the path and so we needn't even do
2194  * list_member_oid() for them.
2195  */
2196  connamespace = conform->connamespace;
2197  if (connamespace != PG_CATALOG_NAMESPACE &&
2198  !list_member_oid(activeSearchPath, connamespace))
2199  visible = false;
2200  else
2201  {
2202  /*
2203  * If it is in the path, it might still not be visible; it could be
2204  * hidden by another conversion of the same name earlier in the path.
2205  * So we must do a slow check to see if this conversion would be found
2206  * by ConversionGetConid.
2207  */
2208  char *conname = NameStr(conform->conname);
2209 
2210  visible = (ConversionGetConid(conname) == conid);
2211  }
2212 
2213  ReleaseSysCache(contup);
2214 
2215  return visible;
2216 }
Oid ConversionGetConid(const char *conname)
Definition: namespace.c:2145
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:61
@ CONVOID
Definition: syscache.h:54

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

Referenced by getObjectDescription(), and pg_conversion_is_visible().

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3443 of file namespace.c.

3444 {
3445  OverrideSearchPath *result;
3446 
3447  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3448  result->schemas = list_copy(path->schemas);
3449  result->addCatalog = path->addCatalog;
3450  result->addTemp = path->addTemp;
3451  result->generation = path->generation;
3452 
3453  return result;
3454 }
List * list_copy(const List *oldlist)
Definition: list.c:1572
void * palloc(Size size)
Definition: mcxt.c:1068

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

Referenced by CopyCachedPlan().

◆ DeconstructQualifiedName()

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

Definition at line 2855 of file namespace.c.

2858 {
2859  char *catalogname;
2860  char *schemaname = NULL;
2861  char *objname = NULL;
2862 
2863  switch (list_length(names))
2864  {
2865  case 1:
2866  objname = strVal(linitial(names));
2867  break;
2868  case 2:
2869  schemaname = strVal(linitial(names));
2870  objname = strVal(lsecond(names));
2871  break;
2872  case 3:
2873  catalogname = strVal(linitial(names));
2874  schemaname = strVal(lsecond(names));
2875  objname = strVal(lthird(names));
2876 
2877  /*
2878  * We check the catalog name and then ignore it.
2879  */
2880  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2881  ereport(ERROR,
2882  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2883  errmsg("cross-database references are not implemented: %s",
2884  NameListToString(names))));
2885  break;
2886  default:
2887  ereport(ERROR,
2888  (errcode(ERRCODE_SYNTAX_ERROR),
2889  errmsg("improper qualified name (too many dotted names): %s",
2890  NameListToString(names))));
2891  break;
2892  }
2893 
2894  *nspname_p = schemaname;
2895  *objname_p = objname;
2896 }
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2994
char * NameListToString(List *names)
Definition: namespace.c:3148
static int list_length(const List *l)
Definition: pg_list.h:150
#define lthird(l)
Definition: pg_list.h:186
#define lsecond(l)
Definition: pg_list.h:181
#define strVal(v)
Definition: value.h:72

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

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4431 of file namespace.c.

4432 {
4433  List *result;
4434 
4436 
4437  /*
4438  * If the temp namespace should be first, force it to exist. This is so
4439  * that callers can trust the result to reflect the actual default
4440  * creation namespace. It's a bit bogus to do this here, since
4441  * current_schema() is supposedly a stable function without side-effects,
4442  * but the alternatives seem worse.
4443  */
4445  {
4448  }
4449 
4450  result = list_copy(activeSearchPath);
4451  if (!includeImplicit)
4452  {
4453  while (result && linitial_oid(result) != activeCreationNamespace)
4454  result = list_delete_first(result);
4455  }
4456 
4457  return result;
4458 }
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3961
#define linitial_oid(l)
Definition: pg_list.h:178
Definition: pg_list.h:52

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

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

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4471 of file namespace.c.

4472 {
4473  int count = 0;
4474  ListCell *l;
4475 
4477 
4478  foreach(l, activeSearchPath)
4479  {
4480  Oid namespaceId = lfirst_oid(l);
4481 
4482  if (namespaceId == myTempNamespace)
4483  continue; /* do not include temp namespace */
4484 
4485  if (count < sarray_len)
4486  sarray[count] = namespaceId;
4487  count++;
4488  }
4489 
4490  return count;
4491 }

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

Referenced by make_oper_cache_key().

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3756 of file namespace.c.

3757 {
3758  Oid proc;
3759  ListCell *l;
3760 
3762 
3763  foreach(l, activeSearchPath)
3764  {
3765  Oid namespaceId = lfirst_oid(l);
3766 
3767  if (namespaceId == myTempNamespace)
3768  continue; /* do not look in temp namespace */
3769 
3770  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3771  if (OidIsValid(proc))
3772  return proc;
3773  }
3774 
3775  /* Not found in path */
3776  return InvalidOid;
3777 }
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)

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

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

◆ FuncnameGetCandidates()

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

Definition at line 951 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1459 of file namespace.c.

1460 {
1461  HeapTuple proctup;
1462  Form_pg_proc procform;
1463  Oid pronamespace;
1464  bool visible;
1465 
1466  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1467  if (!HeapTupleIsValid(proctup))
1468  elog(ERROR, "cache lookup failed for function %u", funcid);
1469  procform = (Form_pg_proc) GETSTRUCT(proctup);
1470 
1472 
1473  /*
1474  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1475  * the system namespace are surely in the path and so we needn't even do
1476  * list_member_oid() for them.
1477  */
1478  pronamespace = procform->pronamespace;
1479  if (pronamespace != PG_CATALOG_NAMESPACE &&
1480  !list_member_oid(activeSearchPath, pronamespace))
1481  visible = false;
1482  else
1483  {
1484  /*
1485  * If it is in the path, it might still not be visible; it could be
1486  * hidden by another proc of the same name and arguments earlier in
1487  * the path. So we must do a slow check to see if this is the same
1488  * proc that would be found by FuncnameGetCandidates.
1489  */
1490  char *proname = NameStr(procform->proname);
1491  int nargs = procform->pronargs;
1492  FuncCandidateList clist;
1493 
1494  visible = false;
1495 
1497  nargs, NIL, false, false, false, false);
1498 
1499  for (; clist; clist = clist->next)
1500  {
1501  if (memcmp(clist->args, procform->proargtypes.values,
1502  nargs * sizeof(Oid)) == 0)
1503  {
1504  /* Found the expected entry; is it the right proc? */
1505  visible = (clist->oid == funcid);
1506  break;
1507  }
1508  }
1509  }
1510 
1511  ReleaseSysCache(proctup);
1512 
1513  return visible;
1514 }
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
Definition: namespace.c:951
#define list_make1(x1)
Definition: pg_list.h:210
NameData proname
Definition: pg_proc.h:35
@ PROCOID
Definition: syscache.h:79
String * makeString(char *str)
Definition: value.c:63

References activeSearchPath, _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().

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3647 of file namespace.c.

3648 {
3649  char *schemaname;
3650  char *collation_name;
3651  int32 dbencoding = GetDatabaseEncoding();
3652  Oid namespaceId;
3653  Oid colloid;
3654  ListCell *l;
3655 
3656  /* deconstruct the name list */
3657  DeconstructQualifiedName(name, &schemaname, &collation_name);
3658 
3659  if (schemaname)
3660  {
3661  /* use exact schema given */
3662  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3663  if (missing_ok && !OidIsValid(namespaceId))
3664  return InvalidOid;
3665 
3666  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3667  if (OidIsValid(colloid))
3668  return colloid;
3669  }
3670  else
3671  {
3672  /* search for it in search path */
3674 
3675  foreach(l, activeSearchPath)
3676  {
3677  namespaceId = lfirst_oid(l);
3678 
3679  if (namespaceId == myTempNamespace)
3680  continue; /* do not look in temp namespace */
3681 
3682  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3683  if (OidIsValid(colloid))
3684  return colloid;
3685  }
3686  }
3687 
3688  /* Not found in path */
3689  if (!missing_ok)
3690  ereport(ERROR,
3691  (errcode(ERRCODE_UNDEFINED_OBJECT),
3692  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3694  return InvalidOid;
3695 }
const char * name
Definition: encode.c:561
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1216

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

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

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 3701 of file namespace.c.

3702 {
3703  char *schemaname;
3704  char *conversion_name;
3705  Oid namespaceId;
3706  Oid conoid = InvalidOid;
3707  ListCell *l;
3708 
3709  /* deconstruct the name list */
3710  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3711 
3712  if (schemaname)
3713  {
3714  /* use exact schema given */
3715  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3716  if (missing_ok && !OidIsValid(namespaceId))
3717  conoid = InvalidOid;
3718  else
3719  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3720  PointerGetDatum(conversion_name),
3721  ObjectIdGetDatum(namespaceId));
3722  }
3723  else
3724  {
3725  /* search for it in search path */
3727 
3728  foreach(l, activeSearchPath)
3729  {
3730  namespaceId = lfirst_oid(l);
3731 
3732  if (namespaceId == myTempNamespace)
3733  continue; /* do not look in temp namespace */
3734 
3735  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3736  PointerGetDatum(conversion_name),
3737  ObjectIdGetDatum(namespaceId));
3738  if (OidIsValid(conoid))
3739  return conoid;
3740  }
3741  }
3742 
3743  /* Not found in path */
3744  if (!OidIsValid(conoid) && !missing_ok)
3745  ereport(ERROR,
3746  (errcode(ERRCODE_UNDEFINED_OBJECT),
3747  errmsg("conversion \"%s\" does not exist",
3748  NameListToString(name))));
3749  return conoid;
3750 }

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

Referenced by get_object_address().

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2224 of file namespace.c.

2225 {
2226  char *schemaname;
2227  char *stats_name;
2228  Oid namespaceId;
2229  Oid stats_oid = InvalidOid;
2230  ListCell *l;
2231 
2232  /* deconstruct the name list */
2233  DeconstructQualifiedName(names, &schemaname, &stats_name);
2234 
2235  if (schemaname)
2236  {
2237  /* use exact schema given */
2238  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2239  if (missing_ok && !OidIsValid(namespaceId))
2240  stats_oid = InvalidOid;
2241  else
2242  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2243  PointerGetDatum(stats_name),
2244  ObjectIdGetDatum(namespaceId));
2245  }
2246  else
2247  {
2248  /* search for it in search path */
2250 
2251  foreach(l, activeSearchPath)
2252  {
2253  namespaceId = lfirst_oid(l);
2254 
2255  if (namespaceId == myTempNamespace)
2256  continue; /* do not look in temp namespace */
2257  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2258  PointerGetDatum(stats_name),
2259  ObjectIdGetDatum(namespaceId));
2260  if (OidIsValid(stats_oid))
2261  break;
2262  }
2263  }
2264 
2265  if (!OidIsValid(stats_oid) && !missing_ok)
2266  ereport(ERROR,
2267  (errcode(ERRCODE_UNDEFINED_OBJECT),
2268  errmsg("statistics object \"%s\" does not exist",
2269  NameListToString(names))));
2270 
2271  return stats_oid;
2272 }
@ STATEXTNAMENSP
Definition: syscache.h:95

References activeSearchPath, 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().

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2725 of file namespace.c.

2726 {
2727  char *schemaname;
2728  char *config_name;
2729  Oid namespaceId;
2730  Oid cfgoid = InvalidOid;
2731  ListCell *l;
2732 
2733  /* deconstruct the name list */
2734  DeconstructQualifiedName(names, &schemaname, &config_name);
2735 
2736  if (schemaname)
2737  {
2738  /* use exact schema given */
2739  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2740  if (missing_ok && !OidIsValid(namespaceId))
2741  cfgoid = InvalidOid;
2742  else
2743  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2744  PointerGetDatum(config_name),
2745  ObjectIdGetDatum(namespaceId));
2746  }
2747  else
2748  {
2749  /* search for it in search path */
2751 
2752  foreach(l, activeSearchPath)
2753  {
2754  namespaceId = lfirst_oid(l);
2755 
2756  if (namespaceId == myTempNamespace)
2757  continue; /* do not look in temp namespace */
2758 
2759  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2760  PointerGetDatum(config_name),
2761  ObjectIdGetDatum(namespaceId));
2762  if (OidIsValid(cfgoid))
2763  break;
2764  }
2765  }
2766 
2767  if (!OidIsValid(cfgoid) && !missing_ok)
2768  ereport(ERROR,
2769  (errcode(ERRCODE_UNDEFINED_OBJECT),
2770  errmsg("text search configuration \"%s\" does not exist",
2771  NameListToString(names))));
2772 
2773  return cfgoid;
2774 }
@ TSCONFIGNAMENSP
Definition: syscache.h:105

References activeSearchPath, 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().

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2472 of file namespace.c.

2473 {
2474  char *schemaname;
2475  char *dict_name;
2476  Oid namespaceId;
2477  Oid dictoid = InvalidOid;
2478  ListCell *l;
2479 
2480  /* deconstruct the name list */
2481  DeconstructQualifiedName(names, &schemaname, &dict_name);
2482 
2483  if (schemaname)
2484  {
2485  /* use exact schema given */
2486  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2487  if (missing_ok && !OidIsValid(namespaceId))
2488  dictoid = InvalidOid;
2489  else
2490  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2491  PointerGetDatum(dict_name),
2492  ObjectIdGetDatum(namespaceId));
2493  }
2494  else
2495  {
2496  /* search for it in search path */
2498 
2499  foreach(l, activeSearchPath)
2500  {
2501  namespaceId = lfirst_oid(l);
2502 
2503  if (namespaceId == myTempNamespace)
2504  continue; /* do not look in temp namespace */
2505 
2506  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2507  PointerGetDatum(dict_name),
2508  ObjectIdGetDatum(namespaceId));
2509  if (OidIsValid(dictoid))
2510  break;
2511  }
2512  }
2513 
2514  if (!OidIsValid(dictoid) && !missing_ok)
2515  ereport(ERROR,
2516  (errcode(ERRCODE_UNDEFINED_OBJECT),
2517  errmsg("text search dictionary \"%s\" does not exist",
2518  NameListToString(names))));
2519 
2520  return dictoid;
2521 }
@ TSDICTNAMENSP
Definition: syscache.h:107

References activeSearchPath, 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().

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2346 of file namespace.c.

2347 {
2348  char *schemaname;
2349  char *parser_name;
2350  Oid namespaceId;
2351  Oid prsoid = InvalidOid;
2352  ListCell *l;
2353 
2354  /* deconstruct the name list */
2355  DeconstructQualifiedName(names, &schemaname, &parser_name);
2356 
2357  if (schemaname)
2358  {
2359  /* use exact schema given */
2360  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2361  if (missing_ok && !OidIsValid(namespaceId))
2362  prsoid = InvalidOid;
2363  else
2364  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2365  PointerGetDatum(parser_name),
2366  ObjectIdGetDatum(namespaceId));
2367  }
2368  else
2369  {
2370  /* search for it in search path */
2372 
2373  foreach(l, activeSearchPath)
2374  {
2375  namespaceId = lfirst_oid(l);
2376 
2377  if (namespaceId == myTempNamespace)
2378  continue; /* do not look in temp namespace */
2379 
2380  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2381  PointerGetDatum(parser_name),
2382  ObjectIdGetDatum(namespaceId));
2383  if (OidIsValid(prsoid))
2384  break;
2385  }
2386  }
2387 
2388  if (!OidIsValid(prsoid) && !missing_ok)
2389  ereport(ERROR,
2390  (errcode(ERRCODE_UNDEFINED_OBJECT),
2391  errmsg("text search parser \"%s\" does not exist",
2392  NameListToString(names))));
2393 
2394  return prsoid;
2395 }
@ TSPARSERNAMENSP
Definition: syscache.h:109

References activeSearchPath, 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().

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2599 of file namespace.c.

2600 {
2601  char *schemaname;
2602  char *template_name;
2603  Oid namespaceId;
2604  Oid tmploid = InvalidOid;
2605  ListCell *l;
2606 
2607  /* deconstruct the name list */
2608  DeconstructQualifiedName(names, &schemaname, &template_name);
2609 
2610  if (schemaname)
2611  {
2612  /* use exact schema given */
2613  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2614  if (missing_ok && !OidIsValid(namespaceId))
2615  tmploid = InvalidOid;
2616  else
2617  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2618  PointerGetDatum(template_name),
2619  ObjectIdGetDatum(namespaceId));
2620  }
2621  else
2622  {
2623  /* search for it in search path */
2625 
2626  foreach(l, activeSearchPath)
2627  {
2628  namespaceId = lfirst_oid(l);
2629 
2630  if (namespaceId == myTempNamespace)
2631  continue; /* do not look in temp namespace */
2632 
2633  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2634  PointerGetDatum(template_name),
2635  ObjectIdGetDatum(namespaceId));
2636  if (OidIsValid(tmploid))
2637  break;
2638  }
2639  }
2640 
2641  if (!OidIsValid(tmploid) && !missing_ok)
2642  ereport(ERROR,
2643  (errcode(ERRCODE_UNDEFINED_OBJECT),
2644  errmsg("text search template \"%s\" does not exist",
2645  NameListToString(names))));
2646 
2647  return tmploid;
2648 }
@ TSTEMPLATENAMENSP
Definition: syscache.h:111

References activeSearchPath, 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().

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3406 of file namespace.c.

3407 {
3408  OverrideSearchPath *result;
3409  List *schemas;
3410  MemoryContext oldcxt;
3411 
3413 
3414  oldcxt = MemoryContextSwitchTo(context);
3415 
3416  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3417  schemas = list_copy(activeSearchPath);
3418  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3419  {
3420  if (linitial_oid(schemas) == myTempNamespace)
3421  result->addTemp = true;
3422  else
3423  {
3424  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3425  result->addCatalog = true;
3426  }
3427  schemas = list_delete_first(schemas);
3428  }
3429  result->schemas = schemas;
3430  result->generation = activePathGeneration;
3431 
3432  MemoryContextSwitchTo(oldcxt);
3433 
3434  return result;
3435 }
void * palloc0(Size size)
Definition: mcxt.c:1099
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109

References activeCreationNamespace, activePathGeneration, activeSearchPath, 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().

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3320 of file namespace.c.

3321 {
3322  int result;
3323  char *nspname;
3324 
3325  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3326  nspname = get_namespace_name(namespaceId);
3327  if (!nspname)
3328  return InvalidBackendId; /* no such namespace? */
3329  if (strncmp(nspname, "pg_temp_", 8) == 0)
3330  result = atoi(nspname + 8);
3331  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3332  result = atoi(nspname + 14);
3333  else
3334  result = InvalidBackendId;
3335  pfree(nspname);
3336  return result;
3337 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3326

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

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

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3359 of file namespace.c.

3360 {
3361  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3362  *tempNamespaceId = myTempNamespace;
3363  *tempToastNamespaceId = myTempToastNamespace;
3364 }

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3345 of file namespace.c.

3346 {
3348  return myTempToastNamespace;
3349 }

References Assert(), myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4372 of file namespace.c.

4373 {
4375  {
4376  /*
4377  * In bootstrap mode, the search path must be 'pg_catalog' so that
4378  * tables are created in the proper namespace; ignore the GUC setting.
4379  */
4380  MemoryContext oldcxt;
4381 
4383  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4384  MemoryContextSwitchTo(oldcxt);
4385  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4386  baseTempCreationPending = false;
4387  baseSearchPathValid = true;
4392  activePathGeneration++; /* pro forma */
4393  }
4394  else
4395  {
4396  /*
4397  * In normal mode, arrange for a callback on any syscache invalidation
4398  * of pg_namespace rows.
4399  */
4402  (Datum) 0);
4403  /* Force search path to be recomputed on next use */
4404  baseSearchPathValid = false;
4405  }
4406 }
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1519
MemoryContext TopMemoryContext
Definition: mcxt.c:48
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406
Oid GetUserId(void)
Definition: miscinit.c:491
static Oid namespaceUser
Definition: namespace.c:158
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4413
#define list_make1_oid(x1)
Definition: pg_list.h:240
@ NAMESPACEOID
Definition: syscache.h:70

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

Referenced by InitPostgres().

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3241 of file namespace.c.

3242 {
3243  bool result;
3244  char *nspname;
3245 
3246  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3247  nspname = get_namespace_name(namespaceId);
3248  if (!nspname)
3249  return false; /* no such namespace? */
3250  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3251  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3252  pfree(nspname);
3253  return result;
3254 }

References get_namespace_name(), and pfree().

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

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3264 of file namespace.c.

3265 {
3266  /* If it's my own temp namespace, say "false" */
3267  if (isTempOrTempToastNamespace(namespaceId))
3268  return false;
3269  /* Else, if it's any temp namespace, say "true" */
3270  return isAnyTempNamespace(namespaceId);
3271 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3227

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3203 of file namespace.c.

3204 {
3205  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3206  return true;
3207  return false;
3208 }

References myTempNamespace, and OidIsValid.

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

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3227 of file namespace.c.

3228 {
3229  if (OidIsValid(myTempNamespace) &&
3230  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3231  return true;
3232  return false;
3233 }

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3215 of file namespace.c.

3216 {
3217  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3218  return true;
3219  return false;
3220 }

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2982 of file namespace.c.

2983 {
2984  Oid namespaceId;
2985  AclResult aclresult;
2986 
2987  /* check for pg_temp alias */
2988  if (strcmp(nspname, "pg_temp") == 0)
2989  {
2990  /* Initialize temp namespace */
2991  AccessTempTableNamespace(false);
2992  return myTempNamespace;
2993  }
2994 
2995  namespaceId = get_namespace_oid(nspname, false);
2996 
2997  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2998  if (aclresult != ACLCHECK_OK)
2999  aclcheck_error(aclresult, OBJECT_SCHEMA,
3000  nspname);
3001 
3002  return namespaceId;
3003 }
AclResult
Definition: acl.h:181
@ ACLCHECK_OK
Definition: acl.h:182
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:5109
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3512
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3089
@ OBJECT_SCHEMA
Definition: parsenodes.h:2171
#define ACL_CREATE
Definition: parsenodes.h:91

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

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2939 of file namespace.c.

2940 {
2941  Oid namespaceId;
2942  AclResult aclresult;
2943 
2944  /* check for pg_temp alias */
2945  if (strcmp(nspname, "pg_temp") == 0)
2946  {
2948  return myTempNamespace;
2949 
2950  /*
2951  * Since this is used only for looking up existing objects, there is
2952  * no point in trying to initialize the temp namespace here; and doing
2953  * so might create problems for some callers --- just fall through.
2954  */
2955  }
2956 
2957  namespaceId = get_namespace_oid(nspname, missing_ok);
2958  if (missing_ok && !OidIsValid(namespaceId))
2959  return InvalidOid;
2960 
2961  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
2962  if (aclresult != ACLCHECK_OK)
2963  aclcheck_error(aclresult, OBJECT_SCHEMA,
2964  nspname);
2965  /* Schema search hook for this lookup */
2966  InvokeNamespaceSearchHook(namespaceId, true);
2967 
2968  return namespaceId;
2969 }
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:206
#define ACL_USAGE
Definition: parsenodes.h:90

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

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2909 of file namespace.c.

2910 {
2911  /* check for pg_temp alias */
2912  if (strcmp(nspname, "pg_temp") == 0)
2913  {
2915  {
2917  return myTempNamespace;
2918  }
2919 
2920  /*
2921  * Since this is used only for looking up existing objects, there is
2922  * no point in trying to initialize the temp namespace here; and doing
2923  * so might create problems for some callers. Just report "not found".
2924  */
2925  return InvalidOid;
2926  }
2927 
2928  return get_namespace_oid(nspname, true);
2929 }

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

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

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 3108 of file namespace.c.

3109 {
3110  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3111 
3112  switch (list_length(names))
3113  {
3114  case 1:
3115  rel->relname = strVal(linitial(names));
3116  break;
3117  case 2:
3118  rel->schemaname = strVal(linitial(names));
3119  rel->relname = strVal(lsecond(names));
3120  break;
3121  case 3:
3122  rel->catalogname = strVal(linitial(names));
3123  rel->schemaname = strVal(lsecond(names));
3124  rel->relname = strVal(lthird(names));
3125  break;
3126  default:
3127  ereport(ERROR,
3128  (errcode(ERRCODE_SYNTAX_ERROR),
3129  errmsg("improper relation name (too many dotted names): %s",
3130  NameListToString(names))));
3131  break;
3132  }
3133 
3134  return rel;
3135 }
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:423
char * relname
Definition: primnodes.h:74
char * catalogname
Definition: primnodes.h:68
char * schemaname
Definition: primnodes.h:71

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_internal(), bt_page_stats_internal(), convert_table_name(), currtid_byrelname(), generateSerialExtraStmts(), get_object_address_attrdef(), get_object_address_attribute(), get_object_address_publication_rel(), get_object_address_relobject(), get_raw_page_internal(), get_rel_from_relname(), get_relation_by_qualified_name(), nextval(), owningrel_does_not_exist_skipping(), pg_get_serial_sequence(), pg_get_viewdef_name(), pg_get_viewdef_name_ext(), pg_relpages(), pg_relpages_v1_5(), pgrowlocks(), pgstatindex(), pgstatindex_v1_5(), pgstattuple(), pgstattuple_v1_5(), process_owned_by(), regclassin(), RelationNameGetTupleDesc(), RemoveRelations(), row_security_active_name(), schema_does_not_exist_skipping(), text_regclass(), and to_regclass().

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3182 of file namespace.c.

3183 {
3185  ListCell *l;
3186 
3187  initStringInfo(&string);
3188 
3189  foreach(l, names)
3190  {
3191  if (l != list_head(names))
3192  appendStringInfoChar(&string, '.');
3194  }
3195 
3196  return string.data;
3197 }
#define lfirst(lc)
Definition: pg_list.h:170
static ListCell * list_head(const List *l)
Definition: pg_list.h:126
char string[11]
Definition: preproc-type.c:46
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:12189
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

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

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3148 of file namespace.c.

3149 {
3151  ListCell *l;
3152 
3153  initStringInfo(&string);
3154 
3155  foreach(l, names)
3156  {
3157  Node *name = (Node *) lfirst(l);
3158 
3159  if (l != list_head(names))
3160  appendStringInfoChar(&string, '.');
3161 
3162  if (IsA(name, String))
3163  appendStringInfoString(&string, strVal(name));
3164  else if (IsA(name, A_Star))
3165  appendStringInfoChar(&string, '*');
3166  else
3167  elog(ERROR, "unexpected node type in name list: %d",
3168  (int) nodeTag(name));
3169  }
3170 
3171  return string.data;
3172 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:625
#define nodeTag(nodeptr)
Definition: nodes.h:579
Definition: nodes.h:575
Definition: value.h:58

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

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

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1879 of file namespace.c.

1880 {
1881  HeapTuple opctup;
1882  Form_pg_opclass opcform;
1883  Oid opcnamespace;
1884  bool visible;
1885 
1886  opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
1887  if (!HeapTupleIsValid(opctup))
1888  elog(ERROR, "cache lookup failed for opclass %u", opcid);
1889  opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1890 
1892 
1893  /*
1894  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1895  * the system namespace are surely in the path and so we needn't even do
1896  * list_member_oid() for them.
1897  */
1898  opcnamespace = opcform->opcnamespace;
1899  if (opcnamespace != PG_CATALOG_NAMESPACE &&
1900  !list_member_oid(activeSearchPath, opcnamespace))
1901  visible = false;
1902  else
1903  {
1904  /*
1905  * If it is in the path, it might still not be visible; it could be
1906  * hidden by another opclass of the same name earlier in the path. So
1907  * we must do a slow check to see if this opclass would be found by
1908  * OpclassnameGetOpcid.
1909  */
1910  char *opcname = NameStr(opcform->opcname);
1911 
1912  visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1913  }
1914 
1915  ReleaseSysCache(opctup);
1916 
1917  return visible;
1918 }
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
Definition: namespace.c:1846
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
@ CLAOID
Definition: syscache.h:48

References activeSearchPath, 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().

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1846 of file namespace.c.

1847 {
1848  Oid opcid;
1849  ListCell *l;
1850 
1852 
1853  foreach(l, activeSearchPath)
1854  {
1855  Oid namespaceId = lfirst_oid(l);
1856 
1857  if (namespaceId == myTempNamespace)
1858  continue; /* do not look in temp namespace */
1859 
1860  opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
1861  ObjectIdGetDatum(amid),
1862  PointerGetDatum(opcname),
1863  ObjectIdGetDatum(namespaceId));
1864  if (OidIsValid(opcid))
1865  return opcid;
1866  }
1867 
1868  /* Not found in path */
1869  return InvalidOid;
1870 }
@ CLAAMNAMENSP
Definition: syscache.h:47
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:201

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

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

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1793 of file namespace.c.

1794 {
1795  HeapTuple oprtup;
1796  Form_pg_operator oprform;
1797  Oid oprnamespace;
1798  bool visible;
1799 
1801  if (!HeapTupleIsValid(oprtup))
1802  elog(ERROR, "cache lookup failed for operator %u", oprid);
1803  oprform = (Form_pg_operator) GETSTRUCT(oprtup);
1804 
1806 
1807  /*
1808  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1809  * the system namespace are surely in the path and so we needn't even do
1810  * list_member_oid() for them.
1811  */
1812  oprnamespace = oprform->oprnamespace;
1813  if (oprnamespace != PG_CATALOG_NAMESPACE &&
1814  !list_member_oid(activeSearchPath, oprnamespace))
1815  visible = false;
1816  else
1817  {
1818  /*
1819  * If it is in the path, it might still not be visible; it could be
1820  * hidden by another operator of the same name and arguments earlier
1821  * in the path. So we must do a slow check to see if this is the same
1822  * operator that would be found by OpernameGetOprid.
1823  */
1824  char *oprname = NameStr(oprform->oprname);
1825 
1826  visible = (OpernameGetOprid(list_make1(makeString(oprname)),
1827  oprform->oprleft, oprform->oprright)
1828  == oprid);
1829  }
1830 
1831  ReleaseSysCache(oprtup);
1832 
1833  return visible;
1834 }
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1529
Oid oprid(Operator op)
Definition: parse_oper.c:250
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
@ OPEROID
Definition: syscache.h:72

References activeSearchPath, 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().

◆ OpernameGetCandidates()

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

Definition at line 1632 of file namespace.c.

1633 {
1634  FuncCandidateList resultList = NULL;
1635  char *resultSpace = NULL;
1636  int nextResult = 0;
1637  char *schemaname;
1638  char *opername;
1639  Oid namespaceId;
1640  CatCList *catlist;
1641  int i;
1642 
1643  /* deconstruct the name list */
1644  DeconstructQualifiedName(names, &schemaname, &opername);
1645 
1646  if (schemaname)
1647  {
1648  /* use exact schema given */
1649  namespaceId = LookupExplicitNamespace(schemaname, missing_schema_ok);
1650  if (missing_schema_ok && !OidIsValid(namespaceId))
1651  return NULL;
1652  }
1653  else
1654  {
1655  /* flag to indicate we need namespace search */
1656  namespaceId = InvalidOid;
1658  }
1659 
1660  /* Search syscache by name only */
1661  catlist = SearchSysCacheList1(OPERNAMENSP, CStringGetDatum(opername));
1662 
1663  /*
1664  * In typical scenarios, most if not all of the operators found by the
1665  * catcache search will end up getting returned; and there can be quite a
1666  * few, for common operator names such as '=' or '+'. To reduce the time
1667  * spent in palloc, we allocate the result space as an array large enough
1668  * to hold all the operators. The original coding of this routine did a
1669  * separate palloc for each operator, but profiling revealed that the
1670  * pallocs used an unreasonably large fraction of parsing time.
1671  */
1672 #define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
1673  2 * sizeof(Oid))
1674 
1675  if (catlist->n_members > 0)
1676  resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
1677 
1678  for (i = 0; i < catlist->n_members; i++)
1679  {
1680  HeapTuple opertup = &catlist->members[i]->tuple;
1681  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1682  int pathpos = 0;
1683  FuncCandidateList newResult;
1684 
1685  /* Ignore operators of wrong kind, if specific kind requested */
1686  if (oprkind && operform->oprkind != oprkind)
1687  continue;
1688 
1689  if (OidIsValid(namespaceId))
1690  {
1691  /* Consider only opers in specified namespace */
1692  if (operform->oprnamespace != namespaceId)
1693  continue;
1694  /* No need to check args, they must all be different */
1695  }
1696  else
1697  {
1698  /*
1699  * Consider only opers that are in the search path and are not in
1700  * the temp namespace.
1701  */
1702  ListCell *nsp;
1703 
1704  foreach(nsp, activeSearchPath)
1705  {
1706  if (operform->oprnamespace == lfirst_oid(nsp) &&
1707  operform->oprnamespace != myTempNamespace)
1708  break;
1709  pathpos++;
1710  }
1711  if (nsp == NULL)
1712  continue; /* oper is not in search path */
1713 
1714  /*
1715  * Okay, it's in the search path, but does it have the same
1716  * arguments as something we already accepted? If so, keep only
1717  * the one that appears earlier in the search path.
1718  *
1719  * If we have an ordered list from SearchSysCacheList (the normal
1720  * case), then any conflicting oper must immediately adjoin this
1721  * one in the list, so we only need to look at the newest result
1722  * item. If we have an unordered list, we have to scan the whole
1723  * result list.
1724  */
1725  if (resultList)
1726  {
1727  FuncCandidateList prevResult;
1728 
1729  if (catlist->ordered)
1730  {
1731  if (operform->oprleft == resultList->args[0] &&
1732  operform->oprright == resultList->args[1])
1733  prevResult = resultList;
1734  else
1735  prevResult = NULL;
1736  }
1737  else
1738  {
1739  for (prevResult = resultList;
1740  prevResult;
1741  prevResult = prevResult->next)
1742  {
1743  if (operform->oprleft == prevResult->args[0] &&
1744  operform->oprright == prevResult->args[1])
1745  break;
1746  }
1747  }
1748  if (prevResult)
1749  {
1750  /* We have a match with a previous result */
1751  Assert(pathpos != prevResult->pathpos);
1752  if (pathpos > prevResult->pathpos)
1753  continue; /* keep previous result */
1754  /* replace previous result */
1755  prevResult->pathpos = pathpos;
1756  prevResult->oid = operform->oid;
1757  continue; /* args are same, of course */
1758  }
1759  }
1760  }
1761 
1762  /*
1763  * Okay to add it to result list
1764  */
1765  newResult = (FuncCandidateList) (resultSpace + nextResult);
1766  nextResult += SPACE_PER_OP;
1767 
1768  newResult->pathpos = pathpos;
1769  newResult->oid = operform->oid;
1770  newResult->nominalnargs = 2;
1771  newResult->nargs = 2;
1772  newResult->nvargs = 0;
1773  newResult->ndargs = 0;
1774  newResult->argnumbers = NULL;
1775  newResult->args[0] = operform->oprleft;
1776  newResult->args[1] = operform->oprright;
1777  newResult->next = resultList;
1778  resultList = newResult;
1779  }
1780 
1781  ReleaseSysCacheList(catlist);
1782 
1783  return resultList;
1784 }
#define SPACE_PER_OP
@ OPERNAMENSP
Definition: syscache.h:71

References activeSearchPath, _FuncCandidateList::argnumbers, _FuncCandidateList::args, Assert(), CStringGetDatum, DeconstructQualifiedName(), GETSTRUCT, i, InvalidOid, lfirst_oid, LookupExplicitNamespace(), catclist::members, myTempNamespace, catclist::n_members, _FuncCandidateList::nargs, _FuncCandidateList::ndargs, _FuncCandidateList::next, _FuncCandidateList::nominalnargs, _FuncCandidateList::nvargs, _FuncCandidateList::oid, OidIsValid, 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().

◆ OpernameGetOprid()

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

Definition at line 1529 of file namespace.c.

1530 {
1531  char *schemaname;
1532  char *opername;
1533  CatCList *catlist;
1534  ListCell *l;
1535 
1536  /* deconstruct the name list */
1537  DeconstructQualifiedName(names, &schemaname, &opername);
1538 
1539  if (schemaname)
1540  {
1541  /* search only in exact schema given */
1542  Oid namespaceId;
1543 
1544  namespaceId = LookupExplicitNamespace(schemaname, true);
1545  if (OidIsValid(namespaceId))
1546  {
1547  HeapTuple opertup;
1548 
1549  opertup = SearchSysCache4(OPERNAMENSP,
1550  CStringGetDatum(opername),
1551  ObjectIdGetDatum(oprleft),
1552  ObjectIdGetDatum(oprright),
1553  ObjectIdGetDatum(namespaceId));
1554  if (HeapTupleIsValid(opertup))
1555  {
1556  Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup);
1557  Oid result = operclass->oid;
1558 
1559  ReleaseSysCache(opertup);
1560  return result;
1561  }
1562  }
1563 
1564  return InvalidOid;
1565  }
1566 
1567  /* Search syscache by name and argument types */
1568  catlist = SearchSysCacheList3(OPERNAMENSP,
1569  CStringGetDatum(opername),
1570  ObjectIdGetDatum(oprleft),
1571  ObjectIdGetDatum(oprright));
1572 
1573  if (catlist->n_members == 0)
1574  {
1575  /* no hope, fall out early */
1576  ReleaseSysCacheList(catlist);
1577  return InvalidOid;
1578  }
1579 
1580  /*
1581  * We have to find the list member that is first in the search path, if
1582  * there's more than one. This doubly-nested loop looks ugly, but in
1583  * practice there should usually be few catlist members.
1584  */
1586 
1587  foreach(l, activeSearchPath)
1588  {
1589  Oid namespaceId = lfirst_oid(l);
1590  int i;
1591 
1592  if (namespaceId == myTempNamespace)
1593  continue; /* do not look in temp namespace */
1594 
1595  for (i = 0; i < catlist->n_members; i++)
1596  {
1597  HeapTuple opertup = &catlist->members[i]->tuple;
1598  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1599 
1600  if (operform->oprnamespace == namespaceId)
1601  {
1602  Oid result = operform->oid;
1603 
1604  ReleaseSysCacheList(catlist);
1605  return result;
1606  }
1607  }
1608  }
1609 
1610  ReleaseSysCacheList(catlist);
1611  return InvalidOid;
1612 }
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1206
#define SearchSysCacheList3(cacheId, key1, key2, key3)
Definition: syscache.h:219

References activeSearchPath, 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().

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1962 of file namespace.c.

1963 {
1964  HeapTuple opftup;
1965  Form_pg_opfamily opfform;
1966  Oid opfnamespace;
1967  bool visible;
1968 
1969  opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
1970  if (!HeapTupleIsValid(opftup))
1971  elog(ERROR, "cache lookup failed for opfamily %u", opfid);
1972  opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
1973 
1975 
1976  /*
1977  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1978  * the system namespace are surely in the path and so we needn't even do
1979  * list_member_oid() for them.
1980  */
1981  opfnamespace = opfform->opfnamespace;
1982  if (opfnamespace != PG_CATALOG_NAMESPACE &&
1983  !list_member_oid(activeSearchPath, opfnamespace))
1984  visible = false;
1985  else
1986  {
1987  /*
1988  * If it is in the path, it might still not be visible; it could be
1989  * hidden by another opfamily of the same name earlier in the path. So
1990  * we must do a slow check to see if this opfamily would be found by
1991  * OpfamilynameGetOpfid.
1992  */
1993  char *opfname = NameStr(opfform->opfname);
1994 
1995  visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
1996  }
1997 
1998  ReleaseSysCache(opftup);
1999 
2000  return visible;
2001 }
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
Definition: namespace.c:1929
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
@ OPFAMILYOID
Definition: syscache.h:74

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1929 of file namespace.c.

1930 {
1931  Oid opfid;
1932  ListCell *l;
1933 
1935 
1936  foreach(l, activeSearchPath)
1937  {
1938  Oid namespaceId = lfirst_oid(l);
1939 
1940  if (namespaceId == myTempNamespace)
1941  continue; /* do not look in temp namespace */
1942 
1943  opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
1944  ObjectIdGetDatum(amid),
1945  PointerGetDatum(opfname),
1946  ObjectIdGetDatum(namespaceId));
1947  if (OidIsValid(opfid))
1948  return opfid;
1949  }
1950 
1951  /* Not found in path */
1952  return InvalidOid;
1953 }
@ OPFAMILYAMNAMENSP
Definition: syscache.h:73

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3465 of file namespace.c.

3466 {
3467  ListCell *lc,
3468  *lcp;
3469 
3471 
3472  /* Quick out if already known equal to active path. */
3473  if (path->generation == activePathGeneration)
3474  return true;
3475 
3476  /* We scan down the activeSearchPath to see if it matches the input. */
3478 
3479  /* If path->addTemp, first item should be my temp namespace. */
3480  if (path->addTemp)
3481  {
3482  if (lc && lfirst_oid(lc) == myTempNamespace)
3483  lc = lnext(activeSearchPath, lc);
3484  else
3485  return false;
3486  }
3487  /* If path->addCatalog, next item should be pg_catalog. */
3488  if (path->addCatalog)
3489  {
3490  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3491  lc = lnext(activeSearchPath, lc);
3492  else
3493  return false;
3494  }
3495  /* We should now be looking at the activeCreationNamespace. */
3496  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3497  return false;
3498  /* The remainder of activeSearchPath should match path->schemas. */
3499  foreach(lcp, path->schemas)
3500  {
3501  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3502  lc = lnext(activeSearchPath, lc);
3503  else
3504  return false;
3505  }
3506  if (lc)
3507  return false;
3508 
3509  /*
3510  * Update path->generation so that future tests will return quickly, so
3511  * long as the active search path doesn't change.
3512  */
3514 
3515  return true;
3516 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:341

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

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

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3603 of file namespace.c.

3604 {
3605  OverrideStackEntry *entry;
3606 
3607  /* Sanity checks. */
3608  if (overrideStack == NIL)
3609  elog(ERROR, "bogus PopOverrideSearchPath call");
3611  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3612  elog(ERROR, "bogus PopOverrideSearchPath call");
3613 
3614  /* Pop the stack and free storage. */
3616  list_free(entry->searchPath);
3617  pfree(entry);
3618 
3619  /* Activate the next level down. */
3620  if (overrideStack)
3621  {
3623  activeSearchPath = entry->searchPath;
3625  activeTempCreationPending = false; /* XXX is this OK? */
3626  }
3627  else
3628  {
3629  /* If not baseSearchPathValid, this is useless but harmless */
3633  }
3634 
3635  /* As above, the generation always increments. */
3637 }

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

Referenced by CreateSchemaCommand().

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3536 of file namespace.c.

3537 {
3538  OverrideStackEntry *entry;
3539  List *oidlist;
3540  Oid firstNS;
3541  MemoryContext oldcxt;
3542 
3543  /*
3544  * Copy the list for safekeeping, and insert implicitly-searched
3545  * namespaces as needed. This code should track recomputeNamespacePath.
3546  */
3548 
3549  oidlist = list_copy(newpath->schemas);
3550 
3551  /*
3552  * Remember the first member of the explicit list.
3553  */
3554  if (oidlist == NIL)
3555  firstNS = InvalidOid;
3556  else
3557  firstNS = linitial_oid(oidlist);
3558 
3559  /*
3560  * Add any implicitly-searched namespaces to the list. Note these go on
3561  * the front, not the back; also notice that we do not check USAGE
3562  * permissions for these.
3563  */
3564  if (newpath->addCatalog)
3565  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3566 
3567  if (newpath->addTemp && OidIsValid(myTempNamespace))
3568  oidlist = lcons_oid(myTempNamespace, oidlist);
3569 
3570  /*
3571  * Build the new stack entry, then insert it at the head of the list.
3572  */
3573  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3574  entry->searchPath = oidlist;
3575  entry->creationNamespace = firstNS;
3577 
3578  overrideStack = lcons(entry, overrideStack);
3579 
3580  /* And make it active. */
3581  activeSearchPath = entry->searchPath;
3583  activeTempCreationPending = false; /* XXX is this OK? */
3584 
3585  /*
3586  * We always increment activePathGeneration when pushing/popping an
3587  * override path. In current usage, these actions always change the
3588  * effective path state, so there's no value in checking to see if it
3589  * didn't change.
3590  */
3592 
3593  MemoryContextSwitchTo(oldcxt);
3594 }
List * lcons(void *datum, List *list)
Definition: list.c:494
List * lcons_oid(Oid datum, List *list)
Definition: list.c:530

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

Referenced by CreateSchemaCommand().

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 3041 of file namespace.c.

3042 {
3043  char *schemaname;
3044  Oid namespaceId;
3045 
3046  /* deconstruct the name list */
3047  DeconstructQualifiedName(names, &schemaname, objname_p);
3048 
3049  if (schemaname)
3050  {
3051  /* check for pg_temp alias */
3052  if (strcmp(schemaname, "pg_temp") == 0)
3053  {
3054  /* Initialize temp namespace */
3055  AccessTempTableNamespace(false);
3056  return myTempNamespace;
3057  }
3058  /* use exact schema given */
3059  namespaceId = get_namespace_oid(schemaname, false);
3060  /* we do not check for USAGE rights here! */
3061  }
3062  else
3063  {
3064  /* use the default creation namespace */
3067  {
3068  /* Need to initialize temp namespace */
3070  return myTempNamespace;
3071  }
3072  namespaceId = activeCreationNamespace;
3073  if (!OidIsValid(namespaceId))
3074  ereport(ERROR,
3075  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3076  errmsg("no schema has been selected to create in")));
3077  }
3078 
3079  return namespaceId;
3080 }

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

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

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 643 of file namespace.c.

644 {
645  switch (newRelation->relpersistence)
646  {
647  case RELPERSISTENCE_TEMP:
648  if (!isTempOrTempToastNamespace(nspid))
649  {
650  if (isAnyTempNamespace(nspid))
651  ereport(ERROR,
652  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
653  errmsg("cannot create relations in temporary schemas of other sessions")));
654  else
655  ereport(ERROR,
656  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
657  errmsg("cannot create temporary relation in non-temporary schema")));
658  }
659  break;
660  case RELPERSISTENCE_PERMANENT:
661  if (isTempOrTempToastNamespace(nspid))
662  newRelation->relpersistence = RELPERSISTENCE_TEMP;
663  else if (isAnyTempNamespace(nspid))
664  ereport(ERROR,
665  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
666  errmsg("cannot create relations in temporary schemas of other sessions")));
667  break;
668  default:
669  if (isAnyTempNamespace(nspid))
670  ereport(ERROR,
671  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
672  errmsg("only temporary relations may be created in temporary schemas")));
673  }
674 }
char relpersistence
Definition: primnodes.h:80

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 536 of file namespace.c.

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 451 of file namespace.c.

452 {
453  Oid namespaceId;
454 
455  /*
456  * We check the catalog name and then ignore it.
457  */
458  if (newRelation->catalogname)
459  {
460  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
461  ereport(ERROR,
462  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
463  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
464  newRelation->catalogname, newRelation->schemaname,
465  newRelation->relname)));
466  }
467 
468  if (newRelation->schemaname)
469  {
470  /* check for pg_temp alias */
471  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
472  {
473  /* Initialize temp namespace */
475  return myTempNamespace;
476  }
477  /* use exact schema given */
478  namespaceId = get_namespace_oid(newRelation->schemaname, false);
479  /* we do not check for USAGE rights here! */
480  }
481  else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
482  {
483  /* Initialize temp namespace */
485  return myTempNamespace;
486  }
487  else
488  {
489  /* use the default creation namespace */
492  {
493  /* Need to initialize temp namespace */
495  return myTempNamespace;
496  }
497  namespaceId = activeCreationNamespace;
498  if (!OidIsValid(namespaceId))
499  ereport(ERROR,
500  (errcode(ERRCODE_UNDEFINED_SCHEMA),
501  errmsg("no schema has been selected to create in")));
502  }
503 
504  /* Note: callers will check for CREATE rights when appropriate */
505 
506  return namespaceId;
507 }

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

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

◆ RangeVarGetRelidExtended()

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

Definition at line 238 of file namespace.c.

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

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

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

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 710 of file namespace.c.

711 {
712  HeapTuple reltup;
713  Form_pg_class relform;
714  Oid relnamespace;
715  bool visible;
716 
717  reltup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
718  if (!HeapTupleIsValid(reltup))
719  elog(ERROR, "cache lookup failed for relation %u", relid);
720  relform = (Form_pg_class) GETSTRUCT(reltup);
721 
723 
724  /*
725  * Quick check: if it ain't in the path at all, it ain't visible. Items in
726  * the system namespace are surely in the path and so we needn't even do
727  * list_member_oid() for them.
728  */
729  relnamespace = relform->relnamespace;
730  if (relnamespace != PG_CATALOG_NAMESPACE &&
731  !list_member_oid(activeSearchPath, relnamespace))
732  visible = false;
733  else
734  {
735  /*
736  * If it is in the path, it might still not be visible; it could be
737  * hidden by another relation of the same name earlier in the path. So
738  * we must do a slow check for conflicting relations.
739  */
740  char *relname = NameStr(relform->relname);
741  ListCell *l;
742 
743  visible = false;
744  foreach(l, activeSearchPath)
745  {
746  Oid namespaceId = lfirst_oid(l);
747 
748  if (namespaceId == relnamespace)
749  {
750  /* Found it first in path */
751  visible = true;
752  break;
753  }
754  if (OidIsValid(get_relname_relid(relname, namespaceId)))
755  {
756  /* Found something else first in path */
757  break;
758  }
759  }
760  }
761 
762  ReleaseSysCache(reltup);
763 
764  return visible;
765 }
NameData relname
Definition: pg_class.h:38
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
@ RELOID
Definition: syscache.h:89

References activeSearchPath, 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().

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 682 of file namespace.c.

683 {
684  Oid relid;
685  ListCell *l;
686 
688 
689  foreach(l, activeSearchPath)
690  {
691  Oid namespaceId = lfirst_oid(l);
692 
693  relid = get_relname_relid(relname, namespaceId);
694  if (OidIsValid(relid))
695  return relid;
696  }
697 
698  /* Not found in path */
699  return InvalidOid;
700 }

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

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

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4309 of file namespace.c.

4310 {
4313 }
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4263

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3375 of file namespace.c.

3376 {
3377  /* Worker should not have created its own namespaces ... */
3381 
3382  /* Assign same namespace OIDs that leader has */
3383  myTempNamespace = tempNamespaceId;
3384  myTempToastNamespace = tempToastNamespaceId;
3385 
3386  /*
3387  * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
3388  * Even if the namespace is new so far as the leader is concerned, it's
3389  * not new to the worker, and we certainly wouldn't want the worker trying
3390  * to destroy it.
3391  */
3392 
3393  baseSearchPathValid = false; /* may need to rebuild list */
3394 }

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

Referenced by ParallelWorkerMain().

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  relid)

Definition at line 2281 of file namespace.c.

2282 {
2283  HeapTuple stxtup;
2284  Form_pg_statistic_ext stxform;
2285  Oid stxnamespace;
2286  bool visible;
2287 
2288  stxtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(relid));
2289  if (!HeapTupleIsValid(stxtup))
2290  elog(ERROR, "cache lookup failed for statistics object %u", relid);
2291  stxform = (Form_pg_statistic_ext) GETSTRUCT(stxtup);
2292 
2294 
2295  /*
2296  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2297  * the system namespace are surely in the path and so we needn't even do
2298  * list_member_oid() for them.
2299  */
2300  stxnamespace = stxform->stxnamespace;
2301  if (stxnamespace != PG_CATALOG_NAMESPACE &&
2302  !list_member_oid(activeSearchPath, stxnamespace))
2303  visible = false;
2304  else
2305  {
2306  /*
2307  * If it is in the path, it might still not be visible; it could be
2308  * hidden by another statistics object of the same name earlier in the
2309  * path. So we must do a slow check for conflicting objects.
2310  */
2311  char *stxname = NameStr(stxform->stxname);
2312  ListCell *l;
2313 
2314  visible = false;
2315  foreach(l, activeSearchPath)
2316  {
2317  Oid namespaceId = lfirst_oid(l);
2318 
2319  if (namespaceId == stxnamespace)
2320  {
2321  /* Found it first in path */
2322  visible = true;
2323  break;
2324  }
2326  PointerGetDatum(stxname),
2327  ObjectIdGetDatum(namespaceId)))
2328  {
2329  /* Found something else first in path */
2330  break;
2331  }
2332  }
2333  }
2334 
2335  ReleaseSysCache(stxtup);
2336 
2337  return visible;
2338 }
FormData_pg_statistic_ext * Form_pg_statistic_ext
@ STATEXTOID
Definition: syscache.h:96
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:190

References activeSearchPath, 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().

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 2783 of file namespace.c.

2784 {
2785  HeapTuple tup;
2786  Form_pg_ts_config form;
2787  Oid namespace;
2788  bool visible;
2789 
2791  if (!HeapTupleIsValid(tup))
2792  elog(ERROR, "cache lookup failed for text search configuration %u",
2793  cfgid);
2794  form = (Form_pg_ts_config) GETSTRUCT(tup);
2795 
2797 
2798  /*
2799  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2800  * the system namespace are surely in the path and so we needn't even do
2801  * list_member_oid() for them.
2802  */
2803  namespace = form->cfgnamespace;
2804  if (namespace != PG_CATALOG_NAMESPACE &&
2805  !list_member_oid(activeSearchPath, namespace))
2806  visible = false;
2807  else
2808  {
2809  /*
2810  * If it is in the path, it might still not be visible; it could be
2811  * hidden by another configuration of the same name earlier in the
2812  * path. So we must do a slow check for conflicting configurations.
2813  */
2814  char *name = NameStr(form->cfgname);
2815  ListCell *l;
2816 
2817  visible = false;
2818  foreach(l, activeSearchPath)
2819  {
2820  Oid namespaceId = lfirst_oid(l);
2821 
2822  if (namespaceId == myTempNamespace)
2823  continue; /* do not look in temp namespace */
2824 
2825  if (namespaceId == namespace)
2826  {
2827  /* Found it first in path */
2828  visible = true;
2829  break;
2830  }
2833  ObjectIdGetDatum(namespaceId)))
2834  {
2835  /* Found something else first in path */
2836  break;
2837  }
2838  }
2839  }
2840 
2841  ReleaseSysCache(tup);
2842 
2843  return visible;
2844 }
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
@ TSCONFIGOID
Definition: syscache.h:106

References activeSearchPath, 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().

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2530 of file namespace.c.

2531 {
2532  HeapTuple tup;
2533  Form_pg_ts_dict form;
2534  Oid namespace;
2535  bool visible;
2536 
2537  tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
2538  if (!HeapTupleIsValid(tup))
2539  elog(ERROR, "cache lookup failed for text search dictionary %u",
2540  dictId);
2541  form = (Form_pg_ts_dict) GETSTRUCT(tup);
2542 
2544 
2545  /*
2546  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2547  * the system namespace are surely in the path and so we needn't even do
2548  * list_member_oid() for them.
2549  */
2550  namespace = form->dictnamespace;
2551  if (namespace != PG_CATALOG_NAMESPACE &&
2552  !list_member_oid(activeSearchPath, namespace))
2553  visible = false;
2554  else
2555  {
2556  /*
2557  * If it is in the path, it might still not be visible; it could be
2558  * hidden by another dictionary of the same name earlier in the path.
2559  * So we must do a slow check for conflicting dictionaries.
2560  */
2561  char *name = NameStr(form->dictname);
2562  ListCell *l;
2563 
2564  visible = false;
2565  foreach(l, activeSearchPath)
2566  {
2567  Oid namespaceId = lfirst_oid(l);
2568 
2569  if (namespaceId == myTempNamespace)
2570  continue; /* do not look in temp namespace */
2571 
2572  if (namespaceId == namespace)
2573  {
2574  /* Found it first in path */
2575  visible = true;
2576  break;
2577  }
2580  ObjectIdGetDatum(namespaceId)))
2581  {
2582  /* Found something else first in path */
2583  break;
2584  }
2585  }
2586  }
2587 
2588  ReleaseSysCache(tup);
2589 
2590  return visible;
2591 }
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:52
@ TSDICTOID
Definition: syscache.h:108

References activeSearchPath, 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().

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2404 of file namespace.c.

2405 {
2406  HeapTuple tup;
2407  Form_pg_ts_parser form;
2408  Oid namespace;
2409  bool visible;
2410 
2412  if (!HeapTupleIsValid(tup))
2413  elog(ERROR, "cache lookup failed for text search parser %u", prsId);
2414  form = (Form_pg_ts_parser) GETSTRUCT(tup);
2415 
2417 
2418  /*
2419  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2420  * the system namespace are surely in the path and so we needn't even do
2421  * list_member_oid() for them.
2422  */
2423  namespace = form->prsnamespace;
2424  if (namespace != PG_CATALOG_NAMESPACE &&
2425  !list_member_oid(activeSearchPath, namespace))
2426  visible = false;
2427  else
2428  {
2429  /*
2430  * If it is in the path, it might still not be visible; it could be
2431  * hidden by another parser of the same name earlier in the path. So
2432  * we must do a slow check for conflicting parsers.
2433  */
2434  char *name = NameStr(form->prsname);
2435  ListCell *l;
2436 
2437  visible = false;
2438  foreach(l, activeSearchPath)
2439  {
2440  Oid namespaceId = lfirst_oid(l);
2441 
2442  if (namespaceId == myTempNamespace)
2443  continue; /* do not look in temp namespace */
2444 
2445  if (namespaceId == namespace)
2446  {
2447  /* Found it first in path */
2448  visible = true;
2449  break;
2450  }
2453  ObjectIdGetDatum(namespaceId)))
2454  {
2455  /* Found something else first in path */
2456  break;
2457  }
2458  }
2459  }
2460 
2461  ReleaseSysCache(tup);
2462 
2463  return visible;
2464 }
FormData_pg_ts_parser * Form_pg_ts_parser
Definition: pg_ts_parser.h:55
@ TSPARSEROID
Definition: syscache.h:110

References activeSearchPath, 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().

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 2657 of file namespace.c.

2658 {
2659  HeapTuple tup;
2660  Form_pg_ts_template form;
2661  Oid namespace;
2662  bool visible;
2663 
2665  if (!HeapTupleIsValid(tup))
2666  elog(ERROR, "cache lookup failed for text search template %u", tmplId);
2667  form = (Form_pg_ts_template) GETSTRUCT(tup);
2668 
2670 
2671  /*
2672  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2673  * the system namespace are surely in the path and so we needn't even do
2674  * list_member_oid() for them.
2675  */
2676  namespace = form->tmplnamespace;
2677  if (namespace != PG_CATALOG_NAMESPACE &&
2678  !list_member_oid(activeSearchPath, namespace))
2679  visible = false;
2680  else
2681  {
2682  /*
2683  * If it is in the path, it might still not be visible; it could be
2684  * hidden by another template of the same name earlier in the path. So
2685  * we must do a slow check for conflicting templates.
2686  */
2687  char *name = NameStr(form->tmplname);
2688  ListCell *l;
2689 
2690  visible = false;
2691  foreach(l, activeSearchPath)
2692  {
2693  Oid namespaceId = lfirst_oid(l);
2694 
2695  if (namespaceId == myTempNamespace)
2696  continue; /* do not look in temp namespace */
2697 
2698  if (namespaceId == namespace)
2699  {
2700  /* Found it first in path */
2701  visible = true;
2702  break;
2703  }
2706  ObjectIdGetDatum(namespaceId)))
2707  {
2708  /* Found something else first in path */
2709  break;
2710  }
2711  }
2712  }
2713 
2714  ReleaseSysCache(tup);
2715 
2716  return visible;
2717 }
FormData_pg_ts_template * Form_pg_ts_template
@ TSTEMPLATEOID
Definition: syscache.h:112

References activeSearchPath, 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().

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 818 of file namespace.c.

819 {
820  HeapTuple typtup;
821  Form_pg_type typform;
822  Oid typnamespace;
823  bool visible;
824 
825  typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
826  if (!HeapTupleIsValid(typtup))
827  elog(ERROR, "cache lookup failed for type %u", typid);
828  typform = (Form_pg_type) GETSTRUCT(typtup);
829 
831 
832  /*
833  * Quick check: if it ain't in the path at all, it ain't visible. Items in
834  * the system namespace are surely in the path and so we needn't even do
835  * list_member_oid() for them.
836  */
837  typnamespace = typform->typnamespace;
838  if (typnamespace != PG_CATALOG_NAMESPACE &&
839  !list_member_oid(activeSearchPath, typnamespace))
840  visible = false;
841  else
842  {
843  /*
844  * If it is in the path, it might still not be visible; it could be
845  * hidden by another type of the same name earlier in the path. So we
846  * must do a slow check for conflicting types.
847  */
848  char *typname = NameStr(typform->typname);
849  ListCell *l;
850 
851  visible = false;
852  foreach(l, activeSearchPath)
853  {
854  Oid namespaceId = lfirst_oid(l);
855 
856  if (namespaceId == typnamespace)
857  {
858  /* Found it first in path */
859  visible = true;
860  break;
861  }
864  ObjectIdGetDatum(namespaceId)))
865  {
866  /* Found something else first in path */
867  break;
868  }
869  }
870  }
871 
872  ReleaseSysCache(typtup);
873 
874  return visible;
875 }
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
NameData typname
Definition: pg_type.h:41
@ TYPEOID
Definition: syscache.h:114
@ TYPENAMENSP
Definition: syscache.h:113

References activeSearchPath, 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().

◆ TypenameGetTypid()

Oid TypenameGetTypid ( const char *  typname)

Definition at line 773 of file namespace.c.

774 {
775  return TypenameGetTypidExtended(typname, true);
776 }
Oid TypenameGetTypidExtended(const char *typname, bool temp_ok)
Definition: namespace.c:786

References TypenameGetTypidExtended(), and typname.

◆ TypenameGetTypidExtended()

Oid TypenameGetTypidExtended ( const char *  typname,
bool  temp_ok 
)

Definition at line 786 of file namespace.c.

787 {
788  Oid typid;
789  ListCell *l;
790 
792 
793  foreach(l, activeSearchPath)
794  {
795  Oid namespaceId = lfirst_oid(l);
796 
797  if (!temp_ok && namespaceId == myTempNamespace)
798  continue; /* do not look in temp namespace */
799 
800  typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
802  ObjectIdGetDatum(namespaceId));
803  if (OidIsValid(typid))
804  return typid;
805  }
806 
807  /* Not found in path */
808  return InvalidOid;
809 }

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

Referenced by LookupTypeNameExtended(), and TypenameGetTypid().

Variable Documentation

◆ namespace_search_path

PGDLLIMPORT char* namespace_search_path
extern

Definition at line 199 of file namespace.c.

Referenced by recomputeNamespacePath().