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  SearchPathMatcher
 

Macros

#define RangeVarGetRelid(relation, lockmode, missing_ok)
 

Typedefs

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

Enumerations

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

Functions

Oid RangeVarGetRelidExtended (const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
 
Oid RangeVarGetCreationNamespace (const RangeVar *newRelation)
 
Oid RangeVarGetAndCheckCreationNamespace (RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
 
void RangeVarAdjustRelationPersistence (RangeVar *newRelation, Oid nspid)
 
Oid RelnameGetRelid (const char *relname)
 
bool RelationIsVisible (Oid relid)
 
Oid TypenameGetTypid (const char *typname)
 
Oid TypenameGetTypidExtended (const char *typname, bool temp_ok)
 
bool TypeIsVisible (Oid typid)
 
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok)
 
bool OperatorIsVisible (Oid oprid)
 
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
 
bool OpclassIsVisible (Oid opcid)
 
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
 
bool OpfamilyIsVisible (Oid opfid)
 
Oid CollationGetCollid (const char *collname)
 
bool CollationIsVisible (Oid collid)
 
Oid ConversionGetConid (const char *conname)
 
bool ConversionIsVisible (Oid conid)
 
Oid get_statistics_object_oid (List *names, bool missing_ok)
 
bool StatisticsObjIsVisible (Oid relid)
 
Oid get_ts_parser_oid (List *names, bool missing_ok)
 
bool TSParserIsVisible (Oid prsId)
 
Oid get_ts_dict_oid (List *names, bool missing_ok)
 
bool TSDictionaryIsVisible (Oid dictId)
 
Oid get_ts_template_oid (List *names, bool missing_ok)
 
bool TSTemplateIsVisible (Oid tmplId)
 
Oid get_ts_config_oid (List *names, bool missing_ok)
 
bool TSConfigIsVisible (Oid cfgid)
 
void DeconstructQualifiedName (const 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 (const List *names, char **objname_p)
 
RangeVarmakeRangeVarFromNameList (const List *names)
 
char * NameListToString (const List *names)
 
char * NameListToQuotedString (const 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)
 
SearchPathMatcherGetSearchPathMatcher (MemoryContext context)
 
SearchPathMatcherCopySearchPathMatcher (SearchPathMatcher *path)
 
bool SearchPathMatchesCurrentEnvironment (SearchPathMatcher *path)
 
Oid get_collation_oid (List *collname, bool missing_ok)
 
Oid get_conversion_oid (List *conname, bool missing_ok)
 
Oid FindDefaultConversionProc (int32 for_encoding, int32 to_encoding)
 
void InitializeSearchPath (void)
 
void AtEOXact_Namespace (bool isCommit, bool parallel)
 
void AtEOSubXact_Namespace (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
Listfetch_search_path (bool includeImplicit)
 
int fetch_search_path_array (Oid *sarray, int sarray_len)
 

Variables

PGDLLIMPORT char * namespace_search_path
 

Macro Definition Documentation

◆ RangeVarGetRelid

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

Definition at line 79 of file namespace.h.

Typedef Documentation

◆ FuncCandidateList

◆ RangeVarGetRelidCallback

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

Definition at line 76 of file namespace.h.

◆ RVROption

typedef enum RVROption RVROption

◆ SearchPathMatcher

◆ TempNamespaceStatus

Enumeration Type Documentation

◆ RVROption

enum RVROption
Enumerator
RVR_MISSING_OK 
RVR_NOWAIT 
RVR_SKIP_LOCKED 

Definition at line 69 of file namespace.h.

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

◆ TempNamespaceStatus

Enumerator
TEMP_NAMESPACE_NOT_TEMP 
TEMP_NAMESPACE_IDLE 
TEMP_NAMESPACE_IN_USE 

Definition at line 44 of file namespace.h.

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

Function Documentation

◆ AtEOSubXact_Namespace()

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

Definition at line 4004 of file namespace.c.

4006 {
4007 
4008  if (myTempNamespaceSubID == mySubid)
4009  {
4010  if (isCommit)
4011  myTempNamespaceSubID = parentSubid;
4012  else
4013  {
4015  /* TEMP namespace creation failed, so reset state */
4018  baseSearchPathValid = false; /* need to rebuild list */
4019 
4020  /*
4021  * Reset the temporary namespace flag in MyProc. We assume that
4022  * this operation is atomic.
4023  *
4024  * Because this subtransaction is aborting, the pg_namespace row
4025  * is not visible to anyone else anyway, but that doesn't matter:
4026  * it's not a problem if objects contained in this namespace are
4027  * removed concurrently.
4028  */
4030  }
4031  }
4032 }
#define InvalidSubTransactionId
Definition: c.h:647
static bool baseSearchPathValid
Definition: namespace.c:155
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:176
static Oid myTempToastNamespace
Definition: namespace.c:174
static Oid myTempNamespace
Definition: namespace.c:172
#define InvalidOid
Definition: postgres_ext.h:36
PGPROC * MyProc
Definition: proc.c:66
Oid tempNamespaceId
Definition: proc.h:201

References baseSearchPathValid, InvalidOid, InvalidSubTransactionId, MyProc, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, and PGPROC::tempNamespaceId.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 3959 of file namespace.c.

3960 {
3961  /*
3962  * If we abort the transaction in which a temp namespace was selected,
3963  * we'll have to do any creation or cleanout work over again. So, just
3964  * forget the namespace entirely until next time. On the other hand, if
3965  * we commit then register an exit callback to clean out the temp tables
3966  * at backend shutdown. (We only want to register the callback once per
3967  * session, so this is a good place to do it.)
3968  */
3969  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
3970  {
3971  if (isCommit)
3973  else
3974  {
3977  baseSearchPathValid = false; /* need to rebuild list */
3978 
3979  /*
3980  * Reset the temporary namespace flag in MyProc. We assume that
3981  * this operation is atomic.
3982  *
3983  * Because this transaction is aborting, the pg_namespace row is
3984  * not visible to anyone else anyway, but that doesn't matter:
3985  * it's not a problem if objects contained in this namespace are
3986  * removed concurrently.
3987  */
3989  }
3991  }
3992 
3993 }
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4069

References baseSearchPathValid, before_shmem_exit(), InvalidOid, InvalidSubTransactionId, MyProc, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, RemoveTempRelationsCallback(), and PGPROC::tempNamespaceId.

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

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2992 of file namespace.c.

2993 {
2994  /* disallow renaming into or out of temp schemas */
2995  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2996  ereport(ERROR,
2997  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2998  errmsg("cannot move objects into or out of temporary schemas")));
2999 
3000  /* same for TOAST schema */
3001  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
3002  ereport(ERROR,
3003  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3004  errmsg("cannot move objects into or out of TOAST schema")));
3005 }
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3220

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

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

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3262 of file namespace.c.

3263 {
3264  PGPROC *proc;
3265  int backendId;
3266 
3268 
3269  backendId = GetTempNamespaceBackendId(namespaceId);
3270 
3271  /* No such namespace, or its name shows it's not temp? */
3272  if (backendId == InvalidBackendId)
3273  return TEMP_NAMESPACE_NOT_TEMP;
3274 
3275  /* Is the backend alive? */
3276  proc = BackendIdGetProc(backendId);
3277  if (proc == NULL)
3278  return TEMP_NAMESPACE_IDLE;
3279 
3280  /* Is the backend connected to the same database we are looking at? */
3281  if (proc->databaseId != MyDatabaseId)
3282  return TEMP_NAMESPACE_IDLE;
3283 
3284  /* Does the backend own the temporary namespace? */
3285  if (proc->tempNamespaceId != namespaceId)
3286  return TEMP_NAMESPACE_IDLE;
3287 
3288  /* Yup, so namespace is busy */
3289  return TEMP_NAMESPACE_IN_USE;
3290 }
#define InvalidBackendId
Definition: backendid.h:23
#define OidIsValid(objectId)
Definition: c.h:764
Oid MyDatabaseId
Definition: globals.c:89
Assert(fmt[strlen(fmt) - 1] !='\n')
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3299
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:385
Definition: proc.h:162
Oid databaseId
Definition: proc.h:198

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

Referenced by do_autovacuum().

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2039 of file namespace.c.

2040 {
2041  int32 dbencoding = GetDatabaseEncoding();
2042  ListCell *l;
2043 
2045 
2046  foreach(l, activeSearchPath)
2047  {
2048  Oid namespaceId = lfirst_oid(l);
2049  Oid collid;
2050 
2051  if (namespaceId == myTempNamespace)
2052  continue; /* do not look in temp namespace */
2053 
2054  collid = lookup_collation(collname, namespaceId, dbencoding);
2055  if (OidIsValid(collid))
2056  return collid;
2057  }
2058 
2059  /* Not found in path */
2060  return InvalidOid;
2061 }
signed int int32
Definition: c.h:483
Oid collid
int GetDatabaseEncoding(void)
Definition: mbutils.c:1268
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1988
static List * activeSearchPath
Definition: namespace.c:133
static void recomputeNamespacePath(void)
Definition: namespace.c:3639
#define lfirst_oid(lc)
Definition: pg_list.h:174
unsigned int Oid
Definition: postgres_ext.h:31

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

Referenced by CollationIsVisible().

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2073 of file namespace.c.

2074 {
2075  HeapTuple colltup;
2076  Form_pg_collation collform;
2077  Oid collnamespace;
2078  bool visible;
2079 
2081  if (!HeapTupleIsValid(colltup))
2082  elog(ERROR, "cache lookup failed for collation %u", collid);
2083  collform = (Form_pg_collation) GETSTRUCT(colltup);
2084 
2086 
2087  /*
2088  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2089  * the system namespace are surely in the path and so we needn't even do
2090  * list_member_oid() for them.
2091  */
2092  collnamespace = collform->collnamespace;
2093  if (collnamespace != PG_CATALOG_NAMESPACE &&
2094  !list_member_oid(activeSearchPath, collnamespace))
2095  visible = false;
2096  else
2097  {
2098  /*
2099  * If it is in the path, it might still not be visible; it could be
2100  * hidden by another collation of the same name earlier in the path,
2101  * or it might not work with the current DB encoding. So we must do a
2102  * slow check to see if this collation would be found by
2103  * CollationGetCollid.
2104  */
2105  char *collname = NameStr(collform->collname);
2106 
2107  visible = (CollationGetCollid(collname) == collid);
2108  }
2109 
2110  ReleaseSysCache(colltup);
2111 
2112  return visible;
2113 }
#define NameStr(name)
Definition: c.h:735
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:721
Oid CollationGetCollid(const char *collname)
Definition: namespace.c:2039
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:58
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:868
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:820
@ COLLOID
Definition: syscache.h:50

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

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

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2124 of file namespace.c.

2125 {
2126  Oid conid;
2127  ListCell *l;
2128 
2130 
2131  foreach(l, activeSearchPath)
2132  {
2133  Oid namespaceId = lfirst_oid(l);
2134 
2135  if (namespaceId == myTempNamespace)
2136  continue; /* do not look in temp namespace */
2137 
2138  conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2139  PointerGetDatum(conname),
2140  ObjectIdGetDatum(namespaceId));
2141  if (OidIsValid(conid))
2142  return conid;
2143  }
2144 
2145  /* Not found in path */
2146  return InvalidOid;
2147 }
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
@ CONNAMENSP
Definition: syscache.h:52
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:202

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

Referenced by ConversionIsVisible().

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2156 of file namespace.c.

2157 {
2158  HeapTuple contup;
2159  Form_pg_conversion conform;
2160  Oid connamespace;
2161  bool visible;
2162 
2163  contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
2164  if (!HeapTupleIsValid(contup))
2165  elog(ERROR, "cache lookup failed for conversion %u", conid);
2166  conform = (Form_pg_conversion) GETSTRUCT(contup);
2167 
2169 
2170  /*
2171  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2172  * the system namespace are surely in the path and so we needn't even do
2173  * list_member_oid() for them.
2174  */
2175  connamespace = conform->connamespace;
2176  if (connamespace != PG_CATALOG_NAMESPACE &&
2177  !list_member_oid(activeSearchPath, connamespace))
2178  visible = false;
2179  else
2180  {
2181  /*
2182  * If it is in the path, it might still not be visible; it could be
2183  * hidden by another conversion of the same name earlier in the path.
2184  * So we must do a slow check to see if this conversion would be found
2185  * by ConversionGetConid.
2186  */
2187  char *conname = NameStr(conform->conname);
2188 
2189  visible = (ConversionGetConid(conname) == conid);
2190  }
2191 
2192  ReleaseSysCache(contup);
2193 
2194  return visible;
2195 }
Oid ConversionGetConid(const char *conname)
Definition: namespace.c:2124
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:61
@ CONVOID
Definition: syscache.h:54

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

Referenced by getObjectDescription(), and pg_conversion_is_visible().

◆ CopySearchPathMatcher()

SearchPathMatcher* CopySearchPathMatcher ( SearchPathMatcher path)

Definition at line 3421 of file namespace.c.

3422 {
3423  SearchPathMatcher *result;
3424 
3425  result = (SearchPathMatcher *) palloc(sizeof(SearchPathMatcher));
3426  result->schemas = list_copy(path->schemas);
3427  result->addCatalog = path->addCatalog;
3428  result->addTemp = path->addTemp;
3429  result->generation = path->generation;
3430 
3431  return result;
3432 }
List * list_copy(const List *oldlist)
Definition: list.c:1572
void * palloc(Size size)
Definition: mcxt.c:1226
uint64 generation
Definition: namespace.h:63

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

Referenced by CopyCachedPlan().

◆ DeconstructQualifiedName()

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

Definition at line 2834 of file namespace.c.

2837 {
2838  char *catalogname;
2839  char *schemaname = NULL;
2840  char *objname = NULL;
2841 
2842  switch (list_length(names))
2843  {
2844  case 1:
2845  objname = strVal(linitial(names));
2846  break;
2847  case 2:
2848  schemaname = strVal(linitial(names));
2849  objname = strVal(lsecond(names));
2850  break;
2851  case 3:
2852  catalogname = strVal(linitial(names));
2853  schemaname = strVal(lsecond(names));
2854  objname = strVal(lthird(names));
2855 
2856  /*
2857  * We check the catalog name and then ignore it.
2858  */
2859  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2860  ereport(ERROR,
2861  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2862  errmsg("cross-database references are not implemented: %s",
2863  NameListToString(names))));
2864  break;
2865  default:
2866  ereport(ERROR,
2867  (errcode(ERRCODE_SYNTAX_ERROR),
2868  errmsg("improper qualified name (too many dotted names): %s",
2869  NameListToString(names))));
2870  break;
2871  }
2872 
2873  *nspname_p = schemaname;
2874  *objname_p = objname;
2875 }
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3084
char * NameListToString(const List *names)
Definition: namespace.c:3127
static int list_length(const List *l)
Definition: pg_list.h:152
#define lthird(l)
Definition: pg_list.h:188
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
#define strVal(v)
Definition: value.h:82

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

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4215 of file namespace.c.

4216 {
4217  List *result;
4218 
4220 
4221  /*
4222  * If the temp namespace should be first, force it to exist. This is so
4223  * that callers can trust the result to reflect the actual default
4224  * creation namespace. It's a bit bogus to do this here, since
4225  * current_schema() is supposedly a stable function without side-effects,
4226  * but the alternatives seem worse.
4227  */
4229  {
4232  }
4233 
4234  result = list_copy(activeSearchPath);
4235  if (!includeImplicit)
4236  {
4237  while (result && linitial_oid(result) != activeCreationNamespace)
4238  result = list_delete_first(result);
4239  }
4240 
4241  return result;
4242 }
List * list_delete_first(List *list)
Definition: list.c:942
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool activeTempCreationPending
Definition: namespace.c:139
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3810
#define linitial_oid(l)
Definition: pg_list.h:180
Definition: pg_list.h:54

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

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

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4255 of file namespace.c.

4256 {
4257  int count = 0;
4258  ListCell *l;
4259 
4261 
4262  foreach(l, activeSearchPath)
4263  {
4264  Oid namespaceId = lfirst_oid(l);
4265 
4266  if (namespaceId == myTempNamespace)
4267  continue; /* do not include temp namespace */
4268 
4269  if (count < sarray_len)
4270  sarray[count] = namespaceId;
4271  count++;
4272  }
4273 
4274  return count;
4275 }

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

Referenced by make_oper_cache_key().

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3612 of file namespace.c.

3613 {
3614  Oid proc;
3615  ListCell *l;
3616 
3618 
3619  foreach(l, activeSearchPath)
3620  {
3621  Oid namespaceId = lfirst_oid(l);
3622 
3623  if (namespaceId == myTempNamespace)
3624  continue; /* do not look in temp namespace */
3625 
3626  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3627  if (OidIsValid(proc))
3628  return proc;
3629  }
3630 
3631  /* Not found in path */
3632  return InvalidOid;
3633 }
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)

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

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

◆ FuncnameGetCandidates()

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

Definition at line 934 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1438 of file namespace.c.

1439 {
1440  HeapTuple proctup;
1441  Form_pg_proc procform;
1442  Oid pronamespace;
1443  bool visible;
1444 
1445  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1446  if (!HeapTupleIsValid(proctup))
1447  elog(ERROR, "cache lookup failed for function %u", funcid);
1448  procform = (Form_pg_proc) GETSTRUCT(proctup);
1449 
1451 
1452  /*
1453  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1454  * the system namespace are surely in the path and so we needn't even do
1455  * list_member_oid() for them.
1456  */
1457  pronamespace = procform->pronamespace;
1458  if (pronamespace != PG_CATALOG_NAMESPACE &&
1459  !list_member_oid(activeSearchPath, pronamespace))
1460  visible = false;
1461  else
1462  {
1463  /*
1464  * If it is in the path, it might still not be visible; it could be
1465  * hidden by another proc of the same name and arguments earlier in
1466  * the path. So we must do a slow check to see if this is the same
1467  * proc that would be found by FuncnameGetCandidates.
1468  */
1469  char *proname = NameStr(procform->proname);
1470  int nargs = procform->pronargs;
1471  FuncCandidateList clist;
1472 
1473  visible = false;
1474 
1476  nargs, NIL, false, false, false, false);
1477 
1478  for (; clist; clist = clist->next)
1479  {
1480  if (memcmp(clist->args, procform->proargtypes.values,
1481  nargs * sizeof(Oid)) == 0)
1482  {
1483  /* Found the expected entry; is it the right proc? */
1484  visible = (clist->oid == funcid);
1485  break;
1486  }
1487  }
1488  }
1489 
1490  ReleaseSysCache(proctup);
1491 
1492  return visible;
1493 }
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
Definition: namespace.c:934
#define list_make1(x1)
Definition: pg_list.h:212
NameData proname
Definition: pg_proc.h:35
@ PROCOID
Definition: syscache.h:79
String * makeString(char *str)
Definition: value.c:63

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

Referenced by format_procedure_extended(), and pg_function_is_visible().

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3503 of file namespace.c.

3504 {
3505  char *schemaname;
3506  char *collation_name;
3507  int32 dbencoding = GetDatabaseEncoding();
3508  Oid namespaceId;
3509  Oid colloid;
3510  ListCell *l;
3511 
3512  /* deconstruct the name list */
3513  DeconstructQualifiedName(collname, &schemaname, &collation_name);
3514 
3515  if (schemaname)
3516  {
3517  /* use exact schema given */
3518  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3519  if (missing_ok && !OidIsValid(namespaceId))
3520  return InvalidOid;
3521 
3522  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3523  if (OidIsValid(colloid))
3524  return colloid;
3525  }
3526  else
3527  {
3528  /* search for it in search path */
3530 
3531  foreach(l, activeSearchPath)
3532  {
3533  namespaceId = lfirst_oid(l);
3534 
3535  if (namespaceId == myTempNamespace)
3536  continue; /* do not look in temp namespace */
3537 
3538  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3539  if (OidIsValid(colloid))
3540  return colloid;
3541  }
3542  }
3543 
3544  /* Not found in path */
3545  if (!missing_ok)
3546  ereport(ERROR,
3547  (errcode(ERRCODE_UNDEFINED_OBJECT),
3548  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3549  NameListToString(collname), GetDatabaseEncodingName())));
3550  return InvalidOid;
3551 }
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1274

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

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

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 3557 of file namespace.c.

3558 {
3559  char *schemaname;
3560  char *conversion_name;
3561  Oid namespaceId;
3562  Oid conoid = InvalidOid;
3563  ListCell *l;
3564 
3565  /* deconstruct the name list */
3566  DeconstructQualifiedName(conname, &schemaname, &conversion_name);
3567 
3568  if (schemaname)
3569  {
3570  /* use exact schema given */
3571  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3572  if (missing_ok && !OidIsValid(namespaceId))
3573  conoid = InvalidOid;
3574  else
3575  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3576  PointerGetDatum(conversion_name),
3577  ObjectIdGetDatum(namespaceId));
3578  }
3579  else
3580  {
3581  /* search for it in search path */
3583 
3584  foreach(l, activeSearchPath)
3585  {
3586  namespaceId = lfirst_oid(l);
3587 
3588  if (namespaceId == myTempNamespace)
3589  continue; /* do not look in temp namespace */
3590 
3591  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3592  PointerGetDatum(conversion_name),
3593  ObjectIdGetDatum(namespaceId));
3594  if (OidIsValid(conoid))
3595  return conoid;
3596  }
3597  }
3598 
3599  /* Not found in path */
3600  if (!OidIsValid(conoid) && !missing_ok)
3601  ereport(ERROR,
3602  (errcode(ERRCODE_UNDEFINED_OBJECT),
3603  errmsg("conversion \"%s\" does not exist",
3604  NameListToString(conname))));
3605  return conoid;
3606 }

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

Referenced by get_object_address().

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2203 of file namespace.c.

2204 {
2205  char *schemaname;
2206  char *stats_name;
2207  Oid namespaceId;
2208  Oid stats_oid = InvalidOid;
2209  ListCell *l;
2210 
2211  /* deconstruct the name list */
2212  DeconstructQualifiedName(names, &schemaname, &stats_name);
2213 
2214  if (schemaname)
2215  {
2216  /* use exact schema given */
2217  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2218  if (missing_ok && !OidIsValid(namespaceId))
2219  stats_oid = InvalidOid;
2220  else
2221  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2222  PointerGetDatum(stats_name),
2223  ObjectIdGetDatum(namespaceId));
2224  }
2225  else
2226  {
2227  /* search for it in search path */
2229 
2230  foreach(l, activeSearchPath)
2231  {
2232  namespaceId = lfirst_oid(l);
2233 
2234  if (namespaceId == myTempNamespace)
2235  continue; /* do not look in temp namespace */
2236  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2237  PointerGetDatum(stats_name),
2238  ObjectIdGetDatum(namespaceId));
2239  if (OidIsValid(stats_oid))
2240  break;
2241  }
2242  }
2243 
2244  if (!OidIsValid(stats_oid) && !missing_ok)
2245  ereport(ERROR,
2246  (errcode(ERRCODE_UNDEFINED_OBJECT),
2247  errmsg("statistics object \"%s\" does not exist",
2248  NameListToString(names))));
2249 
2250  return stats_oid;
2251 }
@ STATEXTNAMENSP
Definition: syscache.h:95

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

Referenced by AlterStatistics(), and get_object_address().

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2704 of file namespace.c.

2705 {
2706  char *schemaname;
2707  char *config_name;
2708  Oid namespaceId;
2709  Oid cfgoid = InvalidOid;
2710  ListCell *l;
2711 
2712  /* deconstruct the name list */
2713  DeconstructQualifiedName(names, &schemaname, &config_name);
2714 
2715  if (schemaname)
2716  {
2717  /* use exact schema given */
2718  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2719  if (missing_ok && !OidIsValid(namespaceId))
2720  cfgoid = InvalidOid;
2721  else
2722  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2723  PointerGetDatum(config_name),
2724  ObjectIdGetDatum(namespaceId));
2725  }
2726  else
2727  {
2728  /* search for it in search path */
2730 
2731  foreach(l, activeSearchPath)
2732  {
2733  namespaceId = lfirst_oid(l);
2734 
2735  if (namespaceId == myTempNamespace)
2736  continue; /* do not look in temp namespace */
2737 
2738  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2739  PointerGetDatum(config_name),
2740  ObjectIdGetDatum(namespaceId));
2741  if (OidIsValid(cfgoid))
2742  break;
2743  }
2744  }
2745 
2746  if (!OidIsValid(cfgoid) && !missing_ok)
2747  ereport(ERROR,
2748  (errcode(ERRCODE_UNDEFINED_OBJECT),
2749  errmsg("text search configuration \"%s\" does not exist",
2750  NameListToString(names))));
2751 
2752  return cfgoid;
2753 }
@ TSCONFIGNAMENSP
Definition: syscache.h:105

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

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

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2451 of file namespace.c.

2452 {
2453  char *schemaname;
2454  char *dict_name;
2455  Oid namespaceId;
2456  Oid dictoid = InvalidOid;
2457  ListCell *l;
2458 
2459  /* deconstruct the name list */
2460  DeconstructQualifiedName(names, &schemaname, &dict_name);
2461 
2462  if (schemaname)
2463  {
2464  /* use exact schema given */
2465  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2466  if (missing_ok && !OidIsValid(namespaceId))
2467  dictoid = InvalidOid;
2468  else
2469  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2470  PointerGetDatum(dict_name),
2471  ObjectIdGetDatum(namespaceId));
2472  }
2473  else
2474  {
2475  /* search for it in search path */
2477 
2478  foreach(l, activeSearchPath)
2479  {
2480  namespaceId = lfirst_oid(l);
2481 
2482  if (namespaceId == myTempNamespace)
2483  continue; /* do not look in temp namespace */
2484 
2485  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2486  PointerGetDatum(dict_name),
2487  ObjectIdGetDatum(namespaceId));
2488  if (OidIsValid(dictoid))
2489  break;
2490  }
2491  }
2492 
2493  if (!OidIsValid(dictoid) && !missing_ok)
2494  ereport(ERROR,
2495  (errcode(ERRCODE_UNDEFINED_OBJECT),
2496  errmsg("text search dictionary \"%s\" does not exist",
2497  NameListToString(names))));
2498 
2499  return dictoid;
2500 }
@ TSDICTNAMENSP
Definition: syscache.h:107

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

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

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2325 of file namespace.c.

2326 {
2327  char *schemaname;
2328  char *parser_name;
2329  Oid namespaceId;
2330  Oid prsoid = InvalidOid;
2331  ListCell *l;
2332 
2333  /* deconstruct the name list */
2334  DeconstructQualifiedName(names, &schemaname, &parser_name);
2335 
2336  if (schemaname)
2337  {
2338  /* use exact schema given */
2339  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2340  if (missing_ok && !OidIsValid(namespaceId))
2341  prsoid = InvalidOid;
2342  else
2343  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2344  PointerGetDatum(parser_name),
2345  ObjectIdGetDatum(namespaceId));
2346  }
2347  else
2348  {
2349  /* search for it in search path */
2351 
2352  foreach(l, activeSearchPath)
2353  {
2354  namespaceId = lfirst_oid(l);
2355 
2356  if (namespaceId == myTempNamespace)
2357  continue; /* do not look in temp namespace */
2358 
2359  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2360  PointerGetDatum(parser_name),
2361  ObjectIdGetDatum(namespaceId));
2362  if (OidIsValid(prsoid))
2363  break;
2364  }
2365  }
2366 
2367  if (!OidIsValid(prsoid) && !missing_ok)
2368  ereport(ERROR,
2369  (errcode(ERRCODE_UNDEFINED_OBJECT),
2370  errmsg("text search parser \"%s\" does not exist",
2371  NameListToString(names))));
2372 
2373  return prsoid;
2374 }
@ TSPARSERNAMENSP
Definition: syscache.h:109

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

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

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2578 of file namespace.c.

2579 {
2580  char *schemaname;
2581  char *template_name;
2582  Oid namespaceId;
2583  Oid tmploid = InvalidOid;
2584  ListCell *l;
2585 
2586  /* deconstruct the name list */
2587  DeconstructQualifiedName(names, &schemaname, &template_name);
2588 
2589  if (schemaname)
2590  {
2591  /* use exact schema given */
2592  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2593  if (missing_ok && !OidIsValid(namespaceId))
2594  tmploid = InvalidOid;
2595  else
2596  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2597  PointerGetDatum(template_name),
2598  ObjectIdGetDatum(namespaceId));
2599  }
2600  else
2601  {
2602  /* search for it in search path */
2604 
2605  foreach(l, activeSearchPath)
2606  {
2607  namespaceId = lfirst_oid(l);
2608 
2609  if (namespaceId == myTempNamespace)
2610  continue; /* do not look in temp namespace */
2611 
2612  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2613  PointerGetDatum(template_name),
2614  ObjectIdGetDatum(namespaceId));
2615  if (OidIsValid(tmploid))
2616  break;
2617  }
2618  }
2619 
2620  if (!OidIsValid(tmploid) && !missing_ok)
2621  ereport(ERROR,
2622  (errcode(ERRCODE_UNDEFINED_OBJECT),
2623  errmsg("text search template \"%s\" does not exist",
2624  NameListToString(names))));
2625 
2626  return tmploid;
2627 }
@ TSTEMPLATENAMENSP
Definition: syscache.h:111

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

Referenced by DefineTSDictionary(), and get_object_address().

◆ GetSearchPathMatcher()

SearchPathMatcher* GetSearchPathMatcher ( MemoryContext  context)

Definition at line 3384 of file namespace.c.

3385 {
3386  SearchPathMatcher *result;
3387  List *schemas;
3388  MemoryContext oldcxt;
3389 
3391 
3392  oldcxt = MemoryContextSwitchTo(context);
3393 
3394  result = (SearchPathMatcher *) palloc0(sizeof(SearchPathMatcher));
3395  schemas = list_copy(activeSearchPath);
3396  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3397  {
3398  if (linitial_oid(schemas) == myTempNamespace)
3399  result->addTemp = true;
3400  else
3401  {
3402  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3403  result->addCatalog = true;
3404  }
3405  schemas = list_delete_first(schemas);
3406  }
3407  result->schemas = schemas;
3408  result->generation = activePathGeneration;
3409 
3410  MemoryContextSwitchTo(oldcxt);
3411 
3412  return result;
3413 }
void * palloc0(Size size)
Definition: mcxt.c:1257
static uint64 activePathGeneration
Definition: namespace.c:142
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138

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

Referenced by CompleteCachedPlan(), and RevalidateCachedQuery().

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3299 of file namespace.c.

3300 {
3301  int result;
3302  char *nspname;
3303 
3304  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3305  nspname = get_namespace_name(namespaceId);
3306  if (!nspname)
3307  return InvalidBackendId; /* no such namespace? */
3308  if (strncmp(nspname, "pg_temp_", 8) == 0)
3309  result = atoi(nspname + 8);
3310  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3311  result = atoi(nspname + 14);
3312  else
3313  result = InvalidBackendId;
3314  pfree(nspname);
3315  return result;
3316 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3348

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

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

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3338 of file namespace.c.

3339 {
3340  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3341  *tempNamespaceId = myTempNamespace;
3342  *tempToastNamespaceId = myTempToastNamespace;
3343 }

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3324 of file namespace.c.

3325 {
3327  return myTempToastNamespace;
3328 }

References Assert(), myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4152 of file namespace.c.

4153 {
4155  {
4156  /*
4157  * In bootstrap mode, the search path must be 'pg_catalog' so that
4158  * tables are created in the proper namespace; ignore the GUC setting.
4159  */
4160  MemoryContext oldcxt;
4161 
4163  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4164  MemoryContextSwitchTo(oldcxt);
4165  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4166  baseTempCreationPending = false;
4167  baseSearchPathValid = true;
4172  activePathGeneration++; /* pro forma */
4173  }
4174  else
4175  {
4176  /*
4177  * In normal mode, arrange for a callback on any syscache invalidation
4178  * of pg_namespace or pg_authid rows. (Changing a role name may affect
4179  * the meaning of the special string $user.)
4180  */
4183  (Datum) 0);
4186  (Datum) 0);
4187  /* Force search path to be recomputed on next use */
4188  baseSearchPathValid = false;
4189  }
4190 }
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1519
MemoryContext TopMemoryContext
Definition: mcxt.c:141
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:414
Oid GetUserId(void)
Definition: miscinit.c:509
static bool baseTempCreationPending
Definition: namespace.c:150
static Oid baseCreationNamespace
Definition: namespace.c:148
static Oid namespaceUser
Definition: namespace.c:152
static List * baseSearchPath
Definition: namespace.c:146
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4197
#define list_make1_oid(x1)
Definition: pg_list.h:242
@ AUTHOID
Definition: syscache.h:45
@ NAMESPACEOID
Definition: syscache.h:70

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

Referenced by InitPostgres().

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3220 of file namespace.c.

3221 {
3222  bool result;
3223  char *nspname;
3224 
3225  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3226  nspname = get_namespace_name(namespaceId);
3227  if (!nspname)
3228  return false; /* no such namespace? */
3229  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3230  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3231  pfree(nspname);
3232  return result;
3233 }

References get_namespace_name(), and pfree().

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

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3243 of file namespace.c.

3244 {
3245  /* If it's my own temp namespace, say "false" */
3246  if (isTempOrTempToastNamespace(namespaceId))
3247  return false;
3248  /* Else, if it's any temp namespace, say "true" */
3249  return isAnyTempNamespace(namespaceId);
3250 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3206

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3182 of file namespace.c.

3183 {
3184  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3185  return true;
3186  return false;
3187 }

References myTempNamespace, and OidIsValid.

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

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3206 of file namespace.c.

3207 {
3208  if (OidIsValid(myTempNamespace) &&
3209  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3210  return true;
3211  return false;
3212 }

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3194 of file namespace.c.

3195 {
3196  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3197  return true;
3198  return false;
3199 }

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2961 of file namespace.c.

2962 {
2963  Oid namespaceId;
2964  AclResult aclresult;
2965 
2966  /* check for pg_temp alias */
2967  if (strcmp(nspname, "pg_temp") == 0)
2968  {
2969  /* Initialize temp namespace */
2970  AccessTempTableNamespace(false);
2971  return myTempNamespace;
2972  }
2973 
2974  namespaceId = get_namespace_oid(nspname, false);
2975 
2976  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
2977  if (aclresult != ACLCHECK_OK)
2978  aclcheck_error(aclresult, OBJECT_SCHEMA,
2979  nspname);
2980 
2981  return namespaceId;
2982 }
AclResult
Definition: acl.h:181
@ ACLCHECK_OK
Definition: acl.h:182
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2669
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3760
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3068
@ OBJECT_SCHEMA
Definition: parsenodes.h:2156
#define ACL_CREATE
Definition: parsenodes.h:92

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

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

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2918 of file namespace.c.

2919 {
2920  Oid namespaceId;
2921  AclResult aclresult;
2922 
2923  /* check for pg_temp alias */
2924  if (strcmp(nspname, "pg_temp") == 0)
2925  {
2927  return myTempNamespace;
2928 
2929  /*
2930  * Since this is used only for looking up existing objects, there is
2931  * no point in trying to initialize the temp namespace here; and doing
2932  * so might create problems for some callers --- just fall through.
2933  */
2934  }
2935 
2936  namespaceId = get_namespace_oid(nspname, missing_ok);
2937  if (missing_ok && !OidIsValid(namespaceId))
2938  return InvalidOid;
2939 
2940  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_USAGE);
2941  if (aclresult != ACLCHECK_OK)
2942  aclcheck_error(aclresult, OBJECT_SCHEMA,
2943  nspname);
2944  /* Schema search hook for this lookup */
2945  InvokeNamespaceSearchHook(namespaceId, true);
2946 
2947  return namespaceId;
2948 }
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:208
#define ACL_USAGE
Definition: parsenodes.h:91

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

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

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2888 of file namespace.c.

2889 {
2890  /* check for pg_temp alias */
2891  if (strcmp(nspname, "pg_temp") == 0)
2892  {
2894  {
2896  return myTempNamespace;
2897  }
2898 
2899  /*
2900  * Since this is used only for looking up existing objects, there is
2901  * no point in trying to initialize the temp namespace here; and doing
2902  * so might create problems for some callers. Just report "not found".
2903  */
2904  return InvalidOid;
2905  }
2906 
2907  return get_namespace_oid(nspname, true);
2908 }

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

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

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( const List names)

Definition at line 3087 of file namespace.c.

3088 {
3089  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3090 
3091  switch (list_length(names))
3092  {
3093  case 1:
3094  rel->relname = strVal(linitial(names));
3095  break;
3096  case 2:
3097  rel->schemaname = strVal(linitial(names));
3098  rel->relname = strVal(lsecond(names));
3099  break;
3100  case 3:
3101  rel->catalogname = strVal(linitial(names));
3102  rel->schemaname = strVal(lsecond(names));
3103  rel->relname = strVal(lthird(names));
3104  break;
3105  default:
3106  ereport(ERROR,
3107  (errcode(ERRCODE_SYNTAX_ERROR),
3108  errmsg("improper relation name (too many dotted names): %s",
3109  NameListToString(names))));
3110  break;
3111  }
3112 
3113  return rel;
3114 }
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:425
char * relname
Definition: primnodes.h:74
char * catalogname
Definition: primnodes.h:68
char * schemaname
Definition: primnodes.h:71

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

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

◆ NameListToQuotedString()

char* NameListToQuotedString ( const List names)

Definition at line 3161 of file namespace.c.

3162 {
3164  ListCell *l;
3165 
3166  initStringInfo(&string);
3167 
3168  foreach(l, names)
3169  {
3170  if (l != list_head(names))
3171  appendStringInfoChar(&string, '.');
3173  }
3174 
3175  return string.data;
3176 }
#define lfirst(lc)
Definition: pg_list.h:172
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
char string[11]
Definition: preproc-type.c:52
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11965
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

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

◆ NameListToString()

char* NameListToString ( const List names)

Definition at line 3127 of file namespace.c.

3128 {
3130  ListCell *l;
3131 
3132  initStringInfo(&string);
3133 
3134  foreach(l, names)
3135  {
3136  Node *name = (Node *) lfirst(l);
3137 
3138  if (l != list_head(names))
3139  appendStringInfoChar(&string, '.');
3140 
3141  if (IsA(name, String))
3142  appendStringInfoString(&string, strVal(name));
3143  else if (IsA(name, A_Star))
3144  appendStringInfoChar(&string, '*');
3145  else
3146  elog(ERROR, "unexpected node type in name list: %d",
3147  (int) nodeTag(name));
3148  }
3149 
3150  return string.data;
3151 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:179
#define nodeTag(nodeptr)
Definition: nodes.h:133
Definition: nodes.h:129
Definition: value.h:64
const char * name

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

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

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1858 of file namespace.c.

1859 {
1860  HeapTuple opctup;
1861  Form_pg_opclass opcform;
1862  Oid opcnamespace;
1863  bool visible;
1864 
1865  opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
1866  if (!HeapTupleIsValid(opctup))
1867  elog(ERROR, "cache lookup failed for opclass %u", opcid);
1868  opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1869 
1871 
1872  /*
1873  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1874  * the system namespace are surely in the path and so we needn't even do
1875  * list_member_oid() for them.
1876  */
1877  opcnamespace = opcform->opcnamespace;
1878  if (opcnamespace != PG_CATALOG_NAMESPACE &&
1879  !list_member_oid(activeSearchPath, opcnamespace))
1880  visible = false;
1881  else
1882  {
1883  /*
1884  * If it is in the path, it might still not be visible; it could be
1885  * hidden by another opclass of the same name earlier in the path. So
1886  * we must do a slow check to see if this opclass would be found by
1887  * OpclassnameGetOpcid.
1888  */
1889  char *opcname = NameStr(opcform->opcname);
1890 
1891  visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1892  }
1893 
1894  ReleaseSysCache(opctup);
1895 
1896  return visible;
1897 }
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
Definition: namespace.c:1825
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
@ CLAOID
Definition: syscache.h:48

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

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

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1825 of file namespace.c.

1826 {
1827  Oid opcid;
1828  ListCell *l;
1829 
1831 
1832  foreach(l, activeSearchPath)
1833  {
1834  Oid namespaceId = lfirst_oid(l);
1835 
1836  if (namespaceId == myTempNamespace)
1837  continue; /* do not look in temp namespace */
1838 
1839  opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
1840  ObjectIdGetDatum(amid),
1841  PointerGetDatum(opcname),
1842  ObjectIdGetDatum(namespaceId));
1843  if (OidIsValid(opcid))
1844  return opcid;
1845  }
1846 
1847  /* Not found in path */
1848  return InvalidOid;
1849 }
@ CLAAMNAMENSP
Definition: syscache.h:47
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:204

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

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

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1772 of file namespace.c.

1773 {
1774  HeapTuple oprtup;
1775  Form_pg_operator oprform;
1776  Oid oprnamespace;
1777  bool visible;
1778 
1780  if (!HeapTupleIsValid(oprtup))
1781  elog(ERROR, "cache lookup failed for operator %u", oprid);
1782  oprform = (Form_pg_operator) GETSTRUCT(oprtup);
1783 
1785 
1786  /*
1787  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1788  * the system namespace are surely in the path and so we needn't even do
1789  * list_member_oid() for them.
1790  */
1791  oprnamespace = oprform->oprnamespace;
1792  if (oprnamespace != PG_CATALOG_NAMESPACE &&
1793  !list_member_oid(activeSearchPath, oprnamespace))
1794  visible = false;
1795  else
1796  {
1797  /*
1798  * If it is in the path, it might still not be visible; it could be
1799  * hidden by another operator of the same name and arguments earlier
1800  * in the path. So we must do a slow check to see if this is the same
1801  * operator that would be found by OpernameGetOprid.
1802  */
1803  char *oprname = NameStr(oprform->oprname);
1804 
1805  visible = (OpernameGetOprid(list_make1(makeString(oprname)),
1806  oprform->oprleft, oprform->oprright)
1807  == oprid);
1808  }
1809 
1810  ReleaseSysCache(oprtup);
1811 
1812  return visible;
1813 }
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1508
Oid oprid(Operator op)
Definition: parse_oper.c:250
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
@ OPEROID
Definition: syscache.h:72

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

Referenced by format_operator_extended(), and pg_operator_is_visible().

◆ OpernameGetCandidates()

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

Definition at line 1611 of file namespace.c.

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

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

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

◆ OpernameGetOprid()

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

Definition at line 1508 of file namespace.c.

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

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

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

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1941 of file namespace.c.

1942 {
1943  HeapTuple opftup;
1944  Form_pg_opfamily opfform;
1945  Oid opfnamespace;
1946  bool visible;
1947 
1948  opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
1949  if (!HeapTupleIsValid(opftup))
1950  elog(ERROR, "cache lookup failed for opfamily %u", opfid);
1951  opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
1952 
1954 
1955  /*
1956  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1957  * the system namespace are surely in the path and so we needn't even do
1958  * list_member_oid() for them.
1959  */
1960  opfnamespace = opfform->opfnamespace;
1961  if (opfnamespace != PG_CATALOG_NAMESPACE &&
1962  !list_member_oid(activeSearchPath, opfnamespace))
1963  visible = false;
1964  else
1965  {
1966  /*
1967  * If it is in the path, it might still not be visible; it could be
1968  * hidden by another opfamily of the same name earlier in the path. So
1969  * we must do a slow check to see if this opfamily would be found by
1970  * OpfamilynameGetOpfid.
1971  */
1972  char *opfname = NameStr(opfform->opfname);
1973 
1974  visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
1975  }
1976 
1977  ReleaseSysCache(opftup);
1978 
1979  return visible;
1980 }
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
Definition: namespace.c:1908
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
@ OPFAMILYOID
Definition: syscache.h:74

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1908 of file namespace.c.

1909 {
1910  Oid opfid;
1911  ListCell *l;
1912 
1914 
1915  foreach(l, activeSearchPath)
1916  {
1917  Oid namespaceId = lfirst_oid(l);
1918 
1919  if (namespaceId == myTempNamespace)
1920  continue; /* do not look in temp namespace */
1921 
1922  opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
1923  ObjectIdGetDatum(amid),
1924  PointerGetDatum(opfname),
1925  ObjectIdGetDatum(namespaceId));
1926  if (OidIsValid(opfid))
1927  return opfid;
1928  }
1929 
1930  /* Not found in path */
1931  return InvalidOid;
1932 }
@ OPFAMILYAMNAMENSP
Definition: syscache.h:73

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( const List names,
char **  objname_p 
)

Definition at line 3020 of file namespace.c.

3021 {
3022  char *schemaname;
3023  Oid namespaceId;
3024 
3025  /* deconstruct the name list */
3026  DeconstructQualifiedName(names, &schemaname, objname_p);
3027 
3028  if (schemaname)
3029  {
3030  /* check for pg_temp alias */
3031  if (strcmp(schemaname, "pg_temp") == 0)
3032  {
3033  /* Initialize temp namespace */
3034  AccessTempTableNamespace(false);
3035  return myTempNamespace;
3036  }
3037  /* use exact schema given */
3038  namespaceId = get_namespace_oid(schemaname, false);
3039  /* we do not check for USAGE rights here! */
3040  }
3041  else
3042  {
3043  /* use the default creation namespace */
3046  {
3047  /* Need to initialize temp namespace */
3049  return myTempNamespace;
3050  }
3051  namespaceId = activeCreationNamespace;
3052  if (!OidIsValid(namespaceId))
3053  ereport(ERROR,
3054  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3055  errmsg("no schema has been selected to create in")));
3056  }
3057 
3058  return namespaceId;
3059 }

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

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

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 626 of file namespace.c.

627 {
628  switch (newRelation->relpersistence)
629  {
630  case RELPERSISTENCE_TEMP:
632  {
634  ereport(ERROR,
635  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
636  errmsg("cannot create relations in temporary schemas of other sessions")));
637  else
638  ereport(ERROR,
639  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
640  errmsg("cannot create temporary relation in non-temporary schema")));
641  }
642  break;
643  case RELPERSISTENCE_PERMANENT:
645  newRelation->relpersistence = RELPERSISTENCE_TEMP;
646  else if (isAnyTempNamespace(nspid))
647  ereport(ERROR,
648  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
649  errmsg("cannot create relations in temporary schemas of other sessions")));
650  break;
651  default:
653  ereport(ERROR,
654  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
655  errmsg("only temporary relations may be created in temporary schemas")));
656  }
657 }
int nspid
char relpersistence
Definition: primnodes.h:80

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 519 of file namespace.c.

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

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 434 of file namespace.c.

435 {
436  Oid namespaceId;
437 
438  /*
439  * We check the catalog name and then ignore it.
440  */
441  if (newRelation->catalogname)
442  {
443  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
444  ereport(ERROR,
445  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
446  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
447  newRelation->catalogname, newRelation->schemaname,
448  newRelation->relname)));
449  }
450 
451  if (newRelation->schemaname)
452  {
453  /* check for pg_temp alias */
454  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
455  {
456  /* Initialize temp namespace */
458  return myTempNamespace;
459  }
460  /* use exact schema given */
461  namespaceId = get_namespace_oid(newRelation->schemaname, false);
462  /* we do not check for USAGE rights here! */
463  }
464  else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
465  {
466  /* Initialize temp namespace */
468  return myTempNamespace;
469  }
470  else
471  {
472  /* use the default creation namespace */
475  {
476  /* Need to initialize temp namespace */
478  return myTempNamespace;
479  }
480  namespaceId = activeCreationNamespace;
481  if (!OidIsValid(namespaceId))
482  ereport(ERROR,
483  (errcode(ERRCODE_UNDEFINED_SCHEMA),
484  errmsg("no schema has been selected to create in")));
485  }
486 
487  /* Note: callers will check for CREATE rights when appropriate */
488 
489  return namespaceId;
490 }

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

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

◆ RangeVarGetRelidExtended()

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

Definition at line 221 of file namespace.c.

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

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

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

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 693 of file namespace.c.

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

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

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

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 665 of file namespace.c.

666 {
667  Oid relid;
668  ListCell *l;
669 
671 
672  foreach(l, activeSearchPath)
673  {
674  Oid namespaceId = lfirst_oid(l);
675 
676  relid = get_relname_relid(relname, namespaceId);
677  if (OidIsValid(relid))
678  return relid;
679  }
680 
681  /* Not found in path */
682  return InvalidOid;
683 }

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

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

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4089 of file namespace.c.

4090 {
4093 }
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4043

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

◆ SearchPathMatchesCurrentEnvironment()

bool SearchPathMatchesCurrentEnvironment ( SearchPathMatcher path)

Definition at line 3443 of file namespace.c.

3444 {
3445  ListCell *lc,
3446  *lcp;
3447 
3449 
3450  /* Quick out if already known equal to active path. */
3451  if (path->generation == activePathGeneration)
3452  return true;
3453 
3454  /* We scan down the activeSearchPath to see if it matches the input. */
3456 
3457  /* If path->addTemp, first item should be my temp namespace. */
3458  if (path->addTemp)
3459  {
3460  if (lc && lfirst_oid(lc) == myTempNamespace)
3461  lc = lnext(activeSearchPath, lc);
3462  else
3463  return false;
3464  }
3465  /* If path->addCatalog, next item should be pg_catalog. */
3466  if (path->addCatalog)
3467  {
3468  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3469  lc = lnext(activeSearchPath, lc);
3470  else
3471  return false;
3472  }
3473  /* We should now be looking at the activeCreationNamespace. */
3474  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3475  return false;
3476  /* The remainder of activeSearchPath should match path->schemas. */
3477  foreach(lcp, path->schemas)
3478  {
3479  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3480  lc = lnext(activeSearchPath, lc);
3481  else
3482  return false;
3483  }
3484  if (lc)
3485  return false;
3486 
3487  /*
3488  * Update path->generation so that future tests will return quickly, so
3489  * long as the active search path doesn't change.
3490  */
3492 
3493  return true;
3494 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343

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

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

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3354 of file namespace.c.

3355 {
3356  /* Worker should not have created its own namespaces ... */
3360 
3361  /* Assign same namespace OIDs that leader has */
3362  myTempNamespace = tempNamespaceId;
3363  myTempToastNamespace = tempToastNamespaceId;
3364 
3365  /*
3366  * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
3367  * Even if the namespace is new so far as the leader is concerned, it's
3368  * not new to the worker, and we certainly wouldn't want the worker trying
3369  * to destroy it.
3370  */
3371 
3372  baseSearchPathValid = false; /* may need to rebuild list */
3373 }

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

Referenced by ParallelWorkerMain().

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  relid)

Definition at line 2260 of file namespace.c.

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

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

Referenced by getObjectDescription(), and pg_statistics_obj_is_visible().

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 2762 of file namespace.c.

2763 {
2764  HeapTuple tup;
2765  Form_pg_ts_config form;
2766  Oid namespace;
2767  bool visible;
2768 
2770  if (!HeapTupleIsValid(tup))
2771  elog(ERROR, "cache lookup failed for text search configuration %u",
2772  cfgid);
2773  form = (Form_pg_ts_config) GETSTRUCT(tup);
2774 
2776 
2777  /*
2778  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2779  * the system namespace are surely in the path and so we needn't even do
2780  * list_member_oid() for them.
2781  */
2782  namespace = form->cfgnamespace;
2783  if (namespace != PG_CATALOG_NAMESPACE &&
2784  !list_member_oid(activeSearchPath, namespace))
2785  visible = false;
2786  else
2787  {
2788  /*
2789  * If it is in the path, it might still not be visible; it could be
2790  * hidden by another configuration of the same name earlier in the
2791  * path. So we must do a slow check for conflicting configurations.
2792  */
2793  char *name = NameStr(form->cfgname);
2794  ListCell *l;
2795 
2796  visible = false;
2797  foreach(l, activeSearchPath)
2798  {
2799  Oid namespaceId = lfirst_oid(l);
2800 
2801  if (namespaceId == myTempNamespace)
2802  continue; /* do not look in temp namespace */
2803 
2804  if (namespaceId == namespace)
2805  {
2806  /* Found it first in path */
2807  visible = true;
2808  break;
2809  }
2812  ObjectIdGetDatum(namespaceId)))
2813  {
2814  /* Found something else first in path */
2815  break;
2816  }
2817  }
2818  }
2819 
2820  ReleaseSysCache(tup);
2821 
2822  return visible;
2823 }
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
@ TSCONFIGOID
Definition: syscache.h:106

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

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

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2509 of file namespace.c.

2510 {
2511  HeapTuple tup;
2512  Form_pg_ts_dict form;
2513  Oid namespace;
2514  bool visible;
2515 
2516  tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
2517  if (!HeapTupleIsValid(tup))
2518  elog(ERROR, "cache lookup failed for text search dictionary %u",
2519  dictId);
2520  form = (Form_pg_ts_dict) GETSTRUCT(tup);
2521 
2523 
2524  /*
2525  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2526  * the system namespace are surely in the path and so we needn't even do
2527  * list_member_oid() for them.
2528  */
2529  namespace = form->dictnamespace;
2530  if (namespace != PG_CATALOG_NAMESPACE &&
2531  !list_member_oid(activeSearchPath, namespace))
2532  visible = false;
2533  else
2534  {
2535  /*
2536  * If it is in the path, it might still not be visible; it could be
2537  * hidden by another dictionary of the same name earlier in the path.
2538  * So we must do a slow check for conflicting dictionaries.
2539  */
2540  char *name = NameStr(form->dictname);
2541  ListCell *l;
2542 
2543  visible = false;
2544  foreach(l, activeSearchPath)
2545  {
2546  Oid namespaceId = lfirst_oid(l);
2547 
2548  if (namespaceId == myTempNamespace)
2549  continue; /* do not look in temp namespace */
2550 
2551  if (namespaceId == namespace)
2552  {
2553  /* Found it first in path */
2554  visible = true;
2555  break;
2556  }
2559  ObjectIdGetDatum(namespaceId)))
2560  {
2561  /* Found something else first in path */
2562  break;
2563  }
2564  }
2565  }
2566 
2567  ReleaseSysCache(tup);
2568 
2569  return visible;
2570 }
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:52
@ TSDICTOID
Definition: syscache.h:108

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

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

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2383 of file namespace.c.

2384 {
2385  HeapTuple tup;
2386  Form_pg_ts_parser form;
2387  Oid namespace;
2388  bool visible;
2389 
2391  if (!HeapTupleIsValid(tup))
2392  elog(ERROR, "cache lookup failed for text search parser %u", prsId);
2393  form = (Form_pg_ts_parser) GETSTRUCT(tup);
2394 
2396 
2397  /*
2398  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2399  * the system namespace are surely in the path and so we needn't even do
2400  * list_member_oid() for them.
2401  */
2402  namespace = form->prsnamespace;
2403  if (namespace != PG_CATALOG_NAMESPACE &&
2404  !list_member_oid(activeSearchPath, namespace))
2405  visible = false;
2406  else
2407  {
2408  /*
2409  * If it is in the path, it might still not be visible; it could be
2410  * hidden by another parser of the same name earlier in the path. So
2411  * we must do a slow check for conflicting parsers.
2412  */
2413  char *name = NameStr(form->prsname);
2414  ListCell *l;
2415 
2416  visible = false;
2417  foreach(l, activeSearchPath)
2418  {
2419  Oid namespaceId = lfirst_oid(l);
2420 
2421  if (namespaceId == myTempNamespace)
2422  continue; /* do not look in temp namespace */
2423 
2424  if (namespaceId == namespace)
2425  {
2426  /* Found it first in path */
2427  visible = true;
2428  break;
2429  }
2432  ObjectIdGetDatum(namespaceId)))
2433  {
2434  /* Found something else first in path */
2435  break;
2436  }
2437  }
2438  }
2439 
2440  ReleaseSysCache(tup);
2441 
2442  return visible;
2443 }
FormData_pg_ts_parser * Form_pg_ts_parser
Definition: pg_ts_parser.h:55
@ TSPARSEROID
Definition: syscache.h:110

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

Referenced by getObjectDescription(), and pg_ts_parser_is_visible().

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 2636 of file namespace.c.

2637 {
2638  HeapTuple tup;
2639  Form_pg_ts_template form;
2640  Oid namespace;
2641  bool visible;
2642 
2644  if (!HeapTupleIsValid(tup))
2645  elog(ERROR, "cache lookup failed for text search template %u", tmplId);
2646  form = (Form_pg_ts_template) GETSTRUCT(tup);
2647 
2649 
2650  /*
2651  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2652  * the system namespace are surely in the path and so we needn't even do
2653  * list_member_oid() for them.
2654  */
2655  namespace = form->tmplnamespace;
2656  if (namespace != PG_CATALOG_NAMESPACE &&
2657  !list_member_oid(activeSearchPath, namespace))
2658  visible = false;
2659  else
2660  {
2661  /*
2662  * If it is in the path, it might still not be visible; it could be
2663  * hidden by another template of the same name earlier in the path. So
2664  * we must do a slow check for conflicting templates.
2665  */
2666  char *name = NameStr(form->tmplname);
2667  ListCell *l;
2668 
2669  visible = false;
2670  foreach(l, activeSearchPath)
2671  {
2672  Oid namespaceId = lfirst_oid(l);
2673 
2674  if (namespaceId == myTempNamespace)
2675  continue; /* do not look in temp namespace */
2676 
2677  if (namespaceId == namespace)
2678  {
2679  /* Found it first in path */
2680  visible = true;
2681  break;
2682  }
2685  ObjectIdGetDatum(namespaceId)))
2686  {
2687  /* Found something else first in path */
2688  break;
2689  }
2690  }
2691  }
2692 
2693  ReleaseSysCache(tup);
2694 
2695  return visible;
2696 }
FormData_pg_ts_template * Form_pg_ts_template
@ TSTEMPLATEOID
Definition: syscache.h:112

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

Referenced by getObjectDescription(), and pg_ts_template_is_visible().

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 801 of file namespace.c.

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

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

Referenced by format_type_extended(), and pg_type_is_visible().

◆ TypenameGetTypid()

Oid TypenameGetTypid ( const char *  typname)

Definition at line 756 of file namespace.c.

757 {
758  return TypenameGetTypidExtended(typname, true);
759 }
Oid TypenameGetTypidExtended(const char *typname, bool temp_ok)
Definition: namespace.c:769

References TypenameGetTypidExtended(), and typname.

◆ TypenameGetTypidExtended()

Oid TypenameGetTypidExtended ( const char *  typname,
bool  temp_ok 
)

Definition at line 769 of file namespace.c.

770 {
771  Oid typid;
772  ListCell *l;
773 
775 
776  foreach(l, activeSearchPath)
777  {
778  Oid namespaceId = lfirst_oid(l);
779 
780  if (!temp_ok && namespaceId == myTempNamespace)
781  continue; /* do not look in temp namespace */
782 
783  typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
785  ObjectIdGetDatum(namespaceId));
786  if (OidIsValid(typid))
787  return typid;
788  }
789 
790  /* Not found in path */
791  return InvalidOid;
792 }

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

Referenced by LookupTypeNameExtended(), and TypenameGetTypid().

Variable Documentation

◆ namespace_search_path

PGDLLIMPORT char* namespace_search_path
extern

Definition at line 182 of file namespace.c.

Referenced by CreateSchemaCommand(), and recomputeNamespacePath().