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

Go to the source code of this file.

Data Structures

struct  _FuncCandidateList
 
struct  OverrideSearchPath
 

Macros

#define RangeVarGetRelid(relation, lockmode, missing_ok)
 

Typedefs

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

Enumerations

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

Functions

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

Variables

char * namespace_search_path
 

Macro Definition Documentation

◆ RangeVarGetRelid

Typedef Documentation

◆ FuncCandidateList

◆ OverrideSearchPath

◆ RangeVarGetRelidCallback

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

Definition at line 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:69

◆ 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:44

Function Documentation

◆ AtEOSubXact_Namespace()

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

Definition at line 4177 of file namespace.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

4179 {
4180  OverrideStackEntry *entry;
4181 
4182  if (myTempNamespaceSubID == mySubid)
4183  {
4184  if (isCommit)
4185  myTempNamespaceSubID = parentSubid;
4186  else
4187  {
4189  /* TEMP namespace creation failed, so reset state */
4192  baseSearchPathValid = false; /* need to rebuild list */
4193 
4194  /*
4195  * Reset the temporary namespace flag in MyProc. We assume that
4196  * this operation is atomic.
4197  *
4198  * Because this subtransaction is aborting, the pg_namespace row
4199  * is not visible to anyone else anyway, but that doesn't matter:
4200  * it's not a problem if objects contained in this namespace are
4201  * removed concurrently.
4202  */
4204  }
4205  }
4206 
4207  /*
4208  * Clean up if someone failed to do PopOverrideSearchPath
4209  */
4210  while (overrideStack)
4211  {
4214  break;
4215  if (isCommit)
4216  elog(WARNING, "leaked override search path");
4218  list_free(entry->searchPath);
4219  pfree(entry);
4220  /* Always bump generation --- see note in recomputeNamespacePath */
4222  }
4223 
4224  /* Activate the next level down. */
4225  if (overrideStack)
4226  {
4228  activeSearchPath = entry->searchPath;
4230  activeTempCreationPending = false; /* XXX is this OK? */
4231 
4232  /*
4233  * It's probably unnecessary to bump generation here, but this should
4234  * not be a performance-critical case, so better to be over-cautious.
4235  */
4237  }
4238  else
4239  {
4240  /* If not baseSearchPathValid, this is useless but harmless */
4244 
4245  /*
4246  * If we popped an override stack entry, then we already bumped the
4247  * generation above. If we did not, then the above assignments did
4248  * nothing and we need not bump the generation.
4249  */
4250  }
4251 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid tempNamespaceId
Definition: proc.h:157
PGPROC * MyProc
Definition: proc.c:68
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1169
#define linitial(l)
Definition: pg_list.h:174
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:151
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
#define InvalidSubTransactionId
Definition: c.h:593
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1391
#define elog(elevel,...)
Definition: elog.h:232
List * list_delete_first(List *list)
Definition: list.c:875

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4109 of file namespace.c.

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

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

4110 {
4111  /*
4112  * If we abort the transaction in which a temp namespace was selected,
4113  * we'll have to do any creation or cleanout work over again. So, just
4114  * forget the namespace entirely until next time. On the other hand, if
4115  * we commit then register an exit callback to clean out the temp tables
4116  * at backend shutdown. (We only want to register the callback once per
4117  * session, so this is a good place to do it.)
4118  */
4119  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
4120  {
4121  if (isCommit)
4123  else
4124  {
4127  baseSearchPathValid = false; /* need to rebuild list */
4128 
4129  /*
4130  * Reset the temporary namespace flag in MyProc. We assume that
4131  * this operation is atomic.
4132  *
4133  * Because this transaction is aborting, the pg_namespace row is
4134  * not visible to anyone else anyway, but that doesn't matter:
4135  * it's not a problem if objects contained in this namespace are
4136  * removed concurrently.
4137  */
4139  }
4141  }
4142 
4143  /*
4144  * Clean up if someone failed to do PopOverrideSearchPath
4145  */
4146  if (overrideStack)
4147  {
4148  if (isCommit)
4149  elog(WARNING, "leaked override search path");
4150  while (overrideStack)
4151  {
4152  OverrideStackEntry *entry;
4153 
4156  list_free(entry->searchPath);
4157  pfree(entry);
4158  }
4159  /* If not baseSearchPathValid, this is useless but harmless */
4163  /* Always bump generation --- see note in recomputeNamespacePath */
4165  }
4166 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid tempNamespaceId
Definition: proc.h:157
PGPROC * MyProc
Definition: proc.c:68
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1169
#define linitial(l)
Definition: pg_list.h:174
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:151
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidSubTransactionId
Definition: c.h:593
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1391
#define elog(elevel,...)
Definition: elog.h:232
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4288
List * list_delete_first(List *list)
Definition: list.c:875

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 3012 of file namespace.c.

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

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

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

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3282 of file namespace.c.

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

Referenced by do_autovacuum().

3283 {
3284  PGPROC *proc;
3285  int backendId;
3286 
3288 
3289  backendId = GetTempNamespaceBackendId(namespaceId);
3290 
3291  /* No such namespace, or its name shows it's not temp? */
3292  if (backendId == InvalidBackendId)
3293  return TEMP_NAMESPACE_NOT_TEMP;
3294 
3295  /* Is the backend alive? */
3296  proc = BackendIdGetProc(backendId);
3297  if (proc == NULL)
3298  return TEMP_NAMESPACE_IDLE;
3299 
3300  /* Is the backend connected to the same database we are looking at? */
3301  if (proc->databaseId != MyDatabaseId)
3302  return TEMP_NAMESPACE_IDLE;
3303 
3304  /* Does the backend own the temporary namespace? */
3305  if (proc->tempNamespaceId != namespaceId)
3306  return TEMP_NAMESPACE_IDLE;
3307 
3308  /* Yup, so namespace is busy */
3309  return TEMP_NAMESPACE_IN_USE;
3310 }
Oid tempNamespaceId
Definition: proc.h:157
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3319
#define OidIsValid(objectId)
Definition: c.h:710
Oid databaseId
Definition: proc.h:154
#define InvalidBackendId
Definition: backendid.h:23
Oid MyDatabaseId
Definition: globals.c:88
#define Assert(condition)
Definition: c.h:804
Definition: proc.h:121
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:376

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2059 of file namespace.c.

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

Referenced by CollationIsVisible().

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

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2093 of file namespace.c.

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

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

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

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2144 of file namespace.c.

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

Referenced by ConversionIsVisible().

2145 {
2146  Oid conid;
2147  ListCell *l;
2148 
2150 
2151  foreach(l, activeSearchPath)
2152  {
2153  Oid namespaceId = lfirst_oid(l);
2154 
2155  if (namespaceId == myTempNamespace)
2156  continue; /* do not look in temp namespace */
2157 
2158  conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2159  PointerGetDatum(conname),
2160  ObjectIdGetDatum(namespaceId));
2161  if (OidIsValid(conid))
2162  return conid;
2163  }
2164 
2165  /* Not found in path */
2166  return InvalidOid;
2167 }
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2176 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_conversion_is_visible().

2177 {
2178  HeapTuple contup;
2179  Form_pg_conversion conform;
2180  Oid connamespace;
2181  bool visible;
2182 
2183  contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
2184  if (!HeapTupleIsValid(contup))
2185  elog(ERROR, "cache lookup failed for conversion %u", conid);
2186  conform = (Form_pg_conversion) GETSTRUCT(contup);
2187 
2189 
2190  /*
2191  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2192  * the system namespace are surely in the path and so we needn't even do
2193  * list_member_oid() for them.
2194  */
2195  connamespace = conform->connamespace;
2196  if (connamespace != PG_CATALOG_NAMESPACE &&
2197  !list_member_oid(activeSearchPath, connamespace))
2198  visible = false;
2199  else
2200  {
2201  /*
2202  * If it is in the path, it might still not be visible; it could be
2203  * hidden by another conversion of the same name earlier in the path.
2204  * So we must do a slow check to see if this conversion would be found
2205  * by ConversionGetConid.
2206  */
2207  char *conname = NameStr(conform->conname);
2208 
2209  visible = (ConversionGetConid(conname) == conid);
2210  }
2211 
2212  ReleaseSysCache(contup);
2213 
2214  return visible;
2215 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
Oid ConversionGetConid(const char *conname)
Definition: namespace.c:2144
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:61
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3442 of file namespace.c.

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

Referenced by CopyCachedPlan().

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

◆ DeconstructQualifiedName()

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

Definition at line 2854 of file namespace.c.

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

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

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4428 of file namespace.c.

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

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

4429 {
4430  List *result;
4431 
4433 
4434  /*
4435  * If the temp namespace should be first, force it to exist. This is so
4436  * that callers can trust the result to reflect the actual default
4437  * creation namespace. It's a bit bogus to do this here, since
4438  * current_schema() is supposedly a stable function without side-effects,
4439  * but the alternatives seem worse.
4440  */
4442  {
4445  }
4446 
4447  result = list_copy(activeSearchPath);
4448  if (!includeImplicit)
4449  {
4450  while (result && linitial_oid(result) != activeCreationNamespace)
4451  result = list_delete_first(result);
4452  }
4453 
4454  return result;
4455 }
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3960
List * list_copy(const List *oldlist)
Definition: list.c:1418
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static Oid activeCreationNamespace
Definition: namespace.c:141
static bool activeTempCreationPending
Definition: namespace.c:144
#define linitial_oid(l)
Definition: pg_list.h:176
static List * activeSearchPath
Definition: namespace.c:138
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:875

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4468 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4469 {
4470  int count = 0;
4471  ListCell *l;
4472 
4474 
4475  foreach(l, activeSearchPath)
4476  {
4477  Oid namespaceId = lfirst_oid(l);
4478 
4479  if (namespaceId == myTempNamespace)
4480  continue; /* do not include temp namespace */
4481 
4482  if (count < sarray_len)
4483  sarray[count] = namespaceId;
4484  count++;
4485  }
4486 
4487  return count;
4488 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3755 of file namespace.c.

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

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

3756 {
3757  Oid proc;
3758  ListCell *l;
3759 
3761 
3762  foreach(l, activeSearchPath)
3763  {
3764  Oid namespaceId = lfirst_oid(l);
3765 
3766  if (namespaceId == myTempNamespace)
3767  continue; /* do not look in temp namespace */
3768 
3769  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3770  if (OidIsValid(proc))
3771  return proc;
3772  }
3773 
3774  /* Not found in path */
3775  return InvalidOid;
3776 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ FuncnameGetCandidates()

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

Definition at line 950 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1458 of file namespace.c.

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

Referenced by format_procedure_extended(), and pg_function_is_visible().

1459 {
1460  HeapTuple proctup;
1461  Form_pg_proc procform;
1462  Oid pronamespace;
1463  bool visible;
1464 
1465  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1466  if (!HeapTupleIsValid(proctup))
1467  elog(ERROR, "cache lookup failed for function %u", funcid);
1468  procform = (Form_pg_proc) GETSTRUCT(proctup);
1469 
1471 
1472  /*
1473  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1474  * the system namespace are surely in the path and so we needn't even do
1475  * list_member_oid() for them.
1476  */
1477  pronamespace = procform->pronamespace;
1478  if (pronamespace != PG_CATALOG_NAMESPACE &&
1479  !list_member_oid(activeSearchPath, pronamespace))
1480  visible = false;
1481  else
1482  {
1483  /*
1484  * If it is in the path, it might still not be visible; it could be
1485  * hidden by another proc of the same name and arguments earlier in
1486  * the path. So we must do a slow check to see if this is the same
1487  * proc that would be found by FuncnameGetCandidates.
1488  */
1489  char *proname = NameStr(procform->proname);
1490  int nargs = procform->pronargs;
1491  FuncCandidateList clist;
1492 
1493  visible = false;
1494 
1495  clist = FuncnameGetCandidates(list_make1(makeString(proname)),
1496  nargs, NIL, false, false, false, false);
1497 
1498  for (; clist; clist = clist->next)
1499  {
1500  if (memcmp(clist->args, procform->proargtypes.values,
1501  nargs * sizeof(Oid)) == 0)
1502  {
1503  /* Found the expected entry; is it the right proc? */
1504  visible = (clist->oid == funcid);
1505  break;
1506  }
1507  }
1508  }
1509 
1510  ReleaseSysCache(proctup);
1511 
1512  return visible;
1513 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:65
NameData proname
Definition: pg_proc.h:35
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define list_make1(x1)
Definition: pg_list.h:206
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:38
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
struct _FuncCandidateList * next
Definition: namespace.h:30
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
Definition: namespace.c:950
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3646 of file namespace.c.

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

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

3647 {
3648  char *schemaname;
3649  char *collation_name;
3650  int32 dbencoding = GetDatabaseEncoding();
3651  Oid namespaceId;
3652  Oid colloid;
3653  ListCell *l;
3654 
3655  /* deconstruct the name list */
3656  DeconstructQualifiedName(name, &schemaname, &collation_name);
3657 
3658  if (schemaname)
3659  {
3660  /* use exact schema given */
3661  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3662  if (missing_ok && !OidIsValid(namespaceId))
3663  return InvalidOid;
3664 
3665  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3666  if (OidIsValid(colloid))
3667  return colloid;
3668  }
3669  else
3670  {
3671  /* search for it in search path */
3673 
3674  foreach(l, activeSearchPath)
3675  {
3676  namespaceId = lfirst_oid(l);
3677 
3678  if (namespaceId == myTempNamespace)
3679  continue; /* do not look in temp namespace */
3680 
3681  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3682  if (OidIsValid(colloid))
3683  return colloid;
3684  }
3685  }
3686 
3687  /* Not found in path */
3688  if (!missing_ok)
3689  ereport(ERROR,
3690  (errcode(ERRCODE_UNDEFINED_OBJECT),
3691  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3693  return InvalidOid;
3694 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
signed int int32
Definition: c.h:429
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:2008
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
int GetDatabaseEncoding(void)
Definition: mbutils.c:1210
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1216
const char * name
Definition: encode.c:515
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 3700 of file namespace.c.

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

Referenced by get_object_address().

3701 {
3702  char *schemaname;
3703  char *conversion_name;
3704  Oid namespaceId;
3705  Oid conoid = InvalidOid;
3706  ListCell *l;
3707 
3708  /* deconstruct the name list */
3709  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3710 
3711  if (schemaname)
3712  {
3713  /* use exact schema given */
3714  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3715  if (missing_ok && !OidIsValid(namespaceId))
3716  conoid = InvalidOid;
3717  else
3718  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3719  PointerGetDatum(conversion_name),
3720  ObjectIdGetDatum(namespaceId));
3721  }
3722  else
3723  {
3724  /* search for it in search path */
3726 
3727  foreach(l, activeSearchPath)
3728  {
3729  namespaceId = lfirst_oid(l);
3730 
3731  if (namespaceId == myTempNamespace)
3732  continue; /* do not look in temp namespace */
3733 
3734  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3735  PointerGetDatum(conversion_name),
3736  ObjectIdGetDatum(namespaceId));
3737  if (OidIsValid(conoid))
3738  return conoid;
3739  }
3740  }
3741 
3742  /* Not found in path */
3743  if (!OidIsValid(conoid) && !missing_ok)
3744  ereport(ERROR,
3745  (errcode(ERRCODE_UNDEFINED_OBJECT),
3746  errmsg("conversion \"%s\" does not exist",
3747  NameListToString(name))));
3748  return conoid;
3749 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
const char * name
Definition: encode.c:515
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

Definition at line 3088 of file namespace.c.

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

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

3089 {
3090  Oid oid;
3091 
3092  oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid,
3093  CStringGetDatum(nspname));
3094  if (!OidIsValid(oid) && !missing_ok)
3095  ereport(ERROR,
3096  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3097  errmsg("schema \"%s\" does not exist", nspname)));
3098 
3099  return oid;
3100 }
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:193
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
#define CStringGetDatum(X)
Definition: postgres.h:622
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2223 of file namespace.c.

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

Referenced by AlterStatistics(), and get_object_address().

2224 {
2225  char *schemaname;
2226  char *stats_name;
2227  Oid namespaceId;
2228  Oid stats_oid = InvalidOid;
2229  ListCell *l;
2230 
2231  /* deconstruct the name list */
2232  DeconstructQualifiedName(names, &schemaname, &stats_name);
2233 
2234  if (schemaname)
2235  {
2236  /* use exact schema given */
2237  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2238  if (missing_ok && !OidIsValid(namespaceId))
2239  stats_oid = InvalidOid;
2240  else
2241  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2242  PointerGetDatum(stats_name),
2243  ObjectIdGetDatum(namespaceId));
2244  }
2245  else
2246  {
2247  /* search for it in search path */
2249 
2250  foreach(l, activeSearchPath)
2251  {
2252  namespaceId = lfirst_oid(l);
2253 
2254  if (namespaceId == myTempNamespace)
2255  continue; /* do not look in temp namespace */
2256  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2257  PointerGetDatum(stats_name),
2258  ObjectIdGetDatum(namespaceId));
2259  if (OidIsValid(stats_oid))
2260  break;
2261  }
2262  }
2263 
2264  if (!OidIsValid(stats_oid) && !missing_ok)
2265  ereport(ERROR,
2266  (errcode(ERRCODE_UNDEFINED_OBJECT),
2267  errmsg("statistics object \"%s\" does not exist",
2268  NameListToString(names))));
2269 
2270  return stats_oid;
2271 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2724 of file namespace.c.

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

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

2725 {
2726  char *schemaname;
2727  char *config_name;
2728  Oid namespaceId;
2729  Oid cfgoid = InvalidOid;
2730  ListCell *l;
2731 
2732  /* deconstruct the name list */
2733  DeconstructQualifiedName(names, &schemaname, &config_name);
2734 
2735  if (schemaname)
2736  {
2737  /* use exact schema given */
2738  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2739  if (missing_ok && !OidIsValid(namespaceId))
2740  cfgoid = InvalidOid;
2741  else
2742  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2743  PointerGetDatum(config_name),
2744  ObjectIdGetDatum(namespaceId));
2745  }
2746  else
2747  {
2748  /* search for it in search path */
2750 
2751  foreach(l, activeSearchPath)
2752  {
2753  namespaceId = lfirst_oid(l);
2754 
2755  if (namespaceId == myTempNamespace)
2756  continue; /* do not look in temp namespace */
2757 
2758  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2759  PointerGetDatum(config_name),
2760  ObjectIdGetDatum(namespaceId));
2761  if (OidIsValid(cfgoid))
2762  break;
2763  }
2764  }
2765 
2766  if (!OidIsValid(cfgoid) && !missing_ok)
2767  ereport(ERROR,
2768  (errcode(ERRCODE_UNDEFINED_OBJECT),
2769  errmsg("text search configuration \"%s\" does not exist",
2770  NameListToString(names))));
2771 
2772  return cfgoid;
2773 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2471 of file namespace.c.

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

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

2472 {
2473  char *schemaname;
2474  char *dict_name;
2475  Oid namespaceId;
2476  Oid dictoid = InvalidOid;
2477  ListCell *l;
2478 
2479  /* deconstruct the name list */
2480  DeconstructQualifiedName(names, &schemaname, &dict_name);
2481 
2482  if (schemaname)
2483  {
2484  /* use exact schema given */
2485  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2486  if (missing_ok && !OidIsValid(namespaceId))
2487  dictoid = InvalidOid;
2488  else
2489  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2490  PointerGetDatum(dict_name),
2491  ObjectIdGetDatum(namespaceId));
2492  }
2493  else
2494  {
2495  /* search for it in search path */
2497 
2498  foreach(l, activeSearchPath)
2499  {
2500  namespaceId = lfirst_oid(l);
2501 
2502  if (namespaceId == myTempNamespace)
2503  continue; /* do not look in temp namespace */
2504 
2505  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2506  PointerGetDatum(dict_name),
2507  ObjectIdGetDatum(namespaceId));
2508  if (OidIsValid(dictoid))
2509  break;
2510  }
2511  }
2512 
2513  if (!OidIsValid(dictoid) && !missing_ok)
2514  ereport(ERROR,
2515  (errcode(ERRCODE_UNDEFINED_OBJECT),
2516  errmsg("text search dictionary \"%s\" does not exist",
2517  NameListToString(names))));
2518 
2519  return dictoid;
2520 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2345 of file namespace.c.

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

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

2346 {
2347  char *schemaname;
2348  char *parser_name;
2349  Oid namespaceId;
2350  Oid prsoid = InvalidOid;
2351  ListCell *l;
2352 
2353  /* deconstruct the name list */
2354  DeconstructQualifiedName(names, &schemaname, &parser_name);
2355 
2356  if (schemaname)
2357  {
2358  /* use exact schema given */
2359  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2360  if (missing_ok && !OidIsValid(namespaceId))
2361  prsoid = InvalidOid;
2362  else
2363  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2364  PointerGetDatum(parser_name),
2365  ObjectIdGetDatum(namespaceId));
2366  }
2367  else
2368  {
2369  /* search for it in search path */
2371 
2372  foreach(l, activeSearchPath)
2373  {
2374  namespaceId = lfirst_oid(l);
2375 
2376  if (namespaceId == myTempNamespace)
2377  continue; /* do not look in temp namespace */
2378 
2379  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2380  PointerGetDatum(parser_name),
2381  ObjectIdGetDatum(namespaceId));
2382  if (OidIsValid(prsoid))
2383  break;
2384  }
2385  }
2386 
2387  if (!OidIsValid(prsoid) && !missing_ok)
2388  ereport(ERROR,
2389  (errcode(ERRCODE_UNDEFINED_OBJECT),
2390  errmsg("text search parser \"%s\" does not exist",
2391  NameListToString(names))));
2392 
2393  return prsoid;
2394 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2598 of file namespace.c.

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

Referenced by DefineTSDictionary(), and get_object_address().

2599 {
2600  char *schemaname;
2601  char *template_name;
2602  Oid namespaceId;
2603  Oid tmploid = InvalidOid;
2604  ListCell *l;
2605 
2606  /* deconstruct the name list */
2607  DeconstructQualifiedName(names, &schemaname, &template_name);
2608 
2609  if (schemaname)
2610  {
2611  /* use exact schema given */
2612  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2613  if (missing_ok && !OidIsValid(namespaceId))
2614  tmploid = InvalidOid;
2615  else
2616  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2617  PointerGetDatum(template_name),
2618  ObjectIdGetDatum(namespaceId));
2619  }
2620  else
2621  {
2622  /* search for it in search path */
2624 
2625  foreach(l, activeSearchPath)
2626  {
2627  namespaceId = lfirst_oid(l);
2628 
2629  if (namespaceId == myTempNamespace)
2630  continue; /* do not look in temp namespace */
2631 
2632  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2633  PointerGetDatum(template_name),
2634  ObjectIdGetDatum(namespaceId));
2635  if (OidIsValid(tmploid))
2636  break;
2637  }
2638  }
2639 
2640  if (!OidIsValid(tmploid) && !missing_ok)
2641  ereport(ERROR,
2642  (errcode(ERRCODE_UNDEFINED_OBJECT),
2643  errmsg("text search template \"%s\" does not exist",
2644  NameListToString(names))));
2645 
2646  return tmploid;
2647 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3405 of file namespace.c.

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

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

3406 {
3407  OverrideSearchPath *result;
3408  List *schemas;
3409  MemoryContext oldcxt;
3410 
3412 
3413  oldcxt = MemoryContextSwitchTo(context);
3414 
3415  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3416  schemas = list_copy(activeSearchPath);
3417  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3418  {
3419  if (linitial_oid(schemas) == myTempNamespace)
3420  result->addTemp = true;
3421  else
3422  {
3423  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3424  result->addCatalog = true;
3425  }
3426  schemas = list_delete_first(schemas);
3427  }
3428  result->schemas = schemas;
3429  result->generation = activePathGeneration;
3430 
3431  MemoryContextSwitchTo(oldcxt);
3432 
3433  return result;
3434 }
static Oid myTempNamespace
Definition: namespace.c:188
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * list_copy(const List *oldlist)
Definition: list.c:1418
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
void * palloc0(Size size)
Definition: mcxt.c:1093
#define Assert(condition)
Definition: c.h:804
#define linitial_oid(l)
Definition: pg_list.h:176
static List * activeSearchPath
Definition: namespace.c:138
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:875

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3319 of file namespace.c.

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

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

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

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3358 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3359 {
3360  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3361  *tempNamespaceId = myTempNamespace;
3362  *tempToastNamespaceId = myTempToastNamespace;
3363 }
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3344 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3345 {
3347  return myTempToastNamespace;
3348 }
static Oid myTempToastNamespace
Definition: namespace.c:190
#define OidIsValid(objectId)
Definition: c.h:710
#define Assert(condition)
Definition: c.h:804

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4369 of file namespace.c.

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

Referenced by InitPostgres().

4370 {
4372  {
4373  /*
4374  * In bootstrap mode, the search path must be 'pg_catalog' so that
4375  * tables are created in the proper namespace; ignore the GUC setting.
4376  */
4377  MemoryContext oldcxt;
4378 
4380  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4381  MemoryContextSwitchTo(oldcxt);
4382  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4383  baseTempCreationPending = false;
4384  baseSearchPathValid = true;
4389  activePathGeneration++; /* pro forma */
4390  }
4391  else
4392  {
4393  /*
4394  * In normal mode, arrange for a callback on any syscache invalidation
4395  * of pg_namespace rows.
4396  */
4399  (Datum) 0);
4400  /* Force search path to be recomputed on next use */
4401  baseSearchPathValid = false;
4402  }
4403 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid GetUserId(void)
Definition: miscinit.c:478
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static Oid namespaceUser
Definition: namespace.c:157
static Oid activeCreationNamespace
Definition: namespace.c:141
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4410
static bool activeTempCreationPending
Definition: namespace.c:144
MemoryContext TopMemoryContext
Definition: mcxt.c:48
static Oid baseCreationNamespace
Definition: namespace.c:153
static List * baseSearchPath
Definition: namespace.c:151
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1435
uintptr_t Datum
Definition: postgres.h:411
#define list_make1_oid(x1)
Definition: pg_list.h:236
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406
static List * activeSearchPath
Definition: namespace.c:138

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3240 of file namespace.c.

References get_namespace_name(), and pfree().

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

3241 {
3242  bool result;
3243  char *nspname;
3244 
3245  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3246  nspname = get_namespace_name(namespaceId);
3247  if (!nspname)
3248  return false; /* no such namespace? */
3249  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3250  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3251  pfree(nspname);
3252  return result;
3253 }
void pfree(void *pointer)
Definition: mcxt.c:1169
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3316

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3263 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

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

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3202 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

3203 {
3204  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3205  return true;
3206  return false;
3207 }
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:710

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3226 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

3227 {
3228  if (OidIsValid(myTempNamespace) &&
3229  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3230  return true;
3231  return false;
3232 }
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:710

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3214 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

3215 {
3216  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3217  return true;
3218  return false;
3219 }
static Oid myTempToastNamespace
Definition: namespace.c:190
#define OidIsValid(objectId)
Definition: c.h:710

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2981 of file namespace.c.

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

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

2982 {
2983  Oid namespaceId;
2984  AclResult aclresult;
2985 
2986  /* check for pg_temp alias */
2987  if (strcmp(nspname, "pg_temp") == 0)
2988  {
2989  /* Initialize temp namespace */
2990  AccessTempTableNamespace(false);
2991  return myTempNamespace;
2992  }
2993 
2994  namespaceId = get_namespace_oid(nspname, false);
2995 
2996  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2997  if (aclresult != ACLCHECK_OK)
2998  aclcheck_error(aclresult, OBJECT_SCHEMA,
2999  nspname);
3000 
3001  return namespaceId;
3002 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3960
Oid GetUserId(void)
Definition: miscinit.c:478
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4756
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3308
#define ACL_CREATE
Definition: parsenodes.h:92
AclResult
Definition: acl.h:177

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2938 of file namespace.c.

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

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

2939 {
2940  Oid namespaceId;
2941  AclResult aclresult;
2942 
2943  /* check for pg_temp alias */
2944  if (strcmp(nspname, "pg_temp") == 0)
2945  {
2947  return myTempNamespace;
2948 
2949  /*
2950  * Since this is used only for looking up existing objects, there is
2951  * no point in trying to initialize the temp namespace here; and doing
2952  * so might create problems for some callers --- just fall through.
2953  */
2954  }
2955 
2956  namespaceId = get_namespace_oid(nspname, missing_ok);
2957  if (missing_ok && !OidIsValid(namespaceId))
2958  return InvalidOid;
2959 
2960  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
2961  if (aclresult != ACLCHECK_OK)
2962  aclcheck_error(aclresult, OBJECT_SCHEMA,
2963  nspname);
2964  /* Schema search hook for this lookup */
2965  InvokeNamespaceSearchHook(namespaceId, true);
2966 
2967  return namespaceId;
2968 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
Oid GetUserId(void)
Definition: miscinit.c:478
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4756
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:186
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3308
#define ACL_USAGE
Definition: parsenodes.h:90
AclResult
Definition: acl.h:177
#define InvalidOid
Definition: postgres_ext.h:36

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2908 of file namespace.c.

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

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

2909 {
2910  /* check for pg_temp alias */
2911  if (strcmp(nspname, "pg_temp") == 0)
2912  {
2914  {
2916  return myTempNamespace;
2917  }
2918 
2919  /*
2920  * Since this is used only for looking up existing objects, there is
2921  * no point in trying to initialize the temp namespace here; and doing
2922  * so might create problems for some callers. Just report "not found".
2923  */
2924  return InvalidOid;
2925  }
2926 
2927  return get_namespace_oid(nspname, true);
2928 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:710
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:186
#define InvalidOid
Definition: postgres_ext.h:36

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 3107 of file namespace.c.

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

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

3108 {
3109  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3110 
3111  switch (list_length(names))
3112  {
3113  case 1:
3114  rel->relname = strVal(linitial(names));
3115  break;
3116  case 2:
3117  rel->schemaname = strVal(linitial(names));
3118  rel->relname = strVal(lsecond(names));
3119  break;
3120  case 3:
3121  rel->catalogname = strVal(linitial(names));
3122  rel->schemaname = strVal(lsecond(names));
3123  rel->relname = strVal(lthird(names));
3124  break;
3125  default:
3126  ereport(ERROR,
3127  (errcode(ERRCODE_SYNTAX_ERROR),
3128  errmsg("improper relation name (too many dotted names): %s",
3129  NameListToString(names))));
3130  break;
3131  }
3132 
3133  return rel;
3134 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:698
#define lsecond(l)
Definition: pg_list.h:179
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define ereport(elevel,...)
Definition: elog.h:157
static int list_length(const List *l)
Definition: pg_list.h:149
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lthird(l)
Definition: pg_list.h:184
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:422
char * catalogname
Definition: primnodes.h:66

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3181 of file namespace.c.

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

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

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3147 of file namespace.c.

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

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

3148 {
3150  ListCell *l;
3151 
3152  initStringInfo(&string);
3153 
3154  foreach(l, names)
3155  {
3156  Node *name = (Node *) lfirst(l);
3157 
3158  if (l != list_head(names))
3159  appendStringInfoChar(&string, '.');
3160 
3161  if (IsA(name, String))
3162  appendStringInfoString(&string, strVal(name));
3163  else if (IsA(name, A_Star))
3164  appendStringInfoChar(&string, '*');
3165  else
3166  elog(ERROR, "unexpected node type in name list: %d",
3167  (int) nodeTag(name));
3168  }
3169 
3170  return string.data;
3171 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:590
Definition: nodes.h:539
#define strVal(v)
Definition: value.h:54
#define ERROR
Definition: elog.h:46
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define lfirst(lc)
Definition: pg_list.h:169
const char * name
Definition: encode.c:515
#define nodeTag(nodeptr)
Definition: nodes.h:544
#define elog(elevel,...)
Definition: elog.h:232

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1878 of file namespace.c.

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

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

1879 {
1880  HeapTuple opctup;
1881  Form_pg_opclass opcform;
1882  Oid opcnamespace;
1883  bool visible;
1884 
1885  opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
1886  if (!HeapTupleIsValid(opctup))
1887  elog(ERROR, "cache lookup failed for opclass %u", opcid);
1888  opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1889 
1891 
1892  /*
1893  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1894  * the system namespace are surely in the path and so we needn't even do
1895  * list_member_oid() for them.
1896  */
1897  opcnamespace = opcform->opcnamespace;
1898  if (opcnamespace != PG_CATALOG_NAMESPACE &&
1899  !list_member_oid(activeSearchPath, opcnamespace))
1900  visible = false;
1901  else
1902  {
1903  /*
1904  * If it is in the path, it might still not be visible; it could be
1905  * hidden by another opclass of the same name earlier in the path. So
1906  * we must do a slow check to see if this opclass would be found by
1907  * OpclassnameGetOpcid.
1908  */
1909  char *opcname = NameStr(opcform->opcname);
1910 
1911  visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1912  }
1913 
1914  ReleaseSysCache(opctup);
1915 
1916  return visible;
1917 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
unsigned int Oid
Definition: postgres_ext.h:31
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
Definition: namespace.c:1845
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1845 of file namespace.c.

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

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

1846 {
1847  Oid opcid;
1848  ListCell *l;
1849 
1851 
1852  foreach(l, activeSearchPath)
1853  {
1854  Oid namespaceId = lfirst_oid(l);
1855 
1856  if (namespaceId == myTempNamespace)
1857  continue; /* do not look in temp namespace */
1858 
1859  opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
1860  ObjectIdGetDatum(amid),
1861  PointerGetDatum(opcname),
1862  ObjectIdGetDatum(namespaceId));
1863  if (OidIsValid(opcid))
1864  return opcid;
1865  }
1866 
1867  /* Not found in path */
1868  return InvalidOid;
1869 }
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:197
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1792 of file namespace.c.

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

Referenced by format_operator_extended(), and pg_operator_is_visible().

1793 {
1794  HeapTuple oprtup;
1795  Form_pg_operator oprform;
1796  Oid oprnamespace;
1797  bool visible;
1798 
1800  if (!HeapTupleIsValid(oprtup))
1801  elog(ERROR, "cache lookup failed for operator %u", oprid);
1802  oprform = (Form_pg_operator) GETSTRUCT(oprtup);
1803 
1805 
1806  /*
1807  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1808  * the system namespace are surely in the path and so we needn't even do
1809  * list_member_oid() for them.
1810  */
1811  oprnamespace = oprform->oprnamespace;
1812  if (oprnamespace != PG_CATALOG_NAMESPACE &&
1813  !list_member_oid(activeSearchPath, oprnamespace))
1814  visible = false;
1815  else
1816  {
1817  /*
1818  * If it is in the path, it might still not be visible; it could be
1819  * hidden by another operator of the same name and arguments earlier
1820  * in the path. So we must do a slow check to see if this is the same
1821  * operator that would be found by OpernameGetOprid.
1822  */
1823  char *oprname = NameStr(oprform->oprname);
1824 
1825  visible = (OpernameGetOprid(list_make1(makeString(oprname)),
1826  oprform->oprleft, oprform->oprright)
1827  == oprid);
1828  }
1829 
1830  ReleaseSysCache(oprtup);
1831 
1832  return visible;
1833 }
Value * makeString(char *str)
Definition: value.c:53
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
Oid oprid(Operator op)
Definition: parse_oper.c:250
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define list_make1(x1)
Definition: pg_list.h:206
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1528
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681

◆ OpernameGetCandidates()

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

Definition at line 1631 of file namespace.c.

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

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

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

◆ OpernameGetOprid()

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

Definition at line 1528 of file namespace.c.

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

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

1529 {
1530  char *schemaname;
1531  char *opername;
1532  CatCList *catlist;
1533  ListCell *l;
1534 
1535  /* deconstruct the name list */
1536  DeconstructQualifiedName(names, &schemaname, &opername);
1537 
1538  if (schemaname)
1539  {
1540  /* search only in exact schema given */
1541  Oid namespaceId;
1542 
1543  namespaceId = LookupExplicitNamespace(schemaname, true);
1544  if (OidIsValid(namespaceId))
1545  {
1546  HeapTuple opertup;
1547 
1548  opertup = SearchSysCache4(OPERNAMENSP,
1549  CStringGetDatum(opername),
1550  ObjectIdGetDatum(oprleft),
1551  ObjectIdGetDatum(oprright),
1552  ObjectIdGetDatum(namespaceId));
1553  if (HeapTupleIsValid(opertup))
1554  {
1555  Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup);
1556  Oid result = operclass->oid;
1557 
1558  ReleaseSysCache(opertup);
1559  return result;
1560  }
1561  }
1562 
1563  return InvalidOid;
1564  }
1565 
1566  /* Search syscache by name and argument types */
1567  catlist = SearchSysCacheList3(OPERNAMENSP,
1568  CStringGetDatum(opername),
1569  ObjectIdGetDatum(oprleft),
1570  ObjectIdGetDatum(oprright));
1571 
1572  if (catlist->n_members == 0)
1573  {
1574  /* no hope, fall out early */
1575  ReleaseSysCacheList(catlist);
1576  return InvalidOid;
1577  }
1578 
1579  /*
1580  * We have to find the list member that is first in the search path, if
1581  * there's more than one. This doubly-nested loop looks ugly, but in
1582  * practice there should usually be few catlist members.
1583  */
1585 
1586  foreach(l, activeSearchPath)
1587  {
1588  Oid namespaceId = lfirst_oid(l);
1589  int i;
1590 
1591  if (namespaceId == myTempNamespace)
1592  continue; /* do not look in temp namespace */
1593 
1594  for (i = 0; i < catlist->n_members; i++)
1595  {
1596  HeapTuple opertup = &catlist->members[i]->tuple;
1597  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1598 
1599  if (operform->oprnamespace == namespaceId)
1600  {
1601  Oid result = operform->oid;
1602 
1603  ReleaseSysCacheList(catlist);
1604  return result;
1605  }
1606  }
1607  }
1608 
1609  ReleaseSysCacheList(catlist);
1610  return InvalidOid;
1611 }
int n_members
Definition: catcache.h:176
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
static Oid myTempNamespace
Definition: namespace.c:188
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define CStringGetDatum(X)
Definition: postgres.h:622
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1160
#define ReleaseSysCacheList(x)
Definition: syscache.h:218
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
static List * activeSearchPath
Definition: namespace.c:138
#define SearchSysCacheList3(cacheId, key1, key2, key3)
Definition: syscache.h:215
int i
HeapTupleData tuple
Definition: catcache.h:121
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1961 of file namespace.c.

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

1962 {
1963  HeapTuple opftup;
1964  Form_pg_opfamily opfform;
1965  Oid opfnamespace;
1966  bool visible;
1967 
1968  opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
1969  if (!HeapTupleIsValid(opftup))
1970  elog(ERROR, "cache lookup failed for opfamily %u", opfid);
1971  opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
1972 
1974 
1975  /*
1976  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1977  * the system namespace are surely in the path and so we needn't even do
1978  * list_member_oid() for them.
1979  */
1980  opfnamespace = opfform->opfnamespace;
1981  if (opfnamespace != PG_CATALOG_NAMESPACE &&
1982  !list_member_oid(activeSearchPath, opfnamespace))
1983  visible = false;
1984  else
1985  {
1986  /*
1987  * If it is in the path, it might still not be visible; it could be
1988  * hidden by another opfamily of the same name earlier in the path. So
1989  * we must do a slow check to see if this opfamily would be found by
1990  * OpfamilynameGetOpfid.
1991  */
1992  char *opfname = NameStr(opfform->opfname);
1993 
1994  visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
1995  }
1996 
1997  ReleaseSysCache(opftup);
1998 
1999  return visible;
2000 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
Definition: namespace.c:1928
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1928 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

1929 {
1930  Oid opfid;
1931  ListCell *l;
1932 
1934 
1935  foreach(l, activeSearchPath)
1936  {
1937  Oid namespaceId = lfirst_oid(l);
1938 
1939  if (namespaceId == myTempNamespace)
1940  continue; /* do not look in temp namespace */
1941 
1942  opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
1943  ObjectIdGetDatum(amid),
1944  PointerGetDatum(opfname),
1945  ObjectIdGetDatum(namespaceId));
1946  if (OidIsValid(opfid))
1947  return opfid;
1948  }
1949 
1950  /* Not found in path */
1951  return InvalidOid;
1952 }
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:197
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3464 of file namespace.c.

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

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

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

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3602 of file namespace.c.

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

Referenced by CreateSchemaCommand().

3603 {
3604  OverrideStackEntry *entry;
3605 
3606  /* Sanity checks. */
3607  if (overrideStack == NIL)
3608  elog(ERROR, "bogus PopOverrideSearchPath call");
3610  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3611  elog(ERROR, "bogus PopOverrideSearchPath call");
3612 
3613  /* Pop the stack and free storage. */
3615  list_free(entry->searchPath);
3616  pfree(entry);
3617 
3618  /* Activate the next level down. */
3619  if (overrideStack)
3620  {
3622  activeSearchPath = entry->searchPath;
3624  activeTempCreationPending = false; /* XXX is this OK? */
3625  }
3626  else
3627  {
3628  /* If not baseSearchPathValid, this is useless but harmless */
3632  }
3633 
3634  /* As above, the generation always increments. */
3636 }
#define NIL
Definition: pg_list.h:65
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1169
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:46
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
static List * baseSearchPath
Definition: namespace.c:151
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1391
#define elog(elevel,...)
Definition: elog.h:232
List * list_delete_first(List *list)
Definition: list.c:875

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3535 of file namespace.c.

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

Referenced by CreateSchemaCommand().

3536 {
3537  OverrideStackEntry *entry;
3538  List *oidlist;
3539  Oid firstNS;
3540  MemoryContext oldcxt;
3541 
3542  /*
3543  * Copy the list for safekeeping, and insert implicitly-searched
3544  * namespaces as needed. This code should track recomputeNamespacePath.
3545  */
3547 
3548  oidlist = list_copy(newpath->schemas);
3549 
3550  /*
3551  * Remember the first member of the explicit list.
3552  */
3553  if (oidlist == NIL)
3554  firstNS = InvalidOid;
3555  else
3556  firstNS = linitial_oid(oidlist);
3557 
3558  /*
3559  * Add any implicitly-searched namespaces to the list. Note these go on
3560  * the front, not the back; also notice that we do not check USAGE
3561  * permissions for these.
3562  */
3563  if (newpath->addCatalog)
3564  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3565 
3566  if (newpath->addTemp && OidIsValid(myTempNamespace))
3567  oidlist = lcons_oid(myTempNamespace, oidlist);
3568 
3569  /*
3570  * Build the new stack entry, then insert it at the head of the list.
3571  */
3572  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3573  entry->searchPath = oidlist;
3574  entry->creationNamespace = firstNS;
3576 
3577  overrideStack = lcons(entry, overrideStack);
3578 
3579  /* And make it active. */
3580  activeSearchPath = entry->searchPath;
3582  activeTempCreationPending = false; /* XXX is this OK? */
3583 
3584  /*
3585  * We always increment activePathGeneration when pushing/popping an
3586  * override path. In current usage, these actions always change the
3587  * effective path state, so there's no value in checking to see if it
3588  * didn't change.
3589  */
3591 
3592  MemoryContextSwitchTo(oldcxt);
3593 }
#define NIL
Definition: pg_list.h:65
static Oid myTempNamespace
Definition: namespace.c:188
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static List * overrideStack
Definition: namespace.c:171
List * list_copy(const List *oldlist)
Definition: list.c:1418
List * lcons_oid(Oid datum, List *list)
Definition: list.c:504
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:144
MemoryContext TopMemoryContext
Definition: mcxt.c:48
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
List * lcons(void *datum, List *list)
Definition: list.c:468
#define linitial_oid(l)
Definition: pg_list.h:176
static List * activeSearchPath
Definition: namespace.c:138
void * palloc(Size size)
Definition: mcxt.c:1062
Definition: pg_list.h:50

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 3040 of file namespace.c.

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

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

3041 {
3042  char *schemaname;
3043  Oid namespaceId;
3044 
3045  /* deconstruct the name list */
3046  DeconstructQualifiedName(names, &schemaname, objname_p);
3047 
3048  if (schemaname)
3049  {
3050  /* check for pg_temp alias */
3051  if (strcmp(schemaname, "pg_temp") == 0)
3052  {
3053  /* Initialize temp namespace */
3054  AccessTempTableNamespace(false);
3055  return myTempNamespace;
3056  }
3057  /* use exact schema given */
3058  namespaceId = get_namespace_oid(schemaname, false);
3059  /* we do not check for USAGE rights here! */
3060  }
3061  else
3062  {
3063  /* use the default creation namespace */
3066  {
3067  /* Need to initialize temp namespace */
3069  return myTempNamespace;
3070  }
3071  namespaceId = activeCreationNamespace;
3072  if (!OidIsValid(namespaceId))
3073  ereport(ERROR,
3074  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3075  errmsg("no schema has been selected to create in")));
3076  }
3077 
3078  return namespaceId;
3079 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3960
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static Oid activeCreationNamespace
Definition: namespace.c:141
#define ERROR
Definition: elog.h:46
static bool activeTempCreationPending
Definition: namespace.c:144
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 642 of file namespace.c.

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

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 535 of file namespace.c.

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

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 450 of file namespace.c.

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

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

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

◆ RangeVarGetRelidExtended()

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

Definition at line 237 of file namespace.c.

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

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

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

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 709 of file namespace.c.

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

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

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

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 681 of file namespace.c.

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

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

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

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4306 of file namespace.c.

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

4307 {
4310 }
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:710
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4262

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3374 of file namespace.c.

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

Referenced by ParallelWorkerMain().

3375 {
3376  /* Worker should not have created its own namespaces ... */
3380 
3381  /* Assign same namespace OIDs that leader has */
3382  myTempNamespace = tempNamespaceId;
3383  myTempToastNamespace = tempToastNamespaceId;
3384 
3385  /*
3386  * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
3387  * Even if the namespace is new so far as the leader is concerned, it's
3388  * not new to the worker, and we certainly wouldn't want the worker trying
3389  * to destroy it.
3390  */
3391 
3392  baseSearchPathValid = false; /* may need to rebuild list */
3393 }
static bool baseSearchPathValid
Definition: namespace.c:160
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:804
#define InvalidSubTransactionId
Definition: c.h:593

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  relid)

Definition at line 2280 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_statistics_obj_is_visible().

2281 {
2282  HeapTuple stxtup;
2283  Form_pg_statistic_ext stxform;
2284  Oid stxnamespace;
2285  bool visible;
2286 
2287  stxtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(relid));
2288  if (!HeapTupleIsValid(stxtup))
2289  elog(ERROR, "cache lookup failed for statistics object %u", relid);
2290  stxform = (Form_pg_statistic_ext) GETSTRUCT(stxtup);
2291 
2293 
2294  /*
2295  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2296  * the system namespace are surely in the path and so we needn't even do
2297  * list_member_oid() for them.
2298  */
2299  stxnamespace = stxform->stxnamespace;
2300  if (stxnamespace != PG_CATALOG_NAMESPACE &&
2301  !list_member_oid(activeSearchPath, stxnamespace))
2302  visible = false;
2303  else
2304  {
2305  /*
2306  * If it is in the path, it might still not be visible; it could be
2307  * hidden by another statistics object of the same name earlier in the
2308  * path. So we must do a slow check for conflicting objects.
2309  */
2310  char *stxname = NameStr(stxform->stxname);
2311  ListCell *l;
2312 
2313  visible = false;
2314  foreach(l, activeSearchPath)
2315  {
2316  Oid namespaceId = lfirst_oid(l);
2317 
2318  if (namespaceId == stxnamespace)
2319  {
2320  /* Found it first in path */
2321  visible = true;
2322  break;
2323  }
2325  PointerGetDatum(stxname),
2326  ObjectIdGetDatum(namespaceId)))
2327  {
2328  /* Found something else first in path */
2329  break;
2330  }
2331  }
2332  }
2333 
2334  ReleaseSysCache(stxtup);
2335 
2336  return visible;
2337 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
#define PointerGetDatum(X)
Definition: postgres.h:600
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:186
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681
FormData_pg_statistic_ext * Form_pg_statistic_ext
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 2782 of file namespace.c.

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

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

2783 {
2784  HeapTuple tup;
2785  Form_pg_ts_config form;
2786  Oid namespace;
2787  bool visible;
2788 
2790  if (!HeapTupleIsValid(tup))
2791  elog(ERROR, "cache lookup failed for text search configuration %u",
2792  cfgid);
2793  form = (Form_pg_ts_config) GETSTRUCT(tup);
2794 
2796 
2797  /*
2798  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2799  * the system namespace are surely in the path and so we needn't even do
2800  * list_member_oid() for them.
2801  */
2802  namespace = form->cfgnamespace;
2803  if (namespace != PG_CATALOG_NAMESPACE &&
2804  !list_member_oid(activeSearchPath, namespace))
2805  visible = false;
2806  else
2807  {
2808  /*
2809  * If it is in the path, it might still not be visible; it could be
2810  * hidden by another configuration of the same name earlier in the
2811  * path. So we must do a slow check for conflicting configurations.
2812  */
2813  char *name = NameStr(form->cfgname);
2814  ListCell *l;
2815 
2816  visible = false;
2817  foreach(l, activeSearchPath)
2818  {
2819  Oid namespaceId = lfirst_oid(l);
2820 
2821  if (namespaceId == myTempNamespace)
2822  continue; /* do not look in temp namespace */
2823 
2824  if (namespaceId == namespace)
2825  {
2826  /* Found it first in path */
2827  visible = true;
2828  break;
2829  }
2831  PointerGetDatum(name),
2832  ObjectIdGetDatum(namespaceId)))
2833  {
2834  /* Found something else first in path */
2835  break;
2836  }
2837  }
2838  }
2839 
2840  ReleaseSysCache(tup);
2841 
2842  return visible;
2843 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:186
const char * name
Definition: encode.c:515
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2529 of file namespace.c.

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

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

2530 {
2531  HeapTuple tup;
2532  Form_pg_ts_dict form;
2533  Oid namespace;
2534  bool visible;
2535 
2536  tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
2537  if (!HeapTupleIsValid(tup))
2538  elog(ERROR, "cache lookup failed for text search dictionary %u",
2539  dictId);
2540  form = (Form_pg_ts_dict) GETSTRUCT(tup);
2541 
2543 
2544  /*
2545  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2546  * the system namespace are surely in the path and so we needn't even do
2547  * list_member_oid() for them.
2548  */
2549  namespace = form->dictnamespace;
2550  if (namespace != PG_CATALOG_NAMESPACE &&
2551  !list_member_oid(activeSearchPath, namespace))
2552  visible = false;
2553  else
2554  {
2555  /*
2556  * If it is in the path, it might still not be visible; it could be
2557  * hidden by another dictionary of the same name earlier in the path.
2558  * So we must do a slow check for conflicting dictionaries.
2559  */
2560  char *name = NameStr(form->dictname);
2561  ListCell *l;
2562 
2563  visible = false;
2564  foreach(l, activeSearchPath)
2565  {
2566  Oid namespaceId = lfirst_oid(l);
2567 
2568  if (namespaceId == myTempNamespace)
2569  continue; /* do not look in temp namespace */
2570 
2571  if (namespaceId == namespace)
2572  {
2573  /* Found it first in path */
2574  visible = true;
2575  break;
2576  }
2578  PointerGetDatum(name),
2579  ObjectIdGetDatum(namespaceId)))
2580  {
2581  /* Found something else first in path */
2582  break;
2583  }
2584  }
2585  }
2586 
2587  ReleaseSysCache(tup);
2588 
2589  return visible;
2590 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:52
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:186
const char * name
Definition: encode.c:515
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2403 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_ts_parser_is_visible().

2404 {
2405  HeapTuple tup;
2406  Form_pg_ts_parser form;
2407  Oid namespace;
2408  bool visible;
2409 
2411  if (!HeapTupleIsValid(tup))
2412  elog(ERROR, "cache lookup failed for text search parser %u", prsId);
2413  form = (Form_pg_ts_parser) GETSTRUCT(tup);
2414 
2416 
2417  /*
2418  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2419  * the system namespace are surely in the path and so we needn't even do
2420  * list_member_oid() for them.
2421  */
2422  namespace = form->prsnamespace;
2423  if (namespace != PG_CATALOG_NAMESPACE &&
2424  !list_member_oid(activeSearchPath, namespace))
2425  visible = false;
2426  else
2427  {
2428  /*
2429  * If it is in the path, it might still not be visible; it could be
2430  * hidden by another parser of the same name earlier in the path. So
2431  * we must do a slow check for conflicting parsers.
2432  */
2433  char *name = NameStr(form->prsname);
2434  ListCell *l;
2435 
2436  visible = false;
2437  foreach(l, activeSearchPath)
2438  {
2439  Oid namespaceId = lfirst_oid(l);
2440 
2441  if (namespaceId == myTempNamespace)
2442  continue; /* do not look in temp namespace */
2443 
2444  if (namespaceId == namespace)
2445  {
2446  /* Found it first in path */
2447  visible = true;
2448  break;
2449  }
2451  PointerGetDatum(name),
2452  ObjectIdGetDatum(namespaceId)))
2453  {
2454  /* Found something else first in path */
2455  break;
2456  }
2457  }
2458  }
2459 
2460  ReleaseSysCache(tup);
2461 
2462  return visible;
2463 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
FormData_pg_ts_parser * Form_pg_ts_parser
Definition: pg_ts_parser.h:55
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:186
const char * name
Definition: encode.c:515
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 2656 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_ts_template_is_visible().

2657 {
2658  HeapTuple tup;
2659  Form_pg_ts_template form;
2660  Oid namespace;
2661  bool visible;
2662 
2664  if (!HeapTupleIsValid(tup))
2665  elog(ERROR, "cache lookup failed for text search template %u", tmplId);
2666  form = (Form_pg_ts_template) GETSTRUCT(tup);
2667 
2669 
2670  /*
2671  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2672  * the system namespace are surely in the path and so we needn't even do
2673  * list_member_oid() for them.
2674  */
2675  namespace = form->tmplnamespace;
2676  if (namespace != PG_CATALOG_NAMESPACE &&
2677  !list_member_oid(activeSearchPath, namespace))
2678  visible = false;
2679  else
2680  {
2681  /*
2682  * If it is in the path, it might still not be visible; it could be
2683  * hidden by another template of the same name earlier in the path. So
2684  * we must do a slow check for conflicting templates.
2685  */
2686  char *name = NameStr(form->tmplname);
2687  ListCell *l;
2688 
2689  visible = false;
2690  foreach(l, activeSearchPath)
2691  {
2692  Oid namespaceId = lfirst_oid(l);
2693 
2694  if (namespaceId == myTempNamespace)
2695  continue; /* do not look in temp namespace */
2696 
2697  if (namespaceId == namespace)
2698  {
2699  /* Found it first in path */
2700  visible = true;
2701  break;
2702  }
2704  PointerGetDatum(name),
2705  ObjectIdGetDatum(namespaceId)))
2706  {
2707  /* Found something else first in path */
2708  break;
2709  }
2710  }
2711  }
2712 
2713  ReleaseSysCache(tup);
2714 
2715  return visible;
2716 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:186
const char * name
Definition: encode.c:515
static List * activeSearchPath
Definition: namespace.c:138
FormData_pg_ts_template * Form_pg_ts_template
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 817 of file namespace.c.

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

Referenced by format_type_extended(), and pg_type_is_visible().

818 {
819  HeapTuple typtup;
820  Form_pg_type typform;
821  Oid typnamespace;
822  bool visible;
823 
824  typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
825  if (!HeapTupleIsValid(typtup))
826  elog(ERROR, "cache lookup failed for type %u", typid);
827  typform = (Form_pg_type) GETSTRUCT(typtup);
828 
830 
831  /*
832  * Quick check: if it ain't in the path at all, it ain't visible. Items in
833  * the system namespace are surely in the path and so we needn't even do
834  * list_member_oid() for them.
835  */
836  typnamespace = typform->typnamespace;