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

Go to the source code of this file.

Data Structures

struct  _FuncCandidateList
 
struct  OverrideSearchPath
 

Macros

#define RangeVarGetRelid(relation, lockmode, missing_ok)
 

Typedefs

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

Enumerations

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

Functions

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

Variables

char * namespace_search_path
 

Macro Definition Documentation

◆ RangeVarGetRelid

Typedef Documentation

◆ FuncCandidateList

◆ OverrideSearchPath

◆ RangeVarGetRelidCallback

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

Definition at line 75 of file namespace.h.

◆ RVROption

typedef enum RVROption RVROption

◆ TempNamespaceStatus

Enumeration Type Documentation

◆ RVROption

enum RVROption
Enumerator
RVR_MISSING_OK 
RVR_NOWAIT 
RVR_SKIP_LOCKED 

Definition at line 68 of file namespace.h.

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

◆ TempNamespaceStatus

Enumerator
TEMP_NAMESPACE_NOT_TEMP 
TEMP_NAMESPACE_IDLE 
TEMP_NAMESPACE_IN_USE 

Definition at line 43 of file namespace.h.

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

Function Documentation

◆ AtEOSubXact_Namespace()

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

Definition at line 4132 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().

4134 {
4135  OverrideStackEntry *entry;
4136 
4137  if (myTempNamespaceSubID == mySubid)
4138  {
4139  if (isCommit)
4140  myTempNamespaceSubID = parentSubid;
4141  else
4142  {
4144  /* TEMP namespace creation failed, so reset state */
4147  baseSearchPathValid = false; /* need to rebuild list */
4148 
4149  /*
4150  * Reset the temporary namespace flag in MyProc. We assume that
4151  * this operation is atomic.
4152  *
4153  * Because this subtransaction is aborting, the pg_namespace row
4154  * is not visible to anyone else anyway, but that doesn't matter:
4155  * it's not a problem if objects contained in this namespace are
4156  * removed concurrently.
4157  */
4159  }
4160  }
4161 
4162  /*
4163  * Clean up if someone failed to do PopOverrideSearchPath
4164  */
4165  while (overrideStack)
4166  {
4169  break;
4170  if (isCommit)
4171  elog(WARNING, "leaked override search path");
4173  list_free(entry->searchPath);
4174  pfree(entry);
4175  /* Always bump generation --- see note in recomputeNamespacePath */
4177  }
4178 
4179  /* Activate the next level down. */
4180  if (overrideStack)
4181  {
4183  activeSearchPath = entry->searchPath;
4185  activeTempCreationPending = false; /* XXX is this OK? */
4186 
4187  /*
4188  * It's probably unnecessary to bump generation here, but this should
4189  * not be a performance-critical case, so better to be over-cautious.
4190  */
4192  }
4193  else
4194  {
4195  /* If not baseSearchPathValid, this is useless but harmless */
4199 
4200  /*
4201  * If we popped an override stack entry, then we already bumped the
4202  * generation above. If we did not, then the above assignments did
4203  * nothing and we need not bump the generation.
4204  */
4205  }
4206 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid tempNamespaceId
Definition: proc.h:117
PGPROC * MyProc
Definition: proc.c:67
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1056
#define linitial(l)
Definition: pg_list.h:195
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:842
#define InvalidSubTransactionId
Definition: c.h:519
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1376
#define elog(elevel,...)
Definition: elog.h:214
List * list_delete_first(List *list)
Definition: list.c:860

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4064 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().

4065 {
4066  /*
4067  * If we abort the transaction in which a temp namespace was selected,
4068  * we'll have to do any creation or cleanout work over again. So, just
4069  * forget the namespace entirely until next time. On the other hand, if
4070  * we commit then register an exit callback to clean out the temp tables
4071  * at backend shutdown. (We only want to register the callback once per
4072  * session, so this is a good place to do it.)
4073  */
4074  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
4075  {
4076  if (isCommit)
4078  else
4079  {
4082  baseSearchPathValid = false; /* need to rebuild list */
4083 
4084  /*
4085  * Reset the temporary namespace flag in MyProc. We assume that
4086  * this operation is atomic.
4087  *
4088  * Because this transaction is aborting, the pg_namespace row is
4089  * not visible to anyone else anyway, but that doesn't matter:
4090  * it's not a problem if objects contained in this namespace are
4091  * removed concurrently.
4092  */
4094  }
4096  }
4097 
4098  /*
4099  * Clean up if someone failed to do PopOverrideSearchPath
4100  */
4101  if (overrideStack)
4102  {
4103  if (isCommit)
4104  elog(WARNING, "leaked override search path");
4105  while (overrideStack)
4106  {
4107  OverrideStackEntry *entry;
4108 
4111  list_free(entry->searchPath);
4112  pfree(entry);
4113  }
4114  /* If not baseSearchPathValid, this is useless but harmless */
4118  /* Always bump generation --- see note in recomputeNamespacePath */
4120  }
4121 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid tempNamespaceId
Definition: proc.h:117
PGPROC * MyProc
Definition: proc.c:67
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1056
#define linitial(l)
Definition: pg_list.h:195
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:519
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1376
#define elog(elevel,...)
Definition: elog.h:214
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4243
List * list_delete_first(List *list)
Definition: list.c:860

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2967 of file namespace.c.

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

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

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

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3237 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().

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

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2014 of file namespace.c.

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

Referenced by CollationIsVisible().

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

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2048 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().

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

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2099 of file namespace.c.

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

Referenced by ConversionIsVisible().

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

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2131 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().

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

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3397 of file namespace.c.

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

Referenced by CopyCachedPlan().

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

◆ DeconstructQualifiedName()

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

Definition at line 2809 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().

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4383 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().

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

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4423 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

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

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3710 of file namespace.c.

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

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

3711 {
3712  Oid proc;
3713  ListCell *l;
3714 
3716 
3717  foreach(l, activeSearchPath)
3718  {
3719  Oid namespaceId = lfirst_oid(l);
3720 
3721  if (namespaceId == myTempNamespace)
3722  continue; /* do not look in temp namespace */
3723 
3724  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3725  if (OidIsValid(proc))
3726  return proc;
3727  }
3728 
3729  /* Not found in path */
3730  return InvalidOid;
3731 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#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:192

◆ FuncnameGetCandidates()

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

Definition at line 942 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1413 of file namespace.c.

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

Referenced by format_procedure_internal(), and pg_function_is_visible().

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

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3601 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().

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

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 3655 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().

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

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

Definition at line 3043 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().

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

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2178 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().

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

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2679 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().

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

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2426 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().

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

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2300 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().

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

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2553 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().

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

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3360 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().

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

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3274 of file namespace.c.

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

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

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

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3313 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

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

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3299 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3300 {
3302  return myTempToastNamespace;
3303 }
static Oid myTempToastNamespace
Definition: namespace.c:190
#define OidIsValid(objectId)
Definition: c.h:644
#define Assert(condition)
Definition: c.h:738

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4324 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().

4325 {
4327  {
4328  /*
4329  * In bootstrap mode, the search path must be 'pg_catalog' so that
4330  * tables are created in the proper namespace; ignore the GUC setting.
4331  */
4332  MemoryContext oldcxt;
4333 
4335  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4336  MemoryContextSwitchTo(oldcxt);
4337  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4338  baseTempCreationPending = false;
4339  baseSearchPathValid = true;
4344  activePathGeneration++; /* pro forma */
4345  }
4346  else
4347  {
4348  /*
4349  * In normal mode, arrange for a callback on any syscache invalidation
4350  * of pg_namespace rows.
4351  */
4354  (Datum) 0);
4355  /* Force search path to be recomputed on next use */
4356  baseSearchPathValid = false;
4357  }
4358 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid GetUserId(void)
Definition: miscinit.c:448
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:4365
static bool activeTempCreationPending
Definition: namespace.c:144
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static Oid baseCreationNamespace
Definition: namespace.c:153
static List * baseSearchPath
Definition: namespace.c:151
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1426
uintptr_t Datum
Definition: postgres.h:367
#define list_make1_oid(x1)
Definition: pg_list.h:249
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:392
static List * activeSearchPath
Definition: namespace.c:138

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3195 of file namespace.c.

References get_namespace_name(), and pfree().

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

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

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3218 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

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

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3157 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

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

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3181 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

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

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3169 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

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

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2936 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().

2937 {
2938  Oid namespaceId;
2939  AclResult aclresult;
2940 
2941  /* check for pg_temp alias */
2942  if (strcmp(nspname, "pg_temp") == 0)
2943  {
2944  /* Initialize temp namespace */
2945  AccessTempTableNamespace(false);
2946  return myTempNamespace;
2947  }
2948 
2949  namespaceId = get_namespace_oid(nspname, false);
2950 
2951  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2952  if (aclresult != ACLCHECK_OK)
2953  aclcheck_error(aclresult, OBJECT_SCHEMA,
2954  nspname);
2955 
2956  return namespaceId;
2957 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3043
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3915
Oid GetUserId(void)
Definition: miscinit.c:448
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:4658
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3327
#define ACL_CREATE
Definition: parsenodes.h:84
AclResult
Definition: acl.h:177

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2893 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().

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

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2863 of file namespace.c.

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

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

2864 {
2865  /* check for pg_temp alias */
2866  if (strcmp(nspname, "pg_temp") == 0)
2867  {
2869  {
2871  return myTempNamespace;
2872  }
2873 
2874  /*
2875  * Since this is used only for looking up existing objects, there is
2876  * no point in trying to initialize the temp namespace here; and doing
2877  * so might create problems for some callers. Just report "not found".
2878  */
2879  return InvalidOid;
2880  }
2881 
2882  return get_namespace_oid(nspname, true);
2883 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3043
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:644
#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 3062 of file namespace.c.

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

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

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

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3136 of file namespace.c.

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

3137 {
3139  ListCell *l;
3140 
3141  initStringInfo(&string);
3142 
3143  foreach(l, names)
3144  {
3145  if (l != list_head(names))
3146  appendStringInfoChar(&string, '.');
3148  }
3149 
3150  return string.data;
3151 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10737
#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:190

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3102 of file namespace.c.

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

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

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

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1833 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().

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

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1800 of file namespace.c.

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

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

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

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1747 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_internal(), and pg_operator_is_visible().

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

◆ OpernameGetCandidates()

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

Definition at line 1587 of file namespace.c.

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

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

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

◆ OpernameGetOprid()

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

Definition at line 1484 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(), right_oper(), and to_regoperator().

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

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1916 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().

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

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1883 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

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

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3419 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().

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

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3557 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().

3558 {
3559  OverrideStackEntry *entry;
3560 
3561  /* Sanity checks. */
3562  if (overrideStack == NIL)
3563  elog(ERROR, "bogus PopOverrideSearchPath call");
3565  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3566  elog(ERROR, "bogus PopOverrideSearchPath call");
3567 
3568  /* Pop the stack and free storage. */
3570  list_free(entry->searchPath);
3571  pfree(entry);
3572 
3573  /* Activate the next level down. */
3574  if (overrideStack)
3575  {
3577  activeSearchPath = entry->searchPath;
3579  activeTempCreationPending = false; /* XXX is this OK? */
3580  }
3581  else
3582  {
3583  /* If not baseSearchPathValid, this is useless but harmless */
3587  }
3588 
3589  /* As above, the generation always increments. */
3591 }
#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:1056
#define linitial(l)
Definition: pg_list.h:195
#define ERROR
Definition: elog.h:43
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
static List * baseSearchPath
Definition: namespace.c:151
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:842
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1376
#define elog(elevel,...)
Definition: elog.h:214
List * list_delete_first(List *list)
Definition: list.c:860

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3490 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().

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

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 2995 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().

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

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 641 of file namespace.c.

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

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 534 of file namespace.c.

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

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 449 of file namespace.c.

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

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

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

◆ RangeVarGetRelidExtended()

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

Definition at line 236 of file namespace.c.

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

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

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

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 708 of file namespace.c.

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

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

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

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 680 of file namespace.c.

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

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

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

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4261 of file namespace.c.

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

4262 {
4265 }
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:644
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4217

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3329 of file namespace.c.

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

Referenced by ParallelWorkerMain().

3330 {
3331  /* Worker should not have created its own namespaces ... */
3335 
3336  /* Assign same namespace OIDs that leader has */
3337  myTempNamespace = tempNamespaceId;
3338  myTempToastNamespace = tempToastNamespaceId;
3339 
3340  /*
3341  * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
3342  * Even if the namespace is new so far as the leader is concerned, it's
3343  * not new to the worker, and we certainly wouldn't want the worker trying
3344  * to destroy it.
3345  */
3346 
3347  baseSearchPathValid = false; /* may need to rebuild list */
3348 }
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:738
#define InvalidSubTransactionId
Definition: c.h:519

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  relid)

Definition at line 2235 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().

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

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 2737 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().

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

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2484 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().

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

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2358 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().

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

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 2611 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().

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

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 816 of file namespace.c.

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

Referenced by format_type_extended(), and pg_type_is_visible().

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