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

Go to the source code of this file.

Data Structures

struct  _FuncCandidateList
 
struct  OverrideSearchPath
 

Macros

#define RangeVarGetRelid(relation, lockmode, missing_ok)
 

Typedefs

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

Enumerations

enum  RVROption { RVR_MISSING_OK = 1 << 0, RVR_NOWAIT = 1 << 1, RVR_SKIP_LOCKED = 1 << 2 }
 

Functions

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

Variables

char * namespace_search_path
 

Macro Definition Documentation

◆ RangeVarGetRelid

Typedef Documentation

◆ FuncCandidateList

◆ OverrideSearchPath

◆ RangeVarGetRelidCallback

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

Definition at line 60 of file namespace.h.

◆ RVROption

Enumeration Type Documentation

◆ RVROption

enum RVROption
Enumerator
RVR_MISSING_OK 
RVR_NOWAIT 
RVR_SKIP_LOCKED 

Definition at line 53 of file namespace.h.

54 {
55  RVR_MISSING_OK = 1 << 0, /* don't error if relation doesn't exist */
56  RVR_NOWAIT = 1 << 1, /* error if relation cannot be locked */
57  RVR_SKIP_LOCKED = 1 << 2 /* skip if relation cannot be locked */
58 } RVROption;
RVROption
Definition: namespace.h:53

Function Documentation

◆ AtEOSubXact_Namespace()

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

Definition at line 3962 of file namespace.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

3964 {
3965  OverrideStackEntry *entry;
3966 
3967  if (myTempNamespaceSubID == mySubid)
3968  {
3969  if (isCommit)
3970  myTempNamespaceSubID = parentSubid;
3971  else
3972  {
3974  /* TEMP namespace creation failed, so reset state */
3977  baseSearchPathValid = false; /* need to rebuild list */
3978  }
3979  }
3980 
3981  /*
3982  * Clean up if someone failed to do PopOverrideSearchPath
3983  */
3984  while (overrideStack)
3985  {
3988  break;
3989  if (isCommit)
3990  elog(WARNING, "leaked override search path");
3992  list_free(entry->searchPath);
3993  pfree(entry);
3994  }
3995 
3996  /* Activate the next level down. */
3997  if (overrideStack)
3998  {
4000  activeSearchPath = entry->searchPath;
4002  activeTempCreationPending = false; /* XXX is this OK? */
4003  }
4004  else
4005  {
4006  /* If not baseSearchPathValid, this is useless but harmless */
4010  }
4011 }
static bool baseSearchPathValid
Definition: namespace.c:152
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
static List * overrideStack
Definition: namespace.c:163
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:1031
#define linitial(l)
Definition: pg_list.h:111
static bool baseTempCreationPending
Definition: namespace.c:147
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:143
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:753
#define InvalidSubTransactionId
Definition: c.h:480
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1133
#define elog
Definition: elog.h:219
List * list_delete_first(List *list)
Definition: list.c:666

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 3907 of file namespace.c.

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

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

3908 {
3909  /*
3910  * If we abort the transaction in which a temp namespace was selected,
3911  * we'll have to do any creation or cleanout work over again. So, just
3912  * forget the namespace entirely until next time. On the other hand, if
3913  * we commit then register an exit callback to clean out the temp tables
3914  * at backend shutdown. (We only want to register the callback once per
3915  * session, so this is a good place to do it.)
3916  */
3917  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
3918  {
3919  if (isCommit)
3921  else
3922  {
3925  baseSearchPathValid = false; /* need to rebuild list */
3926  }
3928  }
3929 
3930  /*
3931  * Clean up if someone failed to do PopOverrideSearchPath
3932  */
3933  if (overrideStack)
3934  {
3935  if (isCommit)
3936  elog(WARNING, "leaked override search path");
3937  while (overrideStack)
3938  {
3939  OverrideStackEntry *entry;
3940 
3943  list_free(entry->searchPath);
3944  pfree(entry);
3945  }
3946  /* If not baseSearchPathValid, this is useless but harmless */
3950  }
3951 }
static bool baseSearchPathValid
Definition: namespace.c:152
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
static List * overrideStack
Definition: namespace.c:163
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:1031
#define linitial(l)
Definition: pg_list.h:111
static bool baseTempCreationPending
Definition: namespace.c:147
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:331
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:143
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidSubTransactionId
Definition: c.h:480
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1133
#define elog
Definition: elog.h:219
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4048
List * list_delete_first(List *list)
Definition: list.c:666

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2947 of file namespace.c.

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

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

2948 {
2949  /* disallow renaming into or out of temp schemas */
2950  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2951  ereport(ERROR,
2952  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2953  errmsg("cannot move objects into or out of temporary schemas")));
2954 
2955  /* same for TOAST schema */
2956  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
2957  ereport(ERROR,
2958  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2959  errmsg("cannot move objects into or out of TOAST schema")));
2960 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3175

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 1993 of file namespace.c.

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

Referenced by CollationIsVisible().

1994 {
1995  int32 dbencoding = GetDatabaseEncoding();
1996  ListCell *l;
1997 
1999 
2000  foreach(l, activeSearchPath)
2001  {
2002  Oid namespaceId = lfirst_oid(l);
2003  Oid collid;
2004 
2005  if (namespaceId == myTempNamespace)
2006  continue; /* do not look in temp namespace */
2007 
2008  collid = lookup_collation(collname, namespaceId, dbencoding);
2009  if (OidIsValid(collid))
2010  return collid;
2011  }
2012 
2013  /* Not found in path */
2014  return InvalidOid;
2015 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
signed int int32
Definition: c.h:313
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1942
int GetDatabaseEncoding(void)
Definition: mbutils.c:1004
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2027 of file namespace.c.

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

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

2028 {
2029  HeapTuple colltup;
2030  Form_pg_collation collform;
2031  Oid collnamespace;
2032  bool visible;
2033 
2034  colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
2035  if (!HeapTupleIsValid(colltup))
2036  elog(ERROR, "cache lookup failed for collation %u", collid);
2037  collform = (Form_pg_collation) GETSTRUCT(colltup);
2038 
2040 
2041  /*
2042  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2043  * the system namespace are surely in the path and so we needn't even do
2044  * list_member_oid() for them.
2045  */
2046  collnamespace = collform->collnamespace;
2047  if (collnamespace != PG_CATALOG_NAMESPACE &&
2048  !list_member_oid(activeSearchPath, collnamespace))
2049  visible = false;
2050  else
2051  {
2052  /*
2053  * If it is in the path, it might still not be visible; it could be
2054  * hidden by another collation of the same name earlier in the path,
2055  * or it might not work with the current DB encoding. So we must do a
2056  * slow check to see if this collation would be found by
2057  * CollationGetCollid.
2058  */
2059  char *collname = NameStr(collform->collname);
2060 
2061  visible = (CollationGetCollid(collname) == collid);
2062  }
2063 
2064  ReleaseSysCache(colltup);
2065 
2066  return visible;
2067 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
Oid CollationGetCollid(const char *collname)
Definition: namespace.c:1993
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:49
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2078 of file namespace.c.

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

Referenced by ConversionIsVisible().

2079 {
2080  Oid conid;
2081  ListCell *l;
2082 
2084 
2085  foreach(l, activeSearchPath)
2086  {
2087  Oid namespaceId = lfirst_oid(l);
2088 
2089  if (namespaceId == myTempNamespace)
2090  continue; /* do not look in temp namespace */
2091 
2092  conid = GetSysCacheOid2(CONNAMENSP,
2093  PointerGetDatum(conname),
2094  ObjectIdGetDatum(namespaceId));
2095  if (OidIsValid(conid))
2096  return conid;
2097  }
2098 
2099  /* Not found in path */
2100  return InvalidOid;
2101 }
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2110 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_conversion_is_visible().

2111 {
2112  HeapTuple contup;
2113  Form_pg_conversion conform;
2114  Oid connamespace;
2115  bool visible;
2116 
2117  contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
2118  if (!HeapTupleIsValid(contup))
2119  elog(ERROR, "cache lookup failed for conversion %u", conid);
2120  conform = (Form_pg_conversion) GETSTRUCT(contup);
2121 
2123 
2124  /*
2125  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2126  * the system namespace are surely in the path and so we needn't even do
2127  * list_member_oid() for them.
2128  */
2129  connamespace = conform->connamespace;
2130  if (connamespace != PG_CATALOG_NAMESPACE &&
2131  !list_member_oid(activeSearchPath, connamespace))
2132  visible = false;
2133  else
2134  {
2135  /*
2136  * If it is in the path, it might still not be visible; it could be
2137  * hidden by another conversion of the same name earlier in the path.
2138  * So we must do a slow check to see if this conversion would be found
2139  * by ConversionGetConid.
2140  */
2141  char *conname = NameStr(conform->conname);
2142 
2143  visible = (ConversionGetConid(conname) == conid);
2144  }
2145 
2146  ReleaseSysCache(contup);
2147 
2148  return visible;
2149 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
Oid ConversionGetConid(const char *conname)
Definition: namespace.c:2078
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:56
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3336 of file namespace.c.

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

Referenced by CopyCachedPlan().

3337 {
3338  OverrideSearchPath *result;
3339 
3340  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3341  result->schemas = list_copy(path->schemas);
3342  result->addCatalog = path->addCatalog;
3343  result->addTemp = path->addTemp;
3344 
3345  return result;
3346 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
void * palloc(Size size)
Definition: mcxt.c:924

◆ DeconstructQualifiedName()

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

Definition at line 2788 of file namespace.c.

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

Referenced by 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(), LookupTypeName(), make_oper_cache_key(), OpClassCacheLookup(), OpernameGetCandidates(), OpernameGetOprid(), OpFamilyCacheLookup(), QualifiedNameGetCreationNamespace(), and ResolveOpClass().

2791 {
2792  char *catalogname;
2793  char *schemaname = NULL;
2794  char *objname = NULL;
2795 
2796  switch (list_length(names))
2797  {
2798  case 1:
2799  objname = strVal(linitial(names));
2800  break;
2801  case 2:
2802  schemaname = strVal(linitial(names));
2803  objname = strVal(lsecond(names));
2804  break;
2805  case 3:
2806  catalogname = strVal(linitial(names));
2807  schemaname = strVal(lsecond(names));
2808  objname = strVal(lthird(names));
2809 
2810  /*
2811  * We check the catalog name and then ignore it.
2812  */
2813  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2814  ereport(ERROR,
2815  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2816  errmsg("cross-database references are not implemented: %s",
2817  NameListToString(names))));
2818  break;
2819  default:
2820  ereport(ERROR,
2821  (errcode(ERRCODE_SYNTAX_ERROR),
2822  errmsg("improper qualified name (too many dotted names): %s",
2823  NameListToString(names))));
2824  break;
2825  }
2826 
2827  *nspname_p = schemaname;
2828  *objname_p = objname;
2829 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
#define lsecond(l)
Definition: pg_list.h:116
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
Oid MyDatabaseId
Definition: globals.c:84
static int list_length(const List *l)
Definition: pg_list.h:89
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lthird(l)
Definition: pg_list.h:121

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4187 of file namespace.c.

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

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

4188 {
4189  List *result;
4190 
4192 
4193  /*
4194  * If the temp namespace should be first, force it to exist. This is so
4195  * that callers can trust the result to reflect the actual default
4196  * creation namespace. It's a bit bogus to do this here, since
4197  * current_schema() is supposedly a stable function without side-effects,
4198  * but the alternatives seem worse.
4199  */
4201  {
4204  }
4205 
4206  result = list_copy(activeSearchPath);
4207  if (!includeImplicit)
4208  {
4209  while (result && linitial_oid(result) != activeCreationNamespace)
4210  result = list_delete_first(result);
4211  }
4212 
4213  return result;
4214 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool activeTempCreationPending
Definition: namespace.c:139
static void InitTempTableNamespace(void)
Definition: namespace.c:3798
#define linitial_oid(l)
Definition: pg_list.h:113
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:45
List * list_delete_first(List *list)
Definition: list.c:666

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4227 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4228 {
4229  int count = 0;
4230  ListCell *l;
4231 
4233 
4234  foreach(l, activeSearchPath)
4235  {
4236  Oid namespaceId = lfirst_oid(l);
4237 
4238  if (namespaceId == myTempNamespace)
4239  continue; /* do not include temp namespace */
4240 
4241  if (count < sarray_len)
4242  sarray[count] = namespaceId;
4243  count++;
4244  }
4245 
4246  return count;
4247 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3621 of file namespace.c.

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

Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().

3622 {
3623  Oid proc;
3624  ListCell *l;
3625 
3627 
3628  foreach(l, activeSearchPath)
3629  {
3630  Oid namespaceId = lfirst_oid(l);
3631 
3632  if (namespaceId == myTempNamespace)
3633  continue; /* do not look in temp namespace */
3634 
3635  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3636  if (OidIsValid(proc))
3637  return proc;
3638  }
3639 
3640  /* Not found in path */
3641  return InvalidOid;
3642 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ FuncnameGetCandidates()

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

Definition at line 922 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1393 of file namespace.c.

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

Referenced by format_procedure_internal(), and pg_function_is_visible().

1394 {
1395  HeapTuple proctup;
1396  Form_pg_proc procform;
1397  Oid pronamespace;
1398  bool visible;
1399 
1400  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1401  if (!HeapTupleIsValid(proctup))
1402  elog(ERROR, "cache lookup failed for function %u", funcid);
1403  procform = (Form_pg_proc) GETSTRUCT(proctup);
1404 
1406 
1407  /*
1408  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1409  * the system namespace are surely in the path and so we needn't even do
1410  * list_member_oid() for them.
1411  */
1412  pronamespace = procform->pronamespace;
1413  if (pronamespace != PG_CATALOG_NAMESPACE &&
1414  !list_member_oid(activeSearchPath, pronamespace))
1415  visible = false;
1416  else
1417  {
1418  /*
1419  * If it is in the path, it might still not be visible; it could be
1420  * hidden by another proc of the same name and arguments earlier in
1421  * the path. So we must do a slow check to see if this is the same
1422  * proc that would be found by FuncnameGetCandidates.
1423  */
1424  char *proname = NameStr(procform->proname);
1425  int nargs = procform->pronargs;
1426  FuncCandidateList clist;
1427 
1428  visible = false;
1429 
1430  clist = FuncnameGetCandidates(list_make1(makeString(proname)),
1431  nargs, NIL, false, false, false);
1432 
1433  for (; clist; clist = clist->next)
1434  {
1435  if (memcmp(clist->args, procform->proargtypes.values,
1436  nargs * sizeof(Oid)) == 0)
1437  {
1438  /* Found the expected entry; is it the right proc? */
1439  visible = (clist->oid == funcid);
1440  break;
1441  }
1442  }
1443  }
1444 
1445  ReleaseSysCache(proctup);
1446 
1447  return visible;
1448 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:69
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define list_make1(x1)
Definition: pg_list.h:139
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:37
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool missing_ok)
Definition: namespace.c:922
struct _FuncCandidateList * next
Definition: namespace.h:30
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:132
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3512 of file namespace.c.

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

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

3513 {
3514  char *schemaname;
3515  char *collation_name;
3516  int32 dbencoding = GetDatabaseEncoding();
3517  Oid namespaceId;
3518  Oid colloid;
3519  ListCell *l;
3520 
3521  /* deconstruct the name list */
3522  DeconstructQualifiedName(name, &schemaname, &collation_name);
3523 
3524  if (schemaname)
3525  {
3526  /* use exact schema given */
3527  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3528  if (missing_ok && !OidIsValid(namespaceId))
3529  return InvalidOid;
3530 
3531  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3532  if (OidIsValid(colloid))
3533  return colloid;
3534  }
3535  else
3536  {
3537  /* search for it in search path */
3539 
3540  foreach(l, activeSearchPath)
3541  {
3542  namespaceId = lfirst_oid(l);
3543 
3544  if (namespaceId == myTempNamespace)
3545  continue; /* do not look in temp namespace */
3546 
3547  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3548  if (OidIsValid(colloid))
3549  return colloid;
3550  }
3551  }
3552 
3553  /* Not found in path */
3554  if (!missing_ok)
3555  ereport(ERROR,
3556  (errcode(ERRCODE_UNDEFINED_OBJECT),
3557  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3559  return InvalidOid;
3560 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
signed int int32
Definition: c.h:313
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1942
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
int GetDatabaseEncoding(void)
Definition: mbutils.c:1004
#define InvalidOid
Definition: postgres_ext.h:36
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1010
const char * name
Definition: encode.c:521
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 3566 of file namespace.c.

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

Referenced by get_object_address().

3567 {
3568  char *schemaname;
3569  char *conversion_name;
3570  Oid namespaceId;
3571  Oid conoid = InvalidOid;
3572  ListCell *l;
3573 
3574  /* deconstruct the name list */
3575  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3576 
3577  if (schemaname)
3578  {
3579  /* use exact schema given */
3580  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3581  if (missing_ok && !OidIsValid(namespaceId))
3582  conoid = InvalidOid;
3583  else
3584  conoid = GetSysCacheOid2(CONNAMENSP,
3585  PointerGetDatum(conversion_name),
3586  ObjectIdGetDatum(namespaceId));
3587  }
3588  else
3589  {
3590  /* search for it in search path */
3592 
3593  foreach(l, activeSearchPath)
3594  {
3595  namespaceId = lfirst_oid(l);
3596 
3597  if (namespaceId == myTempNamespace)
3598  continue; /* do not look in temp namespace */
3599 
3600  conoid = GetSysCacheOid2(CONNAMENSP,
3601  PointerGetDatum(conversion_name),
3602  ObjectIdGetDatum(namespaceId));
3603  if (OidIsValid(conoid))
3604  return conoid;
3605  }
3606  }
3607 
3608  /* Not found in path */
3609  if (!OidIsValid(conoid) && !missing_ok)
3610  ereport(ERROR,
3611  (errcode(ERRCODE_UNDEFINED_OBJECT),
3612  errmsg("conversion \"%s\" does not exist",
3613  NameListToString(name))));
3614  return conoid;
3615 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
#define InvalidOid
Definition: postgres_ext.h:36
const char * name
Definition: encode.c:521
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

Definition at line 3024 of file namespace.c.

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

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

3025 {
3026  Oid oid;
3027 
3029  if (!OidIsValid(oid) && !missing_ok)
3030  ereport(ERROR,
3031  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3032  errmsg("schema \"%s\" does not exist", nspname)));
3033 
3034  return oid;
3035 }
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid1(cacheId, key1)
Definition: syscache.h:191
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:563
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2157 of file namespace.c.

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

Referenced by get_object_address().

2158 {
2159  char *schemaname;
2160  char *stats_name;
2161  Oid namespaceId;
2162  Oid stats_oid = InvalidOid;
2163  ListCell *l;
2164 
2165  /* deconstruct the name list */
2166  DeconstructQualifiedName(names, &schemaname, &stats_name);
2167 
2168  if (schemaname)
2169  {
2170  /* use exact schema given */
2171  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2172  if (missing_ok && !OidIsValid(namespaceId))
2173  stats_oid = InvalidOid;
2174  else
2175  stats_oid = GetSysCacheOid2(STATEXTNAMENSP,
2176  PointerGetDatum(stats_name),
2177  ObjectIdGetDatum(namespaceId));
2178  }
2179  else
2180  {
2181  /* search for it in search path */
2183 
2184  foreach(l, activeSearchPath)
2185  {
2186  namespaceId = lfirst_oid(l);
2187 
2188  if (namespaceId == myTempNamespace)
2189  continue; /* do not look in temp namespace */
2190  stats_oid = GetSysCacheOid2(STATEXTNAMENSP,
2191  PointerGetDatum(stats_name),
2192  ObjectIdGetDatum(namespaceId));
2193  if (OidIsValid(stats_oid))
2194  break;
2195  }
2196  }
2197 
2198  if (!OidIsValid(stats_oid) && !missing_ok)
2199  ereport(ERROR,
2200  (errcode(ERRCODE_UNDEFINED_OBJECT),
2201  errmsg("statistics object \"%s\" does not exist",
2202  NameListToString(names))));
2203 
2204  return stats_oid;
2205 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2658 of file namespace.c.

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

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

2659 {
2660  char *schemaname;
2661  char *config_name;
2662  Oid namespaceId;
2663  Oid cfgoid = InvalidOid;
2664  ListCell *l;
2665 
2666  /* deconstruct the name list */
2667  DeconstructQualifiedName(names, &schemaname, &config_name);
2668 
2669  if (schemaname)
2670  {
2671  /* use exact schema given */
2672  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2673  if (missing_ok && !OidIsValid(namespaceId))
2674  cfgoid = InvalidOid;
2675  else
2677  PointerGetDatum(config_name),
2678  ObjectIdGetDatum(namespaceId));
2679  }
2680  else
2681  {
2682  /* search for it in search path */
2684 
2685  foreach(l, activeSearchPath)
2686  {
2687  namespaceId = lfirst_oid(l);
2688 
2689  if (namespaceId == myTempNamespace)
2690  continue; /* do not look in temp namespace */
2691 
2693  PointerGetDatum(config_name),
2694  ObjectIdGetDatum(namespaceId));
2695  if (OidIsValid(cfgoid))
2696  break;
2697  }
2698  }
2699 
2700  if (!OidIsValid(cfgoid) && !missing_ok)
2701  ereport(ERROR,
2702  (errcode(ERRCODE_UNDEFINED_OBJECT),
2703  errmsg("text search configuration \"%s\" does not exist",
2704  NameListToString(names))));
2705 
2706  return cfgoid;
2707 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2405 of file namespace.c.

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

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

2406 {
2407  char *schemaname;
2408  char *dict_name;
2409  Oid namespaceId;
2410  Oid dictoid = InvalidOid;
2411  ListCell *l;
2412 
2413  /* deconstruct the name list */
2414  DeconstructQualifiedName(names, &schemaname, &dict_name);
2415 
2416  if (schemaname)
2417  {
2418  /* use exact schema given */
2419  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2420  if (missing_ok && !OidIsValid(namespaceId))
2421  dictoid = InvalidOid;
2422  else
2423  dictoid = GetSysCacheOid2(TSDICTNAMENSP,
2424  PointerGetDatum(dict_name),
2425  ObjectIdGetDatum(namespaceId));
2426  }
2427  else
2428  {
2429  /* search for it in search path */
2431 
2432  foreach(l, activeSearchPath)
2433  {
2434  namespaceId = lfirst_oid(l);
2435 
2436  if (namespaceId == myTempNamespace)
2437  continue; /* do not look in temp namespace */
2438 
2439  dictoid = GetSysCacheOid2(TSDICTNAMENSP,
2440  PointerGetDatum(dict_name),
2441  ObjectIdGetDatum(namespaceId));
2442  if (OidIsValid(dictoid))
2443  break;
2444  }
2445  }
2446 
2447  if (!OidIsValid(dictoid) && !missing_ok)
2448  ereport(ERROR,
2449  (errcode(ERRCODE_UNDEFINED_OBJECT),
2450  errmsg("text search dictionary \"%s\" does not exist",
2451  NameListToString(names))));
2452 
2453  return dictoid;
2454 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2279 of file namespace.c.

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

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

2280 {
2281  char *schemaname;
2282  char *parser_name;
2283  Oid namespaceId;
2284  Oid prsoid = InvalidOid;
2285  ListCell *l;
2286 
2287  /* deconstruct the name list */
2288  DeconstructQualifiedName(names, &schemaname, &parser_name);
2289 
2290  if (schemaname)
2291  {
2292  /* use exact schema given */
2293  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2294  if (missing_ok && !OidIsValid(namespaceId))
2295  prsoid = InvalidOid;
2296  else
2298  PointerGetDatum(parser_name),
2299  ObjectIdGetDatum(namespaceId));
2300  }
2301  else
2302  {
2303  /* search for it in search path */
2305 
2306  foreach(l, activeSearchPath)
2307  {
2308  namespaceId = lfirst_oid(l);
2309 
2310  if (namespaceId == myTempNamespace)
2311  continue; /* do not look in temp namespace */
2312 
2314  PointerGetDatum(parser_name),
2315  ObjectIdGetDatum(namespaceId));
2316  if (OidIsValid(prsoid))
2317  break;
2318  }
2319  }
2320 
2321  if (!OidIsValid(prsoid) && !missing_ok)
2322  ereport(ERROR,
2323  (errcode(ERRCODE_UNDEFINED_OBJECT),
2324  errmsg("text search parser \"%s\" does not exist",
2325  NameListToString(names))));
2326 
2327  return prsoid;
2328 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2532 of file namespace.c.

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

Referenced by DefineTSDictionary(), and get_object_address().

2533 {
2534  char *schemaname;
2535  char *template_name;
2536  Oid namespaceId;
2537  Oid tmploid = InvalidOid;
2538  ListCell *l;
2539 
2540  /* deconstruct the name list */
2541  DeconstructQualifiedName(names, &schemaname, &template_name);
2542 
2543  if (schemaname)
2544  {
2545  /* use exact schema given */
2546  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2547  if (missing_ok && !OidIsValid(namespaceId))
2548  tmploid = InvalidOid;
2549  else
2551  PointerGetDatum(template_name),
2552  ObjectIdGetDatum(namespaceId));
2553  }
2554  else
2555  {
2556  /* search for it in search path */
2558 
2559  foreach(l, activeSearchPath)
2560  {
2561  namespaceId = lfirst_oid(l);
2562 
2563  if (namespaceId == myTempNamespace)
2564  continue; /* do not look in temp namespace */
2565 
2567  PointerGetDatum(template_name),
2568  ObjectIdGetDatum(namespaceId));
2569  if (OidIsValid(tmploid))
2570  break;
2571  }
2572  }
2573 
2574  if (!OidIsValid(tmploid) && !missing_ok)
2575  ereport(ERROR,
2576  (errcode(ERRCODE_UNDEFINED_OBJECT),
2577  errmsg("text search template \"%s\" does not exist",
2578  NameListToString(names))));
2579 
2580  return tmploid;
2581 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3300 of file namespace.c.

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

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

3301 {
3302  OverrideSearchPath *result;
3303  List *schemas;
3304  MemoryContext oldcxt;
3305 
3307 
3308  oldcxt = MemoryContextSwitchTo(context);
3309 
3310  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3311  schemas = list_copy(activeSearchPath);
3312  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3313  {
3314  if (linitial_oid(schemas) == myTempNamespace)
3315  result->addTemp = true;
3316  else
3317  {
3318  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3319  result->addCatalog = true;
3320  }
3321  schemas = list_delete_first(schemas);
3322  }
3323  result->schemas = schemas;
3324 
3325  MemoryContextSwitchTo(oldcxt);
3326 
3327  return result;
3328 }
static Oid myTempNamespace
Definition: namespace.c:180
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * list_copy(const List *oldlist)
Definition: list.c:1160
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static Oid activeCreationNamespace
Definition: namespace.c:136
void * palloc0(Size size)
Definition: mcxt.c:955
#define Assert(condition)
Definition: c.h:699
#define linitial_oid(l)
Definition: pg_list.h:113
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:45
List * list_delete_first(List *list)
Definition: list.c:666

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3214 of file namespace.c.

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

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

3215 {
3216  int result;
3217  char *nspname;
3218 
3219  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3220  nspname = get_namespace_name(namespaceId);
3221  if (!nspname)
3222  return InvalidBackendId; /* no such namespace? */
3223  if (strncmp(nspname, "pg_temp_", 8) == 0)
3224  result = atoi(nspname + 8);
3225  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3226  result = atoi(nspname + 14);
3227  else
3228  result = InvalidBackendId;
3229  pfree(nspname);
3230  return result;
3231 }
void pfree(void *pointer)
Definition: mcxt.c:1031
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3051
#define InvalidBackendId
Definition: backendid.h:23

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3253 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3254 {
3255  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3256  *tempNamespaceId = myTempNamespace;
3257  *tempToastNamespaceId = myTempToastNamespace;
3258 }
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3239 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3240 {
3242  return myTempToastNamespace;
3243 }
static Oid myTempToastNamespace
Definition: namespace.c:182
#define OidIsValid(objectId)
Definition: c.h:605
#define Assert(condition)
Definition: c.h:699

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4129 of file namespace.c.

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

Referenced by InitPostgres().

4130 {
4132  {
4133  /*
4134  * In bootstrap mode, the search path must be 'pg_catalog' so that
4135  * tables are created in the proper namespace; ignore the GUC setting.
4136  */
4137  MemoryContext oldcxt;
4138 
4140  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4141  MemoryContextSwitchTo(oldcxt);
4142  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4143  baseTempCreationPending = false;
4144  baseSearchPathValid = true;
4149  }
4150  else
4151  {
4152  /*
4153  * In normal mode, arrange for a callback on any syscache invalidation
4154  * of pg_namespace rows.
4155  */
4158  (Datum) 0);
4159  /* Force search path to be recomputed on next use */
4160  baseSearchPathValid = false;
4161  }
4162 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid GetUserId(void)
Definition: miscinit.c:379
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static Oid namespaceUser
Definition: namespace.c:149
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool baseTempCreationPending
Definition: namespace.c:147
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4169
static bool activeTempCreationPending
Definition: namespace.c:139
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static Oid baseCreationNamespace
Definition: namespace.c:145
static List * baseSearchPath
Definition: namespace.c:143
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1389
uintptr_t Datum
Definition: postgres.h:367
#define list_make1_oid(x1)
Definition: pg_list.h:151
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:372
static List * activeSearchPath
Definition: namespace.c:133

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3175 of file namespace.c.

References get_namespace_name(), and pfree().

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

3176 {
3177  bool result;
3178  char *nspname;
3179 
3180  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3181  nspname = get_namespace_name(namespaceId);
3182  if (!nspname)
3183  return false; /* no such namespace? */
3184  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3185  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3186  pfree(nspname);
3187  return result;
3188 }
void pfree(void *pointer)
Definition: mcxt.c:1031
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3051

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3198 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

3199 {
3200  /* If it's my own temp namespace, say "false" */
3201  if (isTempOrTempToastNamespace(namespaceId))
3202  return false;
3203  /* Else, if it's any temp namespace, say "true" */
3204  return isAnyTempNamespace(namespaceId);
3205 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3161
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3175

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3137 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

3138 {
3139  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3140  return true;
3141  return false;
3142 }
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:605

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3161 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

3162 {
3163  if (OidIsValid(myTempNamespace) &&
3164  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3165  return true;
3166  return false;
3167 }
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:605

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3149 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

3150 {
3151  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3152  return true;
3153  return false;
3154 }
static Oid myTempToastNamespace
Definition: namespace.c:182
#define OidIsValid(objectId)
Definition: c.h:605

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2915 of file namespace.c.

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

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

2916 {
2917  Oid namespaceId;
2918  AclResult aclresult;
2919 
2920  /* check for pg_temp alias */
2921  if (strcmp(nspname, "pg_temp") == 0)
2922  {
2923  /* Initialize temp namespace if first time through */
2926  return myTempNamespace;
2927  }
2928 
2929  namespaceId = get_namespace_oid(nspname, false);
2930 
2931  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2932  if (aclresult != ACLCHECK_OK)
2933  aclcheck_error(aclresult, OBJECT_SCHEMA,
2934  nspname);
2935 
2936  return namespaceId;
2937 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3024
Oid GetUserId(void)
Definition: miscinit.c:379
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4689
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3349
#define ACL_CREATE
Definition: parsenodes.h:84
static void InitTempTableNamespace(void)
Definition: namespace.c:3798
AclResult
Definition: acl.h:178

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2872 of file namespace.c.

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

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

2873 {
2874  Oid namespaceId;
2875  AclResult aclresult;
2876 
2877  /* check for pg_temp alias */
2878  if (strcmp(nspname, "pg_temp") == 0)
2879  {
2881  return myTempNamespace;
2882 
2883  /*
2884  * Since this is used only for looking up existing objects, there is
2885  * no point in trying to initialize the temp namespace here; and doing
2886  * so might create problems for some callers --- just fall through.
2887  */
2888  }
2889 
2890  namespaceId = get_namespace_oid(nspname, missing_ok);
2891  if (missing_ok && !OidIsValid(namespaceId))
2892  return InvalidOid;
2893 
2894  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
2895  if (aclresult != ACLCHECK_OK)
2896  aclcheck_error(aclresult, OBJECT_SCHEMA,
2897  nspname);
2898  /* Schema search hook for this lookup */
2899  InvokeNamespaceSearchHook(namespaceId, true);
2900 
2901  return namespaceId;
2902 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3024
Oid GetUserId(void)
Definition: miscinit.c:379
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4689
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:174
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3349
#define ACL_USAGE
Definition: parsenodes.h:82
AclResult
Definition: acl.h:178
#define InvalidOid
Definition: postgres_ext.h:36

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2842 of file namespace.c.

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

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

2843 {
2844  /* check for pg_temp alias */
2845  if (strcmp(nspname, "pg_temp") == 0)
2846  {
2848  {
2850  return myTempNamespace;
2851  }
2852 
2853  /*
2854  * Since this is used only for looking up existing objects, there is
2855  * no point in trying to initialize the temp namespace here; and doing
2856  * so might create problems for some callers. Just report "not found".
2857  */
2858  return InvalidOid;
2859  }
2860 
2861  return get_namespace_oid(nspname, true);
2862 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3024
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:605
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:174
#define InvalidOid
Definition: postgres_ext.h:36

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 3042 of file namespace.c.

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

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

3043 {
3044  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3045 
3046  switch (list_length(names))
3047  {
3048  case 1:
3049  rel->relname = strVal(linitial(names));
3050  break;
3051  case 2:
3052  rel->schemaname = strVal(linitial(names));
3053  rel->relname = strVal(lsecond(names));
3054  break;
3055  case 3:
3056  rel->catalogname = strVal(linitial(names));
3057  rel->schemaname = strVal(lsecond(names));
3058  rel->relname = strVal(lthird(names));
3059  break;
3060  default:
3061  ereport(ERROR,
3062  (errcode(ERRCODE_SYNTAX_ERROR),
3063  errmsg("improper relation name (too many dotted names): %s",
3064  NameListToString(names))));
3065  break;
3066  }
3067 
3068  return rel;
3069 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
#define lsecond(l)
Definition: pg_list.h:116
char * schemaname
Definition: primnodes.h:68
char * relname
Definition: primnodes.h:69
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
static int list_length(const List *l)
Definition: pg_list.h:89
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lthird(l)
Definition: pg_list.h:121
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:421
char * catalogname
Definition: primnodes.h:67

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3116 of file namespace.c.

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

3117 {
3119  ListCell *l;
3120 
3121  initStringInfo(&string);
3122 
3123  foreach(l, names)
3124  {
3125  if (l != list_head(names))
3126  appendStringInfoChar(&string, '.');
3128  }
3129 
3130  return string.data;
3131 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10488
#define strVal(v)
Definition: value.h:54
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define lfirst(lc)
Definition: pg_list.h:106

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3082 of file namespace.c.

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

Referenced by AggregateCreate(), AlterCollation(), AlterFunction(), AlterTSConfiguration(), AlterTSDictionary(), check_object_ownership(), CreateConversionCommand(), CreateEventTrigger(), CreateProceduralLanguage(), CreateTransform(), CreateTrigger(), DeconstructQualifiedName(), defGetString(), DefineOperator(), DefineType(), does_not_exist_skipping(), dropOperators(), dropProcedures(), ExpandColumnRefStar(), findRangeSubOpclass(), findTypeAnalyzeFunction(), findTypeInputFunction(), findTypeOutputFunction(), 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(), lookup_fdw_handler_func(), lookup_index_am_handler_func(), LookupFuncName(), LookupFuncWithArgs(), LookupTypeName(), makeRangeVarFromNameList(), op_signature_string(), OpClassCacheLookup(), OperatorCreate(), OpFamilyCacheLookup(), owningrel_does_not_exist_skipping(), ParseFuncOrColumn(), plpgsql_post_column_ref(), RemoveObjects(), ResolveOpClass(), storeOperators(), storeProcedures(), transformColumnRef(), transformRangeTableSample(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

3083 {
3085  ListCell *l;
3086 
3087  initStringInfo(&string);
3088 
3089  foreach(l, names)
3090  {
3091  Node *name = (Node *) lfirst(l);
3092 
3093  if (l != list_head(names))
3094  appendStringInfoChar(&string, '.');
3095 
3096  if (IsA(name, String))
3097  appendStringInfoString(&string, strVal(name));
3098  else if (IsA(name, A_Star))
3099  appendStringInfoChar(&string, '*');
3100  else
3101  elog(ERROR, "unexpected node type in name list: %d",
3102  (int) nodeTag(name));
3103  }
3104 
3105  return string.data;
3106 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:568
Definition: nodes.h:517
#define strVal(v)
Definition: value.h:54
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define lfirst(lc)
Definition: pg_list.h:106
const char * name
Definition: encode.c:521
#define nodeTag(nodeptr)
Definition: nodes.h:522
#define elog
Definition: elog.h:219

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1812 of file namespace.c.

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

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

1813 {
1814  HeapTuple opctup;
1815  Form_pg_opclass opcform;
1816  Oid opcnamespace;
1817  bool visible;
1818 
1819  opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
1820  if (!HeapTupleIsValid(opctup))
1821  elog(ERROR, "cache lookup failed for opclass %u", opcid);
1822  opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1823 
1825 
1826  /*
1827  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1828  * the system namespace are surely in the path and so we needn't even do
1829  * list_member_oid() for them.
1830  */
1831  opcnamespace = opcform->opcnamespace;
1832  if (opcnamespace != PG_CATALOG_NAMESPACE &&
1833  !list_member_oid(activeSearchPath, opcnamespace))
1834  visible = false;
1835  else
1836  {
1837  /*
1838  * If it is in the path, it might still not be visible; it could be
1839  * hidden by another opclass of the same name earlier in the path. So
1840  * we must do a slow check to see if this opclass would be found by
1841  * OpclassnameGetOpcid.
1842  */
1843  char *opcname = NameStr(opcform->opcname);
1844 
1845  visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1846  }
1847 
1848  ReleaseSysCache(opctup);
1849 
1850  return visible;
1851 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
unsigned int Oid
Definition: postgres_ext.h:31
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
Definition: namespace.c:1779
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:81

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1779 of file namespace.c.

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

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

1780 {
1781  Oid opcid;
1782  ListCell *l;
1783 
1785 
1786  foreach(l, activeSearchPath)
1787  {
1788  Oid namespaceId = lfirst_oid(l);
1789 
1790  if (namespaceId == myTempNamespace)
1791  continue; /* do not look in temp namespace */
1792 
1793  opcid = GetSysCacheOid3(CLAAMNAMENSP,
1794  ObjectIdGetDatum(amid),
1795  PointerGetDatum(opcname),
1796  ObjectIdGetDatum(namespaceId));
1797  if (OidIsValid(opcid))
1798  return opcid;
1799  }
1800 
1801  /* Not found in path */
1802  return InvalidOid;
1803 }
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:195
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1726 of file namespace.c.

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

Referenced by format_operator_internal(), and pg_operator_is_visible().

1727 {
1728  HeapTuple oprtup;
1729  Form_pg_operator oprform;
1730  Oid oprnamespace;
1731  bool visible;
1732 
1734  if (!HeapTupleIsValid(oprtup))
1735  elog(ERROR, "cache lookup failed for operator %u", oprid);
1736  oprform = (Form_pg_operator) GETSTRUCT(oprtup);
1737 
1739 
1740  /*
1741  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1742  * the system namespace are surely in the path and so we needn't even do
1743  * list_member_oid() for them.
1744  */
1745  oprnamespace = oprform->oprnamespace;
1746  if (oprnamespace != PG_CATALOG_NAMESPACE &&
1747  !list_member_oid(activeSearchPath, oprnamespace))
1748  visible = false;
1749  else
1750  {
1751  /*
1752  * If it is in the path, it might still not be visible; it could be
1753  * hidden by another operator of the same name and arguments earlier
1754  * in the path. So we must do a slow check to see if this is the same
1755  * operator that would be found by OpernameGetOprid.
1756  */
1757  char *oprname = NameStr(oprform->oprname);
1758 
1759  visible = (OpernameGetOprid(list_make1(makeString(oprname)),
1760  oprform->oprleft, oprform->oprright)
1761  == oprid);
1762  }
1763 
1764  ReleaseSysCache(oprtup);
1765 
1766  return visible;
1767 }
Value * makeString(char *str)
Definition: value.c:53
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
Oid oprid(Operator op)
Definition: parse_oper.c:245
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define list_make1(x1)
Definition: pg_list.h:139
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1464
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:82
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219

◆ OpernameGetCandidates()

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

Definition at line 1566 of file namespace.c.

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

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

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

◆ OpernameGetOprid()

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

Definition at line 1464 of file namespace.c.

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

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

1465 {
1466  char *schemaname;
1467  char *opername;
1468  CatCList *catlist;
1469  ListCell *l;
1470 
1471  /* deconstruct the name list */
1472  DeconstructQualifiedName(names, &schemaname, &opername);
1473 
1474  if (schemaname)
1475  {
1476  /* search only in exact schema given */
1477  Oid namespaceId;
1478 
1479  namespaceId = LookupExplicitNamespace(schemaname, true);
1480  if (OidIsValid(namespaceId))
1481  {
1482  HeapTuple opertup;
1483 
1484  opertup = SearchSysCache4(OPERNAMENSP,
1485  CStringGetDatum(opername),
1486  ObjectIdGetDatum(oprleft),
1487  ObjectIdGetDatum(oprright),
1488  ObjectIdGetDatum(namespaceId));
1489  if (HeapTupleIsValid(opertup))
1490  {
1491  Oid result = HeapTupleGetOid(opertup);
1492 
1493  ReleaseSysCache(opertup);
1494  return result;
1495  }
1496  }
1497 
1498  return InvalidOid;
1499  }
1500 
1501  /* Search syscache by name and argument types */
1502  catlist = SearchSysCacheList3(OPERNAMENSP,
1503  CStringGetDatum(opername),
1504  ObjectIdGetDatum(oprleft),
1505  ObjectIdGetDatum(oprright));
1506 
1507  if (catlist->n_members == 0)
1508  {
1509  /* no hope, fall out early */
1510  ReleaseSysCacheList(catlist);
1511  return InvalidOid;
1512  }
1513 
1514  /*
1515  * We have to find the list member that is first in the search path, if
1516  * there's more than one. This doubly-nested loop looks ugly, but in
1517  * practice there should usually be few catlist members.
1518  */
1520 
1521  foreach(l, activeSearchPath)
1522  {
1523  Oid namespaceId = lfirst_oid(l);
1524  int i;
1525 
1526  if (namespaceId == myTempNamespace)
1527  continue; /* do not look in temp namespace */
1528 
1529  for (i = 0; i < catlist->n_members; i++)
1530  {
1531  HeapTuple opertup = &catlist->members[i]->tuple;
1532  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1533 
1534  if (operform->oprnamespace == namespaceId)
1535  {
1536  Oid result = HeapTupleGetOid(opertup);
1537 
1538  ReleaseSysCacheList(catlist);
1539  return result;
1540  }
1541  }
1542  }
1543 
1544  ReleaseSysCacheList(catlist);
1545  return InvalidOid;
1546 }
int n_members
Definition: catcache.h:176
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
static Oid myTempNamespace
Definition: namespace.c:180
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define CStringGetDatum(X)
Definition: postgres.h:563
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1145
#define ReleaseSysCacheList(x)
Definition: syscache.h:216
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:82
static List * activeSearchPath
Definition: namespace.c:133
#define SearchSysCacheList3(cacheId, key1, key2, key3)
Definition: syscache.h:213
int i
HeapTupleData tuple
Definition: catcache.h:121
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:707
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1895 of file namespace.c.

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

1896 {
1897  HeapTuple opftup;
1898  Form_pg_opfamily opfform;
1899  Oid opfnamespace;
1900  bool visible;
1901 
1902  opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
1903  if (!HeapTupleIsValid(opftup))
1904  elog(ERROR, "cache lookup failed for opfamily %u", opfid);
1905  opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
1906 
1908 
1909  /*
1910  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1911  * the system namespace are surely in the path and so we needn't even do
1912  * list_member_oid() for them.
1913  */
1914  opfnamespace = opfform->opfnamespace;
1915  if (opfnamespace != PG_CATALOG_NAMESPACE &&
1916  !list_member_oid(activeSearchPath, opfnamespace))
1917  visible = false;
1918  else
1919  {
1920  /*
1921  * If it is in the path, it might still not be visible; it could be
1922  * hidden by another opfamily of the same name earlier in the path. So
1923  * we must do a slow check to see if this opfamily would be found by
1924  * OpfamilynameGetOpfid.
1925  */
1926  char *opfname = NameStr(opfform->opfname);
1927 
1928  visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
1929  }
1930 
1931  ReleaseSysCache(opftup);
1932 
1933  return visible;
1934 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
Definition: namespace.c:1862
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:49
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1862 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

1863 {
1864  Oid opfid;
1865  ListCell *l;
1866 
1868 
1869  foreach(l, activeSearchPath)
1870  {
1871  Oid namespaceId = lfirst_oid(l);
1872 
1873  if (namespaceId == myTempNamespace)
1874  continue; /* do not look in temp namespace */
1875 
1877  ObjectIdGetDatum(amid),
1878  PointerGetDatum(opfname),
1879  ObjectIdGetDatum(namespaceId));
1880  if (OidIsValid(opfid))
1881  return opfid;
1882  }
1883 
1884  /* Not found in path */
1885  return InvalidOid;
1886 }
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:195
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3352 of file namespace.c.

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

Referenced by RevalidateCachedQuery().

3353 {
3354  ListCell *lc,
3355  *lcp;
3356 
3358 
3359  /* We scan down the activeSearchPath to see if it matches the input. */
3361 
3362  /* If path->addTemp, first item should be my temp namespace. */
3363  if (path->addTemp)
3364  {
3365  if (lc && lfirst_oid(lc) == myTempNamespace)
3366  lc = lnext(lc);
3367  else
3368  return false;
3369  }
3370  /* If path->addCatalog, next item should be pg_catalog. */
3371  if (path->addCatalog)
3372  {
3373  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3374  lc = lnext(lc);
3375  else
3376  return false;
3377  }
3378  /* We should now be looking at the activeCreationNamespace. */
3379  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3380  return false;
3381  /* The remainder of activeSearchPath should match path->schemas. */
3382  foreach(lcp, path->schemas)
3383  {
3384  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3385  lc = lnext(lc);
3386  else
3387  return false;
3388  }
3389  if (lc)
3390  return false;
3391  return true;
3392 }
static Oid myTempNamespace
Definition: namespace.c:180
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static Oid activeCreationNamespace
Definition: namespace.c:136
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
#define lnext(lc)
Definition: pg_list.h:105
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3471 of file namespace.c.

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

Referenced by CreateSchemaCommand().

3472 {
3473  OverrideStackEntry *entry;
3474 
3475  /* Sanity checks. */
3476  if (overrideStack == NIL)
3477  elog(ERROR, "bogus PopOverrideSearchPath call");
3479  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3480  elog(ERROR, "bogus PopOverrideSearchPath call");
3481 
3482  /* Pop the stack and free storage. */
3484  list_free(entry->searchPath);
3485  pfree(entry);
3486 
3487  /* Activate the next level down. */
3488  if (overrideStack)
3489  {
3491  activeSearchPath = entry->searchPath;
3493  activeTempCreationPending = false; /* XXX is this OK? */
3494  }
3495  else
3496  {
3497  /* If not baseSearchPathValid, this is useless but harmless */
3501  }
3502 }
#define NIL
Definition: pg_list.h:69
static List * overrideStack
Definition: namespace.c:163
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:1031
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
static bool baseTempCreationPending
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
static List * baseSearchPath
Definition: namespace.c:143
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:753
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1133
#define elog
Definition: elog.h:219
List * list_delete_first(List *list)
Definition: list.c:666

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3412 of file namespace.c.

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

Referenced by CreateSchemaCommand().

3413 {
3414  OverrideStackEntry *entry;
3415  List *oidlist;
3416  Oid firstNS;
3417  MemoryContext oldcxt;
3418 
3419  /*
3420  * Copy the list for safekeeping, and insert implicitly-searched
3421  * namespaces as needed. This code should track recomputeNamespacePath.
3422  */
3424 
3425  oidlist = list_copy(newpath->schemas);
3426 
3427  /*
3428  * Remember the first member of the explicit list.
3429  */
3430  if (oidlist == NIL)
3431  firstNS = InvalidOid;
3432  else
3433  firstNS = linitial_oid(oidlist);
3434 
3435  /*
3436  * Add any implicitly-searched namespaces to the list. Note these go on
3437  * the front, not the back; also notice that we do not check USAGE
3438  * permissions for these.
3439  */
3440  if (newpath->addCatalog)
3441  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3442 
3443  if (newpath->addTemp && OidIsValid(myTempNamespace))
3444  oidlist = lcons_oid(myTempNamespace, oidlist);
3445 
3446  /*
3447  * Build the new stack entry, then insert it at the head of the list.
3448  */
3449  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3450  entry->searchPath = oidlist;
3451  entry->creationNamespace = firstNS;
3453 
3454  overrideStack = lcons(entry, overrideStack);
3455 
3456  /* And make it active. */
3457  activeSearchPath = entry->searchPath;
3459  activeTempCreationPending = false; /* XXX is this OK? */
3460 
3461  MemoryContextSwitchTo(oldcxt);
3462 }
#define NIL
Definition: pg_list.h:69
static Oid myTempNamespace
Definition: namespace.c:180
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static List * overrideStack
Definition: namespace.c:163
List * list_copy(const List *oldlist)
Definition: list.c:1160
List * lcons_oid(Oid datum, List *list)
Definition: list.c:295
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool activeTempCreationPending
Definition: namespace.c:139
MemoryContext TopMemoryContext
Definition: mcxt.c:44
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:753
List * lcons(void *datum, List *list)
Definition: list.c:259
#define linitial_oid(l)
Definition: pg_list.h:113
static List * activeSearchPath
Definition: namespace.c:133
void * palloc(Size size)
Definition: mcxt.c:924
Definition: pg_list.h:45

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 2975 of file namespace.c.

References activeCreationNamespace, activeTempCreationPending, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, get_namespace_oid(), InitTempTableNamespace(), 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().

2976 {
2977  char *schemaname;
2978  Oid namespaceId;
2979 
2980  /* deconstruct the name list */
2981  DeconstructQualifiedName(names, &schemaname, objname_p);
2982 
2983  if (schemaname)
2984  {
2985  /* check for pg_temp alias */
2986  if (strcmp(schemaname, "pg_temp") == 0)
2987  {
2988  /* Initialize temp namespace if first time through */
2991  return myTempNamespace;
2992  }
2993  /* use exact schema given */
2994  namespaceId = get_namespace_oid(schemaname, false);
2995  /* we do not check for USAGE rights here! */
2996  }
2997  else
2998  {
2999  /* use the default creation namespace */
3002  {
3003  /* Need to initialize temp namespace */
3005  return myTempNamespace;
3006  }
3007  namespaceId = activeCreationNamespace;
3008  if (!OidIsValid(namespaceId))
3009  ereport(ERROR,
3010  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3011  errmsg("no schema has been selected to create in")));
3012  }
3013 
3014  return namespaceId;
3015 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3024
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static Oid activeCreationNamespace
Definition: namespace.c:136
#define ERROR
Definition: elog.h:43
static bool activeTempCreationPending
Definition: namespace.c:139
#define ereport(elevel, rest)
Definition: elog.h:122
static void InitTempTableNamespace(void)
Definition: namespace.c:3798
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 634 of file namespace.c.

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

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

635 {
636  switch (newRelation->relpersistence)
637  {
638  case RELPERSISTENCE_TEMP:
639  if (!isTempOrTempToastNamespace(nspid))
640  {
641  if (isAnyTempNamespace(nspid))
642  ereport(ERROR,
643  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
644  errmsg("cannot create relations in temporary schemas of other sessions")));
645  else
646  ereport(ERROR,
647  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
648  errmsg("cannot create temporary relation in non-temporary schema")));
649  }
650  break;
651  case RELPERSISTENCE_PERMANENT:
652  if (isTempOrTempToastNamespace(nspid))
653  newRelation->relpersistence = RELPERSISTENCE_TEMP;
654  else if (isAnyTempNamespace(nspid))
655  ereport(ERROR,
656  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
657  errmsg("cannot create relations in temporary schemas of other sessions")));
658  break;
659  default:
660  if (isAnyTempNamespace(nspid))
661  ereport(ERROR,
662  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
663  errmsg("only temporary relations may be created in temporary schemas")));
664  }
665 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3161
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char relpersistence
Definition: primnodes.h:72
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3175

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 527 of file namespace.c.

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

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 440 of file namespace.c.

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

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

441 {
442  Oid namespaceId;
443 
444  /*
445  * We check the catalog name and then ignore it.
446  */
447  if (newRelation->catalogname)
448  {
449  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
450  ereport(ERROR,
451  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
452  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
453  newRelation->catalogname, newRelation->schemaname,
454  newRelation->relname)));
455  }
456 
457  if (newRelation->schemaname)
458  {
459  /* check for pg_temp alias */
460  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
461  {
462  /* Initialize temp namespace if first time through */
465  return myTempNamespace;
466  }
467  /* use exact schema given */
468  namespaceId = get_namespace_oid(newRelation->schemaname, false);
469  /* we do not check for USAGE rights here! */
470  }
471  else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
472  {
473  /* Initialize temp namespace if first time through */
476  return myTempNamespace;
477  }
478  else
479  {
480  /* use the default creation namespace */
483  {
484  /* Need to initialize temp namespace */
486  return myTempNamespace;
487  }
488  namespaceId = activeCreationNamespace;
489  if (!OidIsValid(namespaceId))
490  ereport(ERROR,
491  (errcode(ERRCODE_UNDEFINED_SCHEMA),
492  errmsg("no schema has been selected to create in")));
493  }
494 
495  /* Note: callers will check for CREATE rights when appropriate */
496 
497  return namespaceId;
498 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3024
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
char * schemaname
Definition: primnodes.h:68
char * relname
Definition: primnodes.h:69
static Oid activeCreationNamespace
Definition: namespace.c:136
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
static bool activeTempCreationPending
Definition: namespace.c:139
#define ereport(elevel, rest)
Definition: elog.h:122
static void InitTempTableNamespace(void)
Definition: namespace.c:3798
Oid MyDatabaseId
Definition: globals.c:84
char relpersistence
Definition: primnodes.h:72
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * catalogname
Definition: primnodes.h:67

◆ RangeVarGetRelidExtended()

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

Definition at line 227 of file namespace.c.

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

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

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

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 701 of file namespace.c.

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

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

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

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 673 of file namespace.c.

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

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

674 {
675  Oid relid;
676  ListCell *l;
677 
679 
680  foreach(l, activeSearchPath)
681  {
682  Oid namespaceId = lfirst_oid(l);
683 
684  relid = get_relname_relid(relname, namespaceId);
685  if (OidIsValid(relid))
686  return relid;
687  }
688 
689  /* Not found in path */
690  return InvalidOid;
691 }
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1687
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4066 of file namespace.c.

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

4067 {
4070 }
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:605
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4022

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3269 of file namespace.c.

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

Referenced by ParallelWorkerMain().

3270 {
3271  /* Worker should not have created its own namespaces ... */
3275 
3276  /* Assign same namespace OIDs that leader has */
3277  myTempNamespace = tempNamespaceId;
3278  myTempToastNamespace = tempToastNamespaceId;
3279 
3280  /*
3281  * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
3282  * Even if the namespace is new so far as the leader is concerned, it's
3283  * not new to the worker, and we certainly wouldn't want the worker trying
3284  * to destroy it.
3285  */
3286 
3287  baseSearchPathValid = false; /* may need to rebuild list */
3288 }
static bool baseSearchPathValid
Definition: namespace.c:152
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:699
#define InvalidSubTransactionId
Definition: c.h:480

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  stxid)

Definition at line 2214 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_statistics_obj_is_visible().

2215 {
2216  HeapTuple stxtup;
2217  Form_pg_statistic_ext stxform;
2218  Oid stxnamespace;
2219  bool visible;
2220 
2221  stxtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(relid));
2222  if (!HeapTupleIsValid(stxtup))
2223  elog(ERROR, "cache lookup failed for statistics object %u", relid);
2224  stxform = (Form_pg_statistic_ext) GETSTRUCT(stxtup);
2225 
2227 
2228  /*
2229  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2230  * the system namespace are surely in the path and so we needn't even do
2231  * list_member_oid() for them.
2232  */
2233  stxnamespace = stxform->stxnamespace;
2234  if (stxnamespace != PG_CATALOG_NAMESPACE &&
2235  !list_member_oid(activeSearchPath, stxnamespace))
2236  visible = false;
2237  else
2238  {
2239  /*
2240  * If it is in the path, it might still not be visible; it could be
2241  * hidden by another statistics object of the same name earlier in the
2242  * path. So we must do a slow check for conflicting objects.
2243  */
2244  char *stxname = NameStr(stxform->stxname);
2245  ListCell *l;
2246 
2247  visible = false;
2248  foreach(l, activeSearchPath)
2249  {
2250  Oid namespaceId = lfirst_oid(l);
2251 
2252  if (namespaceId == stxnamespace)
2253  {
2254  /* Found it first in path */
2255  visible = true;
2256  break;
2257  }
2259  PointerGetDatum(stxname),
2260  ObjectIdGetDatum(namespaceId)))
2261  {
2262  /* Found something else first in path */
2263  break;
2264  }
2265  }
2266  }
2267 
2268  ReleaseSysCache(stxtup);
2269 
2270  return visible;
2271 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
#define PointerGetDatum(X)
Definition: postgres.h:541
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:184
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219
FormData_pg_statistic_ext * Form_pg_statistic_ext
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 2716 of file namespace.c.

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

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

2717 {
2718  HeapTuple tup;
2719  Form_pg_ts_config form;
2720  Oid namespace;
2721  bool visible;
2722 
2724  if (!HeapTupleIsValid(tup))
2725  elog(ERROR, "cache lookup failed for text search configuration %u",
2726  cfgid);
2727  form = (Form_pg_ts_config) GETSTRUCT(tup);
2728 
2730 
2731  /*
2732  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2733  * the system namespace are surely in the path and so we needn't even do
2734  * list_member_oid() for them.
2735  */
2736  namespace = form->cfgnamespace;
2737  if (namespace != PG_CATALOG_NAMESPACE &&
2738  !list_member_oid(activeSearchPath, namespace))
2739  visible = false;
2740  else
2741  {
2742  /*
2743  * If it is in the path, it might still not be visible; it could be
2744  * hidden by another configuration of the same name earlier in the
2745  * path. So we must do a slow check for conflicting configurations.
2746  */
2747  char *name = NameStr(form->cfgname);
2748  ListCell *l;
2749 
2750  visible = false;
2751  foreach(l, activeSearchPath)
2752  {
2753  Oid namespaceId = lfirst_oid(l);
2754 
2755  if (namespaceId == myTempNamespace)
2756  continue; /* do not look in temp namespace */
2757 
2758  if (namespaceId == namespace)
2759  {
2760  /* Found it first in path */
2761  visible = true;
2762  break;
2763  }
2765  PointerGetDatum(name),
2766  ObjectIdGetDatum(namespaceId)))
2767  {
2768  /* Found something else first in path */
2769  break;
2770  }
2771  }
2772  }
2773 
2774  ReleaseSysCache(tup);
2775 
2776  return visible;
2777 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:38
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:184
const char * name
Definition: encode.c:521
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2463 of file namespace.c.

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

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

2464 {
2465  HeapTuple tup;
2466  Form_pg_ts_dict form;
2467  Oid namespace;
2468  bool visible;
2469 
2470  tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
2471  if (!HeapTupleIsValid(tup))
2472  elog(ERROR, "cache lookup failed for text search dictionary %u",
2473  dictId);
2474  form = (Form_pg_ts_dict) GETSTRUCT(tup);
2475 
2477 
2478  /*
2479  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2480  * the system namespace are surely in the path and so we needn't even do
2481  * list_member_oid() for them.
2482  */
2483  namespace = form->dictnamespace;
2484  if (namespace != PG_CATALOG_NAMESPACE &&
2485  !list_member_oid(activeSearchPath, namespace))
2486  visible = false;
2487  else
2488  {
2489  /*
2490  * If it is in the path, it might still not be visible; it could be
2491  * hidden by another dictionary of the same name earlier in the path.
2492  * So we must do a slow check for conflicting dictionaries.
2493  */
2494  char *name = NameStr(form->dictname);
2495  ListCell *l;
2496 
2497  visible = false;
2498  foreach(l, activeSearchPath)
2499  {
2500  Oid namespaceId = lfirst_oid(l);
2501 
2502  if (namespaceId == myTempNamespace)
2503  continue; /* do not look in temp namespace */
2504 
2505  if (namespaceId == namespace)
2506  {
2507  /* Found it first in path */
2508  visible = true;
2509  break;
2510  }
2512  PointerGetDatum(name),
2513  ObjectIdGetDatum(namespaceId)))
2514  {
2515  /* Found something else first in path */
2516  break;
2517  }
2518  }
2519  }
2520 
2521  ReleaseSysCache(tup);
2522 
2523  return visible;
2524 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:41
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:184
const char * name
Definition: encode.c:521
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2337 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_ts_parser_is_visible().

2338 {
2339  HeapTuple tup;
2340  Form_pg_ts_parser form;
2341  Oid namespace;
2342  bool visible;
2343 
2345  if (!HeapTupleIsValid(tup))
2346  elog(ERROR, "cache lookup failed for text search parser %u", prsId);
2347  form = (Form_pg_ts_parser) GETSTRUCT(tup);
2348 
2350 
2351  /*
2352  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2353  * the system namespace are surely in the path and so we needn't even do
2354  * list_member_oid() for them.
2355  */
2356  namespace = form->prsnamespace;
2357  if (namespace != PG_CATALOG_NAMESPACE &&
2358  !list_member_oid(activeSearchPath, namespace))
2359  visible = false;
2360  else
2361  {
2362  /*
2363  * If it is in the path, it might still not be visible; it could be
2364  * hidden by another parser of the same name earlier in the path. So
2365  * we must do a slow check for conflicting parsers.
2366  */
2367  char *name = NameStr(form->prsname);
2368  ListCell *l;
2369 
2370  visible = false;
2371  foreach(l, activeSearchPath)
2372  {
2373  Oid namespaceId = lfirst_oid(l);
2374 
2375  if (namespaceId == myTempNamespace)
2376  continue; /* do not look in temp namespace */
2377 
2378  if (namespaceId == namespace)
2379  {
2380  /* Found it first in path */
2381  visible = true;
2382  break;
2383  }
2385  PointerGetDatum(name),
2386  ObjectIdGetDatum(namespaceId)))
2387  {
2388  /* Found something else first in path */
2389  break;
2390  }
2391  }
2392  }
2393 
2394  ReleaseSysCache(tup);
2395 
2396  return visible;
2397 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
FormData_pg_ts_parser * Form_pg_ts_parser
Definition: pg_ts_parser.h:53
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:184
const char * name
Definition: encode.c:521
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 2590 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_ts_template_is_visible().

2591 {
2592  HeapTuple tup;
2593  Form_pg_ts_template form;
2594  Oid namespace;
2595  bool visible;
2596 
2598  if (!HeapTupleIsValid(tup))
2599  elog(ERROR, "cache lookup failed for text search template %u", tmplId);
2600  form = (Form_pg_ts_template) GETSTRUCT(tup);
2601 
2603 
2604  /*
2605  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2606  * the system namespace are surely in the path and so we needn't even do
2607  * list_member_oid() for them.
2608  */
2609  namespace = form->tmplnamespace;
2610  if (namespace != PG_CATALOG_NAMESPACE &&
2611  !list_member_oid(activeSearchPath, namespace))
2612  visible = false;
2613  else
2614  {
2615  /*
2616  * If it is in the path, it might still not be visible; it could be
2617  * hidden by another template of the same name earlier in the path. So
2618  * we must do a slow check for conflicting templates.
2619  */
2620  char *name = NameStr(form->tmplname);
2621  ListCell *l;
2622 
2623  visible = false;
2624  foreach(l, activeSearchPath)
2625  {
2626  Oid namespaceId = lfirst_oid(l);
2627 
2628  if (namespaceId == myTempNamespace)
2629  continue; /* do not look in temp namespace */
2630 
2631  if (namespaceId == namespace)
2632  {
2633  /* Found it first in path */
2634  visible = true;
2635  break;
2636  }
2638  PointerGetDatum(name),
2639  ObjectIdGetDatum(namespaceId)))
2640  {
2641  /* Found something else first in path */
2642  break;
2643  }
2644  }
2645  }
2646 
2647  ReleaseSysCache(tup);
2648 
2649  return visible;
2650 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
#define PointerGetDatum(X)
Definition: postgres.h:541
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:184
const char * name
Definition: encode.c:521
static List * activeSearchPath
Definition: namespace.c:133
FormData_pg_ts_template * Form_pg_ts_template
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 796 of file namespace.c.

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

Referenced by format_type_extended(), and pg_type_is_visible().

797 {
798  HeapTuple typtup;
799  Form_pg_type typform;
800  Oid typnamespace;
801  bool visible;
802 
803  typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
804  if (!HeapTupleIsValid(typtup))
805  elog(ERROR, "cache lookup failed for type %u", typid);
806  typform = (Form_pg_type) GETSTRUCT(typtup);
807 
809 
810  /*
811  * Quick check: if it ain't in the path at all, it ain't visible. Items in
812  * the system namespace are surely in the path and so we needn't even do
813  * list_member_oid() for them.
814  */
815  typnamespace = typform->typnamespace;
816  if (typnamespace != PG_CATALOG_NAMESPACE &&
817  !list_member_oid(activeSearchPath, typnamespace))
818  visible = false;
819  else
820  {
821  /*
822  * If it is in the path, it might still not be visible; it could be
823  * hidden by another type of the same name earlier in the path. So we
824  * must do a slow check for conflicting types.
825  */
826  char *typname = NameStr(typform->typname);
827  ListCell *l;
828 
829  visible = false;
830  foreach(l, activeSearchPath)
831  {
832  Oid namespaceId = lfirst_oid(l);
833 
834  if (namespaceId == typnamespace)
835  {
836  /* Found it first in path */
837  visible = true;
838  break;
839  }
841  PointerGetDatum(typname),
842  ObjectIdGetDatum(namespaceId)))
843  {
844  /* Found something else first in path */
845  break;
846  }
847  }
848  }
849 
850  ReleaseSysCache(typtup);
851 
852  return visible;
853 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
#define PointerGetDatum(X)
Definition: postgres.h:541
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_type * Form_pg_type
Definition: pg_type.h:247
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:184
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ TypenameGetTypid()

Oid TypenameGetTypid ( const char *  typname)

Definition at line 767 of file namespace.c.

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

Referenced by LookupTypeName().

768 {
769  Oid typid;
770  ListCell *l;
771 
773 
774  foreach(l, activeSearchPath)
775  {
776  Oid namespaceId = lfirst_oid(l);
777 
779  PointerGetDatum(typname),
780  ObjectIdGetDatum(namespaceId));
781  if (OidIsValid(typid))
782  return typid;
783  }
784 
785  /* Not found in path */
786  return InvalidOid;
787 }
#define PointerGetDatum(X)
Definition: postgres.h:541
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108

Variable Documentation

◆ namespace_search_path

char* namespace_search_path

Definition at line 190 of file namespace.c.

Referenced by recomputeNamespacePath().