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)
 
Oid TypenameGetTypidExtended (const char *typname, bool temp_ok)
 
bool TypeIsVisible (Oid typid)
 
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool missing_ok)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok)
 
bool OperatorIsVisible (Oid oprid)
 
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
 
bool OpclassIsVisible (Oid opcid)
 
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
 
bool OpfamilyIsVisible (Oid opfid)
 
Oid CollationGetCollid (const char *collname)
 
bool CollationIsVisible (Oid collid)
 
Oid ConversionGetConid (const char *conname)
 
bool ConversionIsVisible (Oid conid)
 
Oid get_statistics_object_oid (List *names, bool missing_ok)
 
bool StatisticsObjIsVisible (Oid relid)
 
Oid get_ts_parser_oid (List *names, bool missing_ok)
 
bool TSParserIsVisible (Oid prsId)
 
Oid get_ts_dict_oid (List *names, bool missing_ok)
 
bool TSDictionaryIsVisible (Oid dictId)
 
Oid get_ts_template_oid (List *names, bool missing_ok)
 
bool TSTemplateIsVisible (Oid tmplId)
 
Oid get_ts_config_oid (List *names, bool missing_ok)
 
bool TSConfigIsVisible (Oid cfgid)
 
void DeconstructQualifiedName (List *names, char **nspname_p, char **objname_p)
 
Oid LookupNamespaceNoError (const char *nspname)
 
Oid LookupExplicitNamespace (const char *nspname, bool missing_ok)
 
Oid get_namespace_oid (const char *nspname, bool missing_ok)
 
Oid LookupCreationNamespace (const char *nspname)
 
void CheckSetNamespace (Oid oldNspOid, Oid nspOid)
 
Oid QualifiedNameGetCreationNamespace (List *names, char **objname_p)
 
RangeVarmakeRangeVarFromNameList (List *names)
 
char * NameListToString (List *names)
 
char * NameListToQuotedString (List *names)
 
bool isTempNamespace (Oid namespaceId)
 
bool isTempToastNamespace (Oid namespaceId)
 
bool isTempOrTempToastNamespace (Oid namespaceId)
 
bool isAnyTempNamespace (Oid namespaceId)
 
bool isOtherTempNamespace (Oid namespaceId)
 
bool isTempNamespaceInUse (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 4069 of file namespace.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

4071 {
4072  OverrideStackEntry *entry;
4073 
4074  if (myTempNamespaceSubID == mySubid)
4075  {
4076  if (isCommit)
4077  myTempNamespaceSubID = parentSubid;
4078  else
4079  {
4081  /* TEMP namespace creation failed, so reset state */
4084  baseSearchPathValid = false; /* need to rebuild list */
4085 
4086  /*
4087  * Reset the temporary namespace flag in MyProc. We assume that
4088  * this operation is atomic.
4089  *
4090  * Because this subtransaction is aborting, the pg_namespace row
4091  * is not visible to anyone else anyway, but that doesn't matter:
4092  * it's not a problem if objects contained in this namespace are
4093  * removed concurrently.
4094  */
4096  }
4097  }
4098 
4099  /*
4100  * Clean up if someone failed to do PopOverrideSearchPath
4101  */
4102  while (overrideStack)
4103  {
4106  break;
4107  if (isCommit)
4108  elog(WARNING, "leaked override search path");
4110  list_free(entry->searchPath);
4111  pfree(entry);
4112  }
4113 
4114  /* Activate the next level down. */
4115  if (overrideStack)
4116  {
4118  activeSearchPath = entry->searchPath;
4120  activeTempCreationPending = false; /* XXX is this OK? */
4121  }
4122  else
4123  {
4124  /* If not baseSearchPathValid, this is useless but harmless */
4128  }
4129 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid tempNamespaceId
Definition: proc.h:117
PGPROC * MyProc
Definition: proc.c:68
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:195
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:842
#define InvalidSubTransactionId
Definition: c.h:513
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1373
#define elog(elevel,...)
Definition: elog.h:226
List * list_delete_first(List *list)
Definition: list.c:857

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4003 of file namespace.c.

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

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

4004 {
4005  /*
4006  * If we abort the transaction in which a temp namespace was selected,
4007  * we'll have to do any creation or cleanout work over again. So, just
4008  * forget the namespace entirely until next time. On the other hand, if
4009  * we commit then register an exit callback to clean out the temp tables
4010  * at backend shutdown. (We only want to register the callback once per
4011  * session, so this is a good place to do it.)
4012  */
4013  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
4014  {
4015  if (isCommit)
4017  else
4018  {
4021  baseSearchPathValid = false; /* need to rebuild list */
4022 
4023  /*
4024  * Reset the temporary namespace flag in MyProc. We assume that
4025  * this operation is atomic.
4026  *
4027  * Because this transaction is aborting, the pg_namespace row is
4028  * not visible to anyone else anyway, but that doesn't matter:
4029  * it's not a problem if objects contained in this namespace are
4030  * removed concurrently.
4031  */
4033  }
4035  }
4036 
4037  /*
4038  * Clean up if someone failed to do PopOverrideSearchPath
4039  */
4040  if (overrideStack)
4041  {
4042  if (isCommit)
4043  elog(WARNING, "leaked override search path");
4044  while (overrideStack)
4045  {
4046  OverrideStackEntry *entry;
4047 
4050  list_free(entry->searchPath);
4051  pfree(entry);
4052  }
4053  /* If not baseSearchPathValid, this is useless but harmless */
4057  }
4058 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid tempNamespaceId
Definition: proc.h:117
PGPROC * MyProc
Definition: proc.c:68
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:195
static bool baseTempCreationPending
Definition: namespace.c:147
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c: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:513
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1373
#define elog(elevel,...)
Definition: elog.h:226
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4166
List * list_delete_first(List *list)
Definition: list.c:857

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2959 of file namespace.c.

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

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

2960 {
2961  /* disallow renaming into or out of temp schemas */
2962  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2963  ereport(ERROR,
2964  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2965  errmsg("cannot move objects into or out of temporary schemas")));
2966 
2967  /* same for TOAST schema */
2968  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
2969  ereport(ERROR,
2970  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2971  errmsg("cannot move objects into or out of TOAST schema")));
2972 }
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3187

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2006 of file namespace.c.

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

Referenced by CollationIsVisible().

2007 {
2008  int32 dbencoding = GetDatabaseEncoding();
2009  ListCell *l;
2010 
2012 
2013  foreach(l, activeSearchPath)
2014  {
2015  Oid namespaceId = lfirst_oid(l);
2016  Oid collid;
2017 
2018  if (namespaceId == myTempNamespace)
2019  continue; /* do not look in temp namespace */
2020 
2021  collid = lookup_collation(collname, namespaceId, dbencoding);
2022  if (OidIsValid(collid))
2023  return collid;
2024  }
2025 
2026  /* Not found in path */
2027  return InvalidOid;
2028 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
signed int int32
Definition: c.h:346
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1955
int GetDatabaseEncoding(void)
Definition: mbutils.c:996
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

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

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

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2091 of file namespace.c.

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

Referenced by ConversionIsVisible().

2092 {
2093  Oid conid;
2094  ListCell *l;
2095 
2097 
2098  foreach(l, activeSearchPath)
2099  {
2100  Oid namespaceId = lfirst_oid(l);
2101 
2102  if (namespaceId == myTempNamespace)
2103  continue; /* do not look in temp namespace */
2104 
2105  conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2106  PointerGetDatum(conname),
2107  ObjectIdGetDatum(namespaceId));
2108  if (OidIsValid(conid))
2109  return conid;
2110  }
2111 
2112  /* Not found in path */
2113  return InvalidOid;
2114 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

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

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

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3388 of file namespace.c.

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

Referenced by CopyCachedPlan().

3389 {
3390  OverrideSearchPath *result;
3391 
3392  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3393  result->schemas = list_copy(path->schemas);
3394  result->addCatalog = path->addCatalog;
3395  result->addTemp = path->addTemp;
3396 
3397  return result;
3398 }
List * list_copy(const List *oldlist)
Definition: list.c:1400
void * palloc(Size size)
Definition: mcxt.c:924

◆ DeconstructQualifiedName()

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

Definition at line 2801 of file namespace.c.

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

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

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4305 of file namespace.c.

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

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

4306 {
4307  List *result;
4308 
4310 
4311  /*
4312  * If the temp namespace should be first, force it to exist. This is so
4313  * that callers can trust the result to reflect the actual default
4314  * creation namespace. It's a bit bogus to do this here, since
4315  * current_schema() is supposedly a stable function without side-effects,
4316  * but the alternatives seem worse.
4317  */
4319  {
4322  }
4323 
4324  result = list_copy(activeSearchPath);
4325  if (!includeImplicit)
4326  {
4327  while (result && linitial_oid(result) != activeCreationNamespace)
4328  result = list_delete_first(result);
4329  }
4330 
4331  return result;
4332 }
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3854
List * list_copy(const List *oldlist)
Definition: list.c:1400
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool activeTempCreationPending
Definition: namespace.c:139
#define linitial_oid(l)
Definition: pg_list.h:197
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:857

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4345 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4346 {
4347  int count = 0;
4348  ListCell *l;
4349 
4351 
4352  foreach(l, activeSearchPath)
4353  {
4354  Oid namespaceId = lfirst_oid(l);
4355 
4356  if (namespaceId == myTempNamespace)
4357  continue; /* do not include temp namespace */
4358 
4359  if (count < sarray_len)
4360  sarray[count] = namespaceId;
4361  count++;
4362  }
4363 
4364  return count;
4365 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3673 of file namespace.c.

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

Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().

3674 {
3675  Oid proc;
3676  ListCell *l;
3677 
3679 
3680  foreach(l, activeSearchPath)
3681  {
3682  Oid namespaceId = lfirst_oid(l);
3683 
3684  if (namespaceId == myTempNamespace)
3685  continue; /* do not look in temp namespace */
3686 
3687  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3688  if (OidIsValid(proc))
3689  return proc;
3690  }
3691 
3692  /* Not found in path */
3693  return InvalidOid;
3694 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#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:192

◆ FuncnameGetCandidates()

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

Definition at line 934 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1405 of file namespace.c.

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

Referenced by format_procedure_internal(), and pg_function_is_visible().

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

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

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

3565 {
3566  char *schemaname;
3567  char *collation_name;
3568  int32 dbencoding = GetDatabaseEncoding();
3569  Oid namespaceId;
3570  Oid colloid;
3571  ListCell *l;
3572 
3573  /* deconstruct the name list */
3574  DeconstructQualifiedName(name, &schemaname, &collation_name);
3575 
3576  if (schemaname)
3577  {
3578  /* use exact schema given */
3579  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3580  if (missing_ok && !OidIsValid(namespaceId))
3581  return InvalidOid;
3582 
3583  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3584  if (OidIsValid(colloid))
3585  return colloid;
3586  }
3587  else
3588  {
3589  /* search for it in search path */
3591 
3592  foreach(l, activeSearchPath)
3593  {
3594  namespaceId = lfirst_oid(l);
3595 
3596  if (namespaceId == myTempNamespace)
3597  continue; /* do not look in temp namespace */
3598 
3599  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3600  if (OidIsValid(colloid))
3601  return colloid;
3602  }
3603  }
3604 
3605  /* Not found in path */
3606  if (!missing_ok)
3607  ereport(ERROR,
3608  (errcode(ERRCODE_UNDEFINED_OBJECT),
3609  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3611  return InvalidOid;
3612 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2885
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2801
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
signed int int32
Definition: c.h:346
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1955
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
char * NameListToString(List *names)
Definition: namespace.c:3094
int GetDatabaseEncoding(void)
Definition: mbutils.c:996
#define InvalidOid
Definition: postgres_ext.h:36
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1002
const char * name
Definition: encode.c:521
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

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

3619 {
3620  char *schemaname;
3621  char *conversion_name;
3622  Oid namespaceId;
3623  Oid conoid = InvalidOid;
3624  ListCell *l;
3625 
3626  /* deconstruct the name list */
3627  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3628 
3629  if (schemaname)
3630  {
3631  /* use exact schema given */
3632  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3633  if (missing_ok && !OidIsValid(namespaceId))
3634  conoid = InvalidOid;
3635  else
3636  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3637  PointerGetDatum(conversion_name),
3638  ObjectIdGetDatum(namespaceId));
3639  }
3640  else
3641  {
3642  /* search for it in search path */
3644 
3645  foreach(l, activeSearchPath)
3646  {
3647  namespaceId = lfirst_oid(l);
3648 
3649  if (namespaceId == myTempNamespace)
3650  continue; /* do not look in temp namespace */
3651 
3652  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3653  PointerGetDatum(conversion_name),
3654  ObjectIdGetDatum(namespaceId));
3655  if (OidIsValid(conoid))
3656  return conoid;
3657  }
3658  }
3659 
3660  /* Not found in path */
3661  if (!OidIsValid(conoid) && !missing_ok)
3662  ereport(ERROR,
3663  (errcode(ERRCODE_UNDEFINED_OBJECT),
3664  errmsg("conversion \"%s\" does not exist",
3665  NameListToString(name))));
3666  return conoid;
3667 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2885
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2801
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
char * NameListToString(List *names)
Definition: namespace.c:3094
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
const char * name
Definition: encode.c:521
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

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

3036 {
3037  Oid oid;
3038 
3039  oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid,
3040  CStringGetDatum(nspname));
3041  if (!OidIsValid(oid) && !missing_ok)
3042  ereport(ERROR,
3043  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3044  errmsg("schema \"%s\" does not exist", nspname)));
3045 
3046  return oid;
3047 }
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:192
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2170 of file namespace.c.

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

Referenced by AlterStatistics(), and get_object_address().

2171 {
2172  char *schemaname;
2173  char *stats_name;
2174  Oid namespaceId;
2175  Oid stats_oid = InvalidOid;
2176  ListCell *l;
2177 
2178  /* deconstruct the name list */
2179  DeconstructQualifiedName(names, &schemaname, &stats_name);
2180 
2181  if (schemaname)
2182  {
2183  /* use exact schema given */
2184  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2185  if (missing_ok && !OidIsValid(namespaceId))
2186  stats_oid = InvalidOid;
2187  else
2188  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2189  PointerGetDatum(stats_name),
2190  ObjectIdGetDatum(namespaceId));
2191  }
2192  else
2193  {
2194  /* search for it in search path */
2196 
2197  foreach(l, activeSearchPath)
2198  {
2199  namespaceId = lfirst_oid(l);
2200 
2201  if (namespaceId == myTempNamespace)
2202  continue; /* do not look in temp namespace */
2203  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2204  PointerGetDatum(stats_name),
2205  ObjectIdGetDatum(namespaceId));
2206  if (OidIsValid(stats_oid))
2207  break;
2208  }
2209  }
2210 
2211  if (!OidIsValid(stats_oid) && !missing_ok)
2212  ereport(ERROR,
2213  (errcode(ERRCODE_UNDEFINED_OBJECT),
2214  errmsg("statistics object \"%s\" does not exist",
2215  NameListToString(names))));
2216 
2217  return stats_oid;
2218 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2885
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2801
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
char * NameListToString(List *names)
Definition: namespace.c:3094
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

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

2672 {
2673  char *schemaname;
2674  char *config_name;
2675  Oid namespaceId;
2676  Oid cfgoid = InvalidOid;
2677  ListCell *l;
2678 
2679  /* deconstruct the name list */
2680  DeconstructQualifiedName(names, &schemaname, &config_name);
2681 
2682  if (schemaname)
2683  {
2684  /* use exact schema given */
2685  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2686  if (missing_ok && !OidIsValid(namespaceId))
2687  cfgoid = InvalidOid;
2688  else
2689  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2690  PointerGetDatum(config_name),
2691  ObjectIdGetDatum(namespaceId));
2692  }
2693  else
2694  {
2695  /* search for it in search path */
2697 
2698  foreach(l, activeSearchPath)
2699  {
2700  namespaceId = lfirst_oid(l);
2701 
2702  if (namespaceId == myTempNamespace)
2703  continue; /* do not look in temp namespace */
2704 
2705  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2706  PointerGetDatum(config_name),
2707  ObjectIdGetDatum(namespaceId));
2708  if (OidIsValid(cfgoid))
2709  break;
2710  }
2711  }
2712 
2713  if (!OidIsValid(cfgoid) && !missing_ok)
2714  ereport(ERROR,
2715  (errcode(ERRCODE_UNDEFINED_OBJECT),
2716  errmsg("text search configuration \"%s\" does not exist",
2717  NameListToString(names))));
2718 
2719  return cfgoid;
2720 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2885
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2801
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
char * NameListToString(List *names)
Definition: namespace.c:3094
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2418 of file namespace.c.

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

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

2419 {
2420  char *schemaname;
2421  char *dict_name;
2422  Oid namespaceId;
2423  Oid dictoid = InvalidOid;
2424  ListCell *l;
2425 
2426  /* deconstruct the name list */
2427  DeconstructQualifiedName(names, &schemaname, &dict_name);
2428 
2429  if (schemaname)
2430  {
2431  /* use exact schema given */
2432  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2433  if (missing_ok && !OidIsValid(namespaceId))
2434  dictoid = InvalidOid;
2435  else
2436  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2437  PointerGetDatum(dict_name),
2438  ObjectIdGetDatum(namespaceId));
2439  }
2440  else
2441  {
2442  /* search for it in search path */
2444 
2445  foreach(l, activeSearchPath)
2446  {
2447  namespaceId = lfirst_oid(l);
2448 
2449  if (namespaceId == myTempNamespace)
2450  continue; /* do not look in temp namespace */
2451 
2452  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2453  PointerGetDatum(dict_name),
2454  ObjectIdGetDatum(namespaceId));
2455  if (OidIsValid(dictoid))
2456  break;
2457  }
2458  }
2459 
2460  if (!OidIsValid(dictoid) && !missing_ok)
2461  ereport(ERROR,
2462  (errcode(ERRCODE_UNDEFINED_OBJECT),
2463  errmsg("text search dictionary \"%s\" does not exist",
2464  NameListToString(names))));
2465 
2466  return dictoid;
2467 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2885
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2801
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
char * NameListToString(List *names)
Definition: namespace.c:3094
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

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

2293 {
2294  char *schemaname;
2295  char *parser_name;
2296  Oid namespaceId;
2297  Oid prsoid = InvalidOid;
2298  ListCell *l;
2299 
2300  /* deconstruct the name list */
2301  DeconstructQualifiedName(names, &schemaname, &parser_name);
2302 
2303  if (schemaname)
2304  {
2305  /* use exact schema given */
2306  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2307  if (missing_ok && !OidIsValid(namespaceId))
2308  prsoid = InvalidOid;
2309  else
2310  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2311  PointerGetDatum(parser_name),
2312  ObjectIdGetDatum(namespaceId));
2313  }
2314  else
2315  {
2316  /* search for it in search path */
2318 
2319  foreach(l, activeSearchPath)
2320  {
2321  namespaceId = lfirst_oid(l);
2322 
2323  if (namespaceId == myTempNamespace)
2324  continue; /* do not look in temp namespace */
2325 
2326  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2327  PointerGetDatum(parser_name),
2328  ObjectIdGetDatum(namespaceId));
2329  if (OidIsValid(prsoid))
2330  break;
2331  }
2332  }
2333 
2334  if (!OidIsValid(prsoid) && !missing_ok)
2335  ereport(ERROR,
2336  (errcode(ERRCODE_UNDEFINED_OBJECT),
2337  errmsg("text search parser \"%s\" does not exist",
2338  NameListToString(names))));
2339 
2340  return prsoid;
2341 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2885
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2801
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
char * NameListToString(List *names)
Definition: namespace.c:3094
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

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

2546 {
2547  char *schemaname;
2548  char *template_name;
2549  Oid namespaceId;
2550  Oid tmploid = InvalidOid;
2551  ListCell *l;
2552 
2553  /* deconstruct the name list */
2554  DeconstructQualifiedName(names, &schemaname, &template_name);
2555 
2556  if (schemaname)
2557  {
2558  /* use exact schema given */
2559  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2560  if (missing_ok && !OidIsValid(namespaceId))
2561  tmploid = InvalidOid;
2562  else
2563  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2564  PointerGetDatum(template_name),
2565  ObjectIdGetDatum(namespaceId));
2566  }
2567  else
2568  {
2569  /* search for it in search path */
2571 
2572  foreach(l, activeSearchPath)
2573  {
2574  namespaceId = lfirst_oid(l);
2575 
2576  if (namespaceId == myTempNamespace)
2577  continue; /* do not look in temp namespace */
2578 
2579  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2580  PointerGetDatum(template_name),
2581  ObjectIdGetDatum(namespaceId));
2582  if (OidIsValid(tmploid))
2583  break;
2584  }
2585  }
2586 
2587  if (!OidIsValid(tmploid) && !missing_ok)
2588  ereport(ERROR,
2589  (errcode(ERRCODE_UNDEFINED_OBJECT),
2590  errmsg("text search template \"%s\" does not exist",
2591  NameListToString(names))));
2592 
2593  return tmploid;
2594 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2885
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2801
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
char * NameListToString(List *names)
Definition: namespace.c:3094
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

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

3353 {
3354  OverrideSearchPath *result;
3355  List *schemas;
3356  MemoryContext oldcxt;
3357 
3359 
3360  oldcxt = MemoryContextSwitchTo(context);
3361 
3362  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3363  schemas = list_copy(activeSearchPath);
3364  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3365  {
3366  if (linitial_oid(schemas) == myTempNamespace)
3367  result->addTemp = true;
3368  else
3369  {
3370  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3371  result->addCatalog = true;
3372  }
3373  schemas = list_delete_first(schemas);
3374  }
3375  result->schemas = schemas;
3376 
3377  MemoryContextSwitchTo(oldcxt);
3378 
3379  return result;
3380 }
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:1400
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
static Oid activeCreationNamespace
Definition: namespace.c:136
void * palloc0(Size size)
Definition: mcxt.c:955
#define Assert(condition)
Definition: c.h:732
#define linitial_oid(l)
Definition: pg_list.h:197
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:857

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3266 of file namespace.c.

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

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

3267 {
3268  int result;
3269  char *nspname;
3270 
3271  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3272  nspname = get_namespace_name(namespaceId);
3273  if (!nspname)
3274  return InvalidBackendId; /* no such namespace? */
3275  if (strncmp(nspname, "pg_temp_", 8) == 0)
3276  result = atoi(nspname + 8);
3277  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3278  result = atoi(nspname + 14);
3279  else
3280  result = InvalidBackendId;
3281  pfree(nspname);
3282  return result;
3283 }
void pfree(void *pointer)
Definition: mcxt.c:1031
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
#define InvalidBackendId
Definition: backendid.h:23

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3305 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3306 {
3307  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3308  *tempNamespaceId = myTempNamespace;
3309  *tempToastNamespaceId = myTempToastNamespace;
3310 }
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3291 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3292 {
3294  return myTempToastNamespace;
3295 }
static Oid myTempToastNamespace
Definition: namespace.c:182
#define OidIsValid(objectId)
Definition: c.h:638
#define Assert(condition)
Definition: c.h:732

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

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

4248 {
4250  {
4251  /*
4252  * In bootstrap mode, the search path must be 'pg_catalog' so that
4253  * tables are created in the proper namespace; ignore the GUC setting.
4254  */
4255  MemoryContext oldcxt;
4256 
4258  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4259  MemoryContextSwitchTo(oldcxt);
4260  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4261  baseTempCreationPending = false;
4262  baseSearchPathValid = true;
4267  }
4268  else
4269  {
4270  /*
4271  * In normal mode, arrange for a callback on any syscache invalidation
4272  * of pg_namespace rows.
4273  */
4276  (Datum) 0);
4277  /* Force search path to be recomputed on next use */
4278  baseSearchPathValid = false;
4279  }
4280 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid GetUserId(void)
Definition: miscinit.c:380
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:4287
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:1426
uintptr_t Datum
Definition: postgres.h:367
#define list_make1_oid(x1)
Definition: pg_list.h:249
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374
static List * activeSearchPath
Definition: namespace.c:133

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3187 of file namespace.c.

References get_namespace_name(), and pfree().

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

3188 {
3189  bool result;
3190  char *nspname;
3191 
3192  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3193  nspname = get_namespace_name(namespaceId);
3194  if (!nspname)
3195  return false; /* no such namespace? */
3196  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3197  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3198  pfree(nspname);
3199  return result;
3200 }
void pfree(void *pointer)
Definition: mcxt.c:1031
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3210 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

3211 {
3212  /* If it's my own temp namespace, say "false" */
3213  if (isTempOrTempToastNamespace(namespaceId))
3214  return false;
3215  /* Else, if it's any temp namespace, say "true" */
3216  return isAnyTempNamespace(namespaceId);
3217 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3173
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3187

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3149 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

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

◆ isTempNamespaceInUse()

bool isTempNamespaceInUse ( Oid  namespaceId)

Definition at line 3229 of file namespace.c.

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

Referenced by do_autovacuum().

3230 {
3231  PGPROC *proc;
3232  int backendId;
3233 
3235 
3236  backendId = GetTempNamespaceBackendId(namespaceId);
3237 
3238  if (backendId == InvalidBackendId ||
3239  backendId == MyBackendId)
3240  return false;
3241 
3242  /* Is the backend alive? */
3243  proc = BackendIdGetProc(backendId);
3244  if (proc == NULL)
3245  return false;
3246 
3247  /* Is the backend connected to the same database we are looking at? */
3248  if (proc->databaseId != MyDatabaseId)
3249  return false;
3250 
3251  /* Does the backend own the temporary namespace? */
3252  if (proc->tempNamespaceId != namespaceId)
3253  return false;
3254 
3255  /* all good to go */
3256  return true;
3257 }
BackendId MyBackendId
Definition: globals.c:81
Oid tempNamespaceId
Definition: proc.h:117
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3266
#define OidIsValid(objectId)
Definition: c.h:638
Oid databaseId
Definition: proc.h:114
#define InvalidBackendId
Definition: backendid.h:23
Oid MyDatabaseId
Definition: globals.c:85
#define Assert(condition)
Definition: c.h:732
Definition: proc.h:95
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:377

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3173 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

3174 {
3175  if (OidIsValid(myTempNamespace) &&
3176  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3177  return true;
3178  return false;
3179 }
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:638

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3161 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

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

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2928 of file namespace.c.

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

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

2929 {
2930  Oid namespaceId;
2931  AclResult aclresult;
2932 
2933  /* check for pg_temp alias */
2934  if (strcmp(nspname, "pg_temp") == 0)
2935  {
2936  /* Initialize temp namespace */
2937  AccessTempTableNamespace(false);
2938  return myTempNamespace;
2939  }
2940 
2941  namespaceId = get_namespace_oid(nspname, false);
2942 
2943  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2944  if (aclresult != ACLCHECK_OK)
2945  aclcheck_error(aclresult, OBJECT_SCHEMA,
2946  nspname);
2947 
2948  return namespaceId;
2949 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3035
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3854
Oid GetUserId(void)
Definition: miscinit.c:380
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4693
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
#define ACL_CREATE
Definition: parsenodes.h:84
AclResult
Definition: acl.h:177

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2885 of file namespace.c.

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

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

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

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2855 of file namespace.c.

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

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

2856 {
2857  /* check for pg_temp alias */
2858  if (strcmp(nspname, "pg_temp") == 0)
2859  {
2861  {
2863  return myTempNamespace;
2864  }
2865 
2866  /*
2867  * Since this is used only for looking up existing objects, there is
2868  * no point in trying to initialize the temp namespace here; and doing
2869  * so might create problems for some callers. Just report "not found".
2870  */
2871  return InvalidOid;
2872  }
2873 
2874  return get_namespace_oid(nspname, true);
2875 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3035
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:638
#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 3054 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().

3055 {
3056  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3057 
3058  switch (list_length(names))
3059  {
3060  case 1:
3061  rel->relname = strVal(linitial(names));
3062  break;
3063  case 2:
3064  rel->schemaname = strVal(linitial(names));
3065  rel->relname = strVal(lsecond(names));
3066  break;
3067  case 3:
3068  rel->catalogname = strVal(linitial(names));
3069  rel->schemaname = strVal(lsecond(names));
3070  rel->relname = strVal(lthird(names));
3071  break;
3072  default:
3073  ereport(ERROR,
3074  (errcode(ERRCODE_SYNTAX_ERROR),
3075  errmsg("improper relation name (too many dotted names): %s",
3076  NameListToString(names))));
3077  break;
3078  }
3079 
3080  return rel;
3081 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:570
#define lsecond(l)
Definition: pg_list.h:200
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
#define linitial(l)
Definition: pg_list.h:195
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
char * NameListToString(List *names)
Definition: namespace.c:3094
static int list_length(const List *l)
Definition: pg_list.h:169
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define lthird(l)
Definition: pg_list.h:205
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:420
char * catalogname
Definition: primnodes.h:66

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3128 of file namespace.c.

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

3129 {
3131  ListCell *l;
3132 
3133  initStringInfo(&string);
3134 
3135  foreach(l, names)
3136  {
3137  if (l != list_head(names))
3138  appendStringInfoChar(&string, '.');
3140  }
3141 
3142  return string.data;
3143 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10628
#define strVal(v)
Definition: value.h:54
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define lfirst(lc)
Definition: pg_list.h:190

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3094 of file namespace.c.

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

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

3095 {
3097  ListCell *l;
3098 
3099  initStringInfo(&string);
3100 
3101  foreach(l, names)
3102  {
3103  Node *name = (Node *) lfirst(l);
3104 
3105  if (l != list_head(names))
3106  appendStringInfoChar(&string, '.');
3107 
3108  if (IsA(name, String))
3109  appendStringInfoString(&string, strVal(name));
3110  else if (IsA(name, A_Star))
3111  appendStringInfoChar(&string, '*');
3112  else
3113  elog(ERROR, "unexpected node type in name list: %d",
3114  (int) nodeTag(name));
3115  }
3116 
3117  return string.data;
3118 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
Definition: nodes.h:525
#define strVal(v)
Definition: value.h:54
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define lfirst(lc)
Definition: pg_list.h:190
const char * name
Definition: encode.c:521
#define nodeTag(nodeptr)
Definition: nodes.h:530
#define elog(elevel,...)
Definition: elog.h:226

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

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

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

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1792 of file namespace.c.

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

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

1793 {
1794  Oid opcid;
1795  ListCell *l;
1796 
1798 
1799  foreach(l, activeSearchPath)
1800  {
1801  Oid namespaceId = lfirst_oid(l);
1802 
1803  if (namespaceId == myTempNamespace)
1804  continue; /* do not look in temp namespace */
1805 
1806  opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
1807  ObjectIdGetDatum(amid),
1808  PointerGetDatum(opcname),
1809  ObjectIdGetDatum(namespaceId));
1810  if (OidIsValid(opcid))
1811  return opcid;
1812  }
1813 
1814  /* Not found in path */
1815  return InvalidOid;
1816 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:196
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

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

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

◆ OpernameGetCandidates()

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

Definition at line 1579 of file namespace.c.

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

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

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

◆ OpernameGetOprid()

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

Definition at line 1476 of file namespace.c.

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

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

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

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

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

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

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1875 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

1876 {
1877  Oid opfid;
1878  ListCell *l;
1879 
1881 
1882  foreach(l, activeSearchPath)
1883  {
1884  Oid namespaceId = lfirst_oid(l);
1885 
1886  if (namespaceId == myTempNamespace)
1887  continue; /* do not look in temp namespace */
1888 
1889  opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
1890  ObjectIdGetDatum(amid),
1891  PointerGetDatum(opfname),
1892  ObjectIdGetDatum(namespaceId));
1893  if (OidIsValid(opfid))
1894  return opfid;
1895  }
1896 
1897  /* Not found in path */
1898  return InvalidOid;
1899 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:196
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3404 of file namespace.c.

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

Referenced by RevalidateCachedQuery().

3405 {
3406  ListCell *lc,
3407  *lcp;
3408 
3410 
3411  /* We scan down the activeSearchPath to see if it matches the input. */
3413 
3414  /* If path->addTemp, first item should be my temp namespace. */
3415  if (path->addTemp)
3416  {
3417  if (lc && lfirst_oid(lc) == myTempNamespace)
3418  lc = lnext(activeSearchPath, lc);
3419  else
3420  return false;
3421  }
3422  /* If path->addCatalog, next item should be pg_catalog. */
3423  if (path->addCatalog)
3424  {
3425  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3426  lc = lnext(activeSearchPath, lc);
3427  else
3428  return false;
3429  }
3430  /* We should now be looking at the activeCreationNamespace. */
3431  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3432  return false;
3433  /* The remainder of activeSearchPath should match path->schemas. */
3434  foreach(lcp, path->schemas)
3435  {
3436  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3437  lc = lnext(activeSearchPath, lc);
3438  else
3439  return false;
3440  }
3441  if (lc)
3442  return false;
3443  return true;
3444 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
static Oid myTempNamespace
Definition: namespace.c:180
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
static Oid activeCreationNamespace
Definition: namespace.c:136
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

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

3524 {
3525  OverrideStackEntry *entry;
3526 
3527  /* Sanity checks. */
3528  if (overrideStack == NIL)
3529  elog(ERROR, "bogus PopOverrideSearchPath call");
3531  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3532  elog(ERROR, "bogus PopOverrideSearchPath call");
3533 
3534  /* Pop the stack and free storage. */
3536  list_free(entry->searchPath);
3537  pfree(entry);
3538 
3539  /* Activate the next level down. */
3540  if (overrideStack)
3541  {
3543  activeSearchPath = entry->searchPath;
3545  activeTempCreationPending = false; /* XXX is this OK? */
3546  }
3547  else
3548  {
3549  /* If not baseSearchPathValid, this is useless but harmless */
3553  }
3554 }
#define NIL
Definition: pg_list.h:65
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:195
#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:842
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1373
#define elog(elevel,...)
Definition: elog.h:226
List * list_delete_first(List *list)
Definition: list.c:857

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

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

3465 {
3466  OverrideStackEntry *entry;
3467  List *oidlist;
3468  Oid firstNS;
3469  MemoryContext oldcxt;
3470 
3471  /*
3472  * Copy the list for safekeeping, and insert implicitly-searched
3473  * namespaces as needed. This code should track recomputeNamespacePath.
3474  */
3476 
3477  oidlist = list_copy(newpath->schemas);
3478 
3479  /*
3480  * Remember the first member of the explicit list.
3481  */
3482  if (oidlist == NIL)
3483  firstNS = InvalidOid;
3484  else
3485  firstNS = linitial_oid(oidlist);
3486 
3487  /*
3488  * Add any implicitly-searched namespaces to the list. Note these go on
3489  * the front, not the back; also notice that we do not check USAGE
3490  * permissions for these.
3491  */
3492  if (newpath->addCatalog)
3493  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3494 
3495  if (newpath->addTemp && OidIsValid(myTempNamespace))
3496  oidlist = lcons_oid(myTempNamespace, oidlist);
3497 
3498  /*
3499  * Build the new stack entry, then insert it at the head of the list.
3500  */
3501  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3502  entry->searchPath = oidlist;
3503  entry->creationNamespace = firstNS;
3505 
3506  overrideStack = lcons(entry, overrideStack);
3507 
3508  /* And make it active. */
3509  activeSearchPath = entry->searchPath;
3511  activeTempCreationPending = false; /* XXX is this OK? */
3512 
3513  MemoryContextSwitchTo(oldcxt);
3514 }
#define NIL
Definition: pg_list.h:65
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:1400
List * lcons_oid(Oid datum, List *list)
Definition: list.c:489
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
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:842
List * lcons(void *datum, List *list)
Definition: list.c:453
#define linitial_oid(l)
Definition: pg_list.h:197
static List * activeSearchPath
Definition: namespace.c:133
void * palloc(Size size)
Definition: mcxt.c:924
Definition: pg_list.h:50

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 2987 of file namespace.c.

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

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

2988 {
2989  char *schemaname;
2990  Oid namespaceId;
2991 
2992  /* deconstruct the name list */
2993  DeconstructQualifiedName(names, &schemaname, objname_p);
2994 
2995  if (schemaname)
2996  {
2997  /* check for pg_temp alias */
2998  if (strcmp(schemaname, "pg_temp") == 0)
2999  {
3000  /* Initialize temp namespace */
3001  AccessTempTableNamespace(false);
3002  return myTempNamespace;
3003  }
3004  /* use exact schema given */
3005  namespaceId = get_namespace_oid(schemaname, false);
3006  /* we do not check for USAGE rights here! */
3007  }
3008  else
3009  {
3010  /* use the default creation namespace */
3013  {
3014  /* Need to initialize temp namespace */
3016  return myTempNamespace;
3017  }
3018  namespaceId = activeCreationNamespace;
3019  if (!OidIsValid(namespaceId))
3020  ereport(ERROR,
3021  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3022  errmsg("no schema has been selected to create in")));
3023  }
3024 
3025  return namespaceId;
3026 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3035
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3854
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2801
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
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:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 633 of file namespace.c.

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

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 441 of file namespace.c.

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

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

442 {
443  Oid namespaceId;
444 
445  /*
446  * We check the catalog name and then ignore it.
447  */
448  if (newRelation->catalogname)
449  {
450  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
451  ereport(ERROR,
452  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
453  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
454  newRelation->catalogname, newRelation->schemaname,
455  newRelation->relname)));
456  }
457 
458  if (newRelation->schemaname)
459  {
460  /* check for pg_temp alias */
461  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
462  {
463  /* Initialize temp namespace */
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 */
475  return myTempNamespace;
476  }
477  else
478  {
479  /* use the default creation namespace */
482  {
483  /* Need to initialize temp namespace */
485  return myTempNamespace;
486  }
487  namespaceId = activeCreationNamespace;
488  if (!OidIsValid(namespaceId))
489  ereport(ERROR,
490  (errcode(ERRCODE_UNDEFINED_SCHEMA),
491  errmsg("no schema has been selected to create in")));
492  }
493 
494  /* Note: callers will check for CREATE rights when appropriate */
495 
496  return namespaceId;
497 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3035
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3854
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
static Oid activeCreationNamespace
Definition: namespace.c:136
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2099
static bool activeTempCreationPending
Definition: namespace.c:139
#define ereport(elevel, rest)
Definition: elog.h:141
Oid MyDatabaseId
Definition: globals.c:85
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:784
char * catalogname
Definition: primnodes.h:66

◆ RangeVarGetRelidExtended()

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

Definition at line 228 of file namespace.c.

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

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

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

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 700 of file namespace.c.

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

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

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

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 672 of file namespace.c.

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

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

673 {
674  Oid relid;
675  ListCell *l;
676 
678 
679  foreach(l, activeSearchPath)
680  {
681  Oid namespaceId = lfirst_oid(l);
682 
683  relid = get_relname_relid(relname, namespaceId);
684  if (OidIsValid(relid))
685  return relid;
686  }
687 
688  /* Not found in path */
689  return InvalidOid;
690 }
NameData relname
Definition: pg_class.h:35
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
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:192

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4184 of file namespace.c.

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

4185 {
4188 }
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:638
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4140

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3321 of file namespace.c.

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

Referenced by ParallelWorkerMain().

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

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  relid)

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

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

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

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

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

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

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

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

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

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

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

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

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

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

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 808 of file namespace.c.

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

Referenced by format_type_extended(), and pg_type_is_visible().

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

◆ TypenameGetTypid()

Oid TypenameGetTypid ( const char *  typname)

Definition at line 763 of file namespace.c.

References TypenameGetTypidExtended().

764 {
765  return TypenameGetTypidExtended(typname, true);
766 }
Oid TypenameGetTypidExtended(const char *typname, bool temp_ok)
Definition: namespace.c:776
NameData typname
Definition: pg_type.h:42

◆ TypenameGetTypidExtended()

Oid TypenameGetTypidExtended ( const char *  typname,
bool  temp_ok 
)

Definition at line 776 of file namespace.c.

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

Referenced by LookupTypeNameExtended(), and TypenameGetTypid().

777 {
778  Oid typid;
779  ListCell *l;
780 
782 
783  foreach(l, activeSearchPath)
784  {
785  Oid namespaceId = lfirst_oid(l);
786 
787  if (!temp_ok && namespaceId == myTempNamespace)
788  continue; /* do not look in temp namespace */
789 
790  typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
792  ObjectIdGetDatum(namespaceId));
793  if (OidIsValid(typid))
794  return typid;
795  }
796 
797  /* Not found in path */
798  return InvalidOid;
799 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
NameData typname
Definition: pg_type.h:42
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:192

Variable Documentation

◆ namespace_search_path

char* namespace_search_path

Definition at line 190 of file namespace.c.

Referenced by recomputeNamespacePath().