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 *relation, LOCKMODE lockmode, Oid *existing_relation_id)
 
void RangeVarAdjustRelationPersistence (RangeVar *newRelation, Oid nspid)
 
Oid RelnameGetRelid (const char *relname)
 
bool RelationIsVisible (Oid relid)
 
Oid TypenameGetTypid (const char *typname)
 
Oid TypenameGetTypidExtended (const char *typname, bool temp_ok)
 
bool TypeIsVisible (Oid typid)
 
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok)
 
bool OperatorIsVisible (Oid oprid)
 
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
 
bool OpclassIsVisible (Oid opcid)
 
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
 
bool OpfamilyIsVisible (Oid opfid)
 
Oid CollationGetCollid (const char *collname)
 
bool CollationIsVisible (Oid collid)
 
Oid ConversionGetConid (const char *conname)
 
bool ConversionIsVisible (Oid conid)
 
Oid get_statistics_object_oid (List *names, bool missing_ok)
 
bool StatisticsObjIsVisible (Oid 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:239

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 4179 of file namespace.c.

4181 {
4182  OverrideStackEntry *entry;
4183 
4184  if (myTempNamespaceSubID == mySubid)
4185  {
4186  if (isCommit)
4187  myTempNamespaceSubID = parentSubid;
4188  else
4189  {
4191  /* TEMP namespace creation failed, so reset state */
4194  baseSearchPathValid = false; /* need to rebuild list */
4195 
4196  /*
4197  * Reset the temporary namespace flag in MyProc. We assume that
4198  * this operation is atomic.
4199  *
4200  * Because this subtransaction is aborting, the pg_namespace row
4201  * is not visible to anyone else anyway, but that doesn't matter:
4202  * it's not a problem if objects contained in this namespace are
4203  * removed concurrently.
4204  */
4206  }
4207  }
4208 
4209  /*
4210  * Clean up if someone failed to do PopOverrideSearchPath
4211  */
4212  while (overrideStack)
4213  {
4216  break;
4217  if (isCommit)
4218  elog(WARNING, "leaked override search path");
4220  list_free(entry->searchPath);
4221  pfree(entry);
4222  /* Always bump generation --- see note in recomputeNamespacePath */
4224  }
4225 
4226  /* Activate the next level down. */
4227  if (overrideStack)
4228  {
4230  activeSearchPath = entry->searchPath;
4232  activeTempCreationPending = false; /* XXX is this OK? */
4233 
4234  /*
4235  * It's probably unnecessary to bump generation here, but this should
4236  * not be a performance-critical case, so better to be over-cautious.
4237  */
4239  }
4240  else
4241  {
4242  /* If not baseSearchPathValid, this is useless but harmless */
4246 
4247  /*
4248  * If we popped an override stack entry, then we already bumped the
4249  * generation above. If we did not, then the above assignments did
4250  * nothing and we need not bump the generation.
4251  */
4252  }
4253 }
#define InvalidSubTransactionId
Definition: c.h:642
#define WARNING
Definition: elog.h:36
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:1456
static bool baseTempCreationPending
Definition: namespace.c:157
static Oid baseCreationNamespace
Definition: namespace.c:155
static Oid activeCreationNamespace
Definition: namespace.c:143
static List * activeSearchPath
Definition: namespace.c:140
static bool baseSearchPathValid
Definition: namespace.c:162
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:194
static Oid myTempToastNamespace
Definition: namespace.c:192
static List * overrideStack
Definition: namespace.c:173
static Oid myTempNamespace
Definition: namespace.c:190
static bool activeTempCreationPending
Definition: namespace.c:146
static uint64 activePathGeneration
Definition: namespace.c:149
static List * baseSearchPath
Definition: namespace.c:153
#define linitial(l)
Definition: pg_list.h:178
#define InvalidOid
Definition: postgres_ext.h:36
PGPROC * MyProc
Definition: proc.c:66
Oid tempNamespaceId
Definition: proc.h:201
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:914

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 4111 of file namespace.c.

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

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 3010 of file namespace.c.

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

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

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

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3280 of file namespace.c.

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

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 2057 of file namespace.c.

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

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

Referenced by CollationIsVisible().

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2091 of file namespace.c.

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

References activeSearchPath, CollationGetCollid(), collid, 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 2142 of file namespace.c.

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

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

Referenced by ConversionIsVisible().

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2174 of file namespace.c.

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

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

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 2852 of file namespace.c.

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

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

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4432 of file namespace.c.

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

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

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

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4472 of file namespace.c.

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

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 3757 of file namespace.c.

3758 {
3759  Oid proc;
3760  ListCell *l;
3761 
3763 
3764  foreach(l, activeSearchPath)
3765  {
3766  Oid namespaceId = lfirst_oid(l);
3767 
3768  if (namespaceId == myTempNamespace)
3769  continue; /* do not look in temp namespace */
3770 
3771  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3772  if (OidIsValid(proc))
3773  return proc;
3774  }
3775 
3776  /* Not found in path */
3777  return InvalidOid;
3778 }
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 952 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1456 of file namespace.c.

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

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

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

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

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 3702 of file namespace.c.

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

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

Referenced by get_object_address().

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2221 of file namespace.c.

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

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

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2469 of file namespace.c.

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

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

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

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

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(), and RevalidateCachedQuery().

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3317 of file namespace.c.

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

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 3356 of file namespace.c.

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

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3342 of file namespace.c.

3343 {
3345  return myTempToastNamespace;
3346 }

References Assert(), myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4373 of file namespace.c.

4374 {
4376  {
4377  /*
4378  * In bootstrap mode, the search path must be 'pg_catalog' so that
4379  * tables are created in the proper namespace; ignore the GUC setting.
4380  */
4381  MemoryContext oldcxt;
4382 
4384  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4385  MemoryContextSwitchTo(oldcxt);
4386  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4387  baseTempCreationPending = false;
4388  baseSearchPathValid = true;
4393  activePathGeneration++; /* pro forma */
4394  }
4395  else
4396  {
4397  /*
4398  * In normal mode, arrange for a callback on any syscache invalidation
4399  * of pg_namespace rows.
4400  */
4403  (Datum) 0);
4404  /* Force search path to be recomputed on next use */
4405  baseSearchPathValid = false;
4406  }
4407 }
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1519
MemoryContext TopMemoryContext
Definition: mcxt.c:141
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:414
Oid GetUserId(void)
Definition: miscinit.c:510
static Oid namespaceUser
Definition: namespace.c:159
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4414
#define list_make1_oid(x1)
Definition: pg_list.h:242
@ 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 3238 of file namespace.c.

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

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 3261 of file namespace.c.

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

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3200 of file namespace.c.

3201 {
3202  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3203  return true;
3204  return false;
3205 }

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 3224 of file namespace.c.

3225 {
3226  if (OidIsValid(myTempNamespace) &&
3227  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3228  return true;
3229  return false;
3230 }

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 3212 of file namespace.c.

3213 {
3214  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3215  return true;
3216  return false;
3217 }

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2979 of file namespace.c.

2980 {
2981  Oid namespaceId;
2982  AclResult aclresult;
2983 
2984  /* check for pg_temp alias */
2985  if (strcmp(nspname, "pg_temp") == 0)
2986  {
2987  /* Initialize temp namespace */
2988  AccessTempTableNamespace(false);
2989  return myTempNamespace;
2990  }
2991 
2992  namespaceId = get_namespace_oid(nspname, false);
2993 
2994  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
2995  if (aclresult != ACLCHECK_OK)
2996  aclcheck_error(aclresult, OBJECT_SCHEMA,
2997  nspname);
2998 
2999  return namespaceId;
3000 }
AclResult
Definition: acl.h:182
@ ACLCHECK_OK
Definition: acl.h:183
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2673
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3775
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3086
@ OBJECT_SCHEMA
Definition: parsenodes.h:2118
#define ACL_CREATE
Definition: parsenodes.h:92

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

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

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2936 of file namespace.c.

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

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

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

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2906 of file namespace.c.

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

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 3105 of file namespace.c.

3106 {
3107  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3108 
3109  switch (list_length(names))
3110  {
3111  case 1:
3112  rel->relname = strVal(linitial(names));
3113  break;
3114  case 2:
3115  rel->schemaname = strVal(linitial(names));
3116  rel->relname = strVal(lsecond(names));
3117  break;
3118  case 3:
3119  rel->catalogname = strVal(linitial(names));
3120  rel->schemaname = strVal(lsecond(names));
3121  rel->relname = strVal(lthird(names));
3122  break;
3123  default:
3124  ereport(ERROR,
3125  (errcode(ERRCODE_SYNTAX_ERROR),
3126  errmsg("improper relation name (too many dotted names): %s",
3127  NameListToString(names))));
3128  break;
3129  }
3130 
3131  return rel;
3132 }
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:425
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_multi_page_stats(), bt_page_items_internal(), bt_page_stats_internal(), convert_table_name(), currtid_byrelname(), generateSerialExtraStmts(), get_object_address_attrdef(), get_object_address_attribute(), get_object_address_publication_rel(), get_object_address_relobject(), get_raw_page_internal(), get_rel_from_relname(), get_relation_by_qualified_name(), nextval(), owningrel_does_not_exist_skipping(), pg_get_serial_sequence(), pg_get_viewdef_name(), pg_get_viewdef_name_ext(), pg_relpages(), pg_relpages_v1_5(), pgrowlocks(), pgstatindex(), pgstatindex_v1_5(), pgstattuple(), pgstattuple_v1_5(), process_owned_by(), regclassin(), RelationNameGetTupleDesc(), RemoveRelations(), row_security_active_name(), schema_does_not_exist_skipping(), and text_regclass().

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3179 of file namespace.c.

3180 {
3182  ListCell *l;
3183 
3184  initStringInfo(&string);
3185 
3186  foreach(l, names)
3187  {
3188  if (l != list_head(names))
3189  appendStringInfoChar(&string, '.');
3191  }
3192 
3193  return string.data;
3194 }
#define lfirst(lc)
Definition: pg_list.h:172
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
char string[11]
Definition: preproc-type.c:52
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11930
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 3145 of file namespace.c.

3146 {
3148  ListCell *l;
3149 
3150  initStringInfo(&string);
3151 
3152  foreach(l, names)
3153  {
3154  Node *name = (Node *) lfirst(l);
3155 
3156  if (l != list_head(names))
3157  appendStringInfoChar(&string, '.');
3158 
3159  if (IsA(name, String))
3160  appendStringInfoString(&string, strVal(name));
3161  else if (IsA(name, A_Star))
3162  appendStringInfoChar(&string, '*');
3163  else
3164  elog(ERROR, "unexpected node type in name list: %d",
3165  (int) nodeTag(name));
3166  }
3167 
3168  return string.data;
3169 }
const char * name
Definition: encode.c:571
#define IsA(nodeptr, _type_)
Definition: nodes.h:179
#define nodeTag(nodeptr)
Definition: nodes.h:133
Definition: nodes.h:129
Definition: value.h:64

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

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

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1876 of file namespace.c.

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

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

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 1790 of file namespace.c.

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

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

◆ OpernameGetOprid()

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

Definition at line 1526 of file namespace.c.

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

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(), and regoperatorin().

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1959 of file namespace.c.

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

1927 {
1928  Oid opfid;
1929  ListCell *l;
1930 
1932 
1933  foreach(l, activeSearchPath)
1934  {
1935  Oid namespaceId = lfirst_oid(l);
1936 
1937  if (namespaceId == myTempNamespace)
1938  continue; /* do not look in temp namespace */
1939 
1940  opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
1941  ObjectIdGetDatum(amid),
1942  PointerGetDatum(opfname),
1943  ObjectIdGetDatum(namespaceId));
1944  if (OidIsValid(opfid))
1945  return opfid;
1946  }
1947 
1948  /* Not found in path */
1949  return InvalidOid;
1950 }
@ 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 3462 of file namespace.c.

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

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 3604 of file namespace.c.

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

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.

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3537 of file namespace.c.

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

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 3038 of file namespace.c.

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

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 644 of file namespace.c.

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

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 537 of file namespace.c.

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 452 of file namespace.c.

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

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 239 of file namespace.c.

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

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

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

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 711 of file namespace.c.

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

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

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 4310 of file namespace.c.

4311 {
4314 }
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4264

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3372 of file namespace.c.

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

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

Referenced by ParallelWorkerMain().

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  relid)

Definition at line 2278 of file namespace.c.

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

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 2780 of file namespace.c.

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

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

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

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

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

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

References TypenameGetTypidExtended(), and typname.

◆ TypenameGetTypidExtended()

Oid TypenameGetTypidExtended ( const char *  typname,
bool  temp_ok 
)

Definition at line 787 of file namespace.c.

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

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 200 of file namespace.c.

Referenced by CreateSchemaCommand(), and recomputeNamespacePath().