PostgreSQL Source Code  git master
namespace.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/parallel.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/dependency.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_ts_parser.h"
#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "funcapi.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_func.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/sinvaladt.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/catcache.h"
#include "utils/guc_hooks.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
#include "utils/varlena.h"
Include dependency graph for namespace.c:

Go to the source code of this file.

Macros

#define SPACE_PER_OP
 

Functions

static void recomputeNamespacePath (void)
 
static void AccessTempTableNamespace (bool force)
 
static void InitTempTableNamespace (void)
 
static void RemoveTempRelations (Oid tempNamespaceId)
 
static void RemoveTempRelationsCallback (int code, Datum arg)
 
static void NamespaceCallback (Datum arg, int cacheid, uint32 hashvalue)
 
static bool MatchNamedCall (HeapTuple proctup, int nargs, List *argnames, bool include_out_arguments, int pronargs, int **argnumbers)
 
Oid RangeVarGetRelidExtended (const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
 
Oid RangeVarGetCreationNamespace (const RangeVar *newRelation)
 
Oid RangeVarGetAndCheckCreationNamespace (RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
 
void RangeVarAdjustRelationPersistence (RangeVar *newRelation, Oid nspid)
 
Oid RelnameGetRelid (const char *relname)
 
bool RelationIsVisible (Oid relid)
 
Oid TypenameGetTypid (const char *typname)
 
Oid TypenameGetTypidExtended (const char *typname, bool temp_ok)
 
bool TypeIsVisible (Oid typid)
 
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok)
 
bool OperatorIsVisible (Oid oprid)
 
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
 
bool OpclassIsVisible (Oid opcid)
 
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
 
bool OpfamilyIsVisible (Oid opfid)
 
static Oid lookup_collation (const char *collname, Oid collnamespace, int32 encoding)
 
Oid CollationGetCollid (const char *collname)
 
bool CollationIsVisible (Oid collid)
 
Oid ConversionGetConid (const char *conname)
 
bool ConversionIsVisible (Oid conid)
 
Oid get_statistics_object_oid (List *names, bool missing_ok)
 
bool StatisticsObjIsVisible (Oid relid)
 
Oid get_ts_parser_oid (List *names, bool missing_ok)
 
bool TSParserIsVisible (Oid prsId)
 
Oid get_ts_dict_oid (List *names, bool missing_ok)
 
bool TSDictionaryIsVisible (Oid dictId)
 
Oid get_ts_template_oid (List *names, bool missing_ok)
 
bool TSTemplateIsVisible (Oid tmplId)
 
Oid get_ts_config_oid (List *names, bool missing_ok)
 
bool TSConfigIsVisible (Oid cfgid)
 
void DeconstructQualifiedName (const List *names, char **nspname_p, char **objname_p)
 
Oid LookupNamespaceNoError (const char *nspname)
 
Oid LookupExplicitNamespace (const char *nspname, bool missing_ok)
 
Oid LookupCreationNamespace (const char *nspname)
 
void CheckSetNamespace (Oid oldNspOid, Oid nspOid)
 
Oid QualifiedNameGetCreationNamespace (const List *names, char **objname_p)
 
Oid get_namespace_oid (const char *nspname, bool missing_ok)
 
RangeVarmakeRangeVarFromNameList (const List *names)
 
char * NameListToString (const List *names)
 
char * NameListToQuotedString (const List *names)
 
bool isTempNamespace (Oid namespaceId)
 
bool isTempToastNamespace (Oid namespaceId)
 
bool isTempOrTempToastNamespace (Oid namespaceId)
 
bool isAnyTempNamespace (Oid namespaceId)
 
bool isOtherTempNamespace (Oid namespaceId)
 
TempNamespaceStatus checkTempNamespaceStatus (Oid namespaceId)
 
int GetTempNamespaceBackendId (Oid namespaceId)
 
Oid GetTempToastNamespace (void)
 
void GetTempNamespaceState (Oid *tempNamespaceId, Oid *tempToastNamespaceId)
 
void SetTempNamespaceState (Oid tempNamespaceId, Oid tempToastNamespaceId)
 
SearchPathMatcherGetSearchPathMatcher (MemoryContext context)
 
SearchPathMatcherCopySearchPathMatcher (SearchPathMatcher *path)
 
bool SearchPathMatchesCurrentEnvironment (SearchPathMatcher *path)
 
Oid get_collation_oid (List *collname, bool missing_ok)
 
Oid get_conversion_oid (List *conname, bool missing_ok)
 
Oid FindDefaultConversionProc (int32 for_encoding, int32 to_encoding)
 
void AtEOXact_Namespace (bool isCommit, bool parallel)
 
void AtEOSubXact_Namespace (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void ResetTempTableNamespace (void)
 
bool check_search_path (char **newval, void **extra, GucSource source)
 
void assign_search_path (const char *newval, void *extra)
 
void InitializeSearchPath (void)
 
Listfetch_search_path (bool includeImplicit)
 
int fetch_search_path_array (Oid *sarray, int sarray_len)
 
Datum pg_table_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_type_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_function_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_operator_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_opclass_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_opfamily_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_collation_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_conversion_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_statistics_obj_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_parser_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_dict_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_template_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_config_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_my_temp_schema (PG_FUNCTION_ARGS)
 
Datum pg_is_other_temp_schema (PG_FUNCTION_ARGS)
 

Variables

static ListactiveSearchPath = NIL
 
static Oid activeCreationNamespace = InvalidOid
 
static bool activeTempCreationPending = false
 
static uint64 activePathGeneration = 1
 
static ListbaseSearchPath = NIL
 
static Oid baseCreationNamespace = InvalidOid
 
static bool baseTempCreationPending = false
 
static Oid namespaceUser = InvalidOid
 
static bool baseSearchPathValid = true
 
static Oid myTempNamespace = InvalidOid
 
static Oid myTempToastNamespace = InvalidOid
 
static SubTransactionId myTempNamespaceSubID = InvalidSubTransactionId
 
char * namespace_search_path = NULL
 

Macro Definition Documentation

◆ SPACE_PER_OP

#define SPACE_PER_OP
Value:
MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
2 * sizeof(Oid))
#define MAXALIGN(LEN)
Definition: c.h:800
unsigned int Oid
Definition: postgres_ext.h:31

Function Documentation

◆ AccessTempTableNamespace()

static void AccessTempTableNamespace ( bool  force)
static

Definition at line 3810 of file namespace.c.

3811 {
3812  /*
3813  * Make note that this temporary namespace has been accessed in this
3814  * transaction.
3815  */
3817 
3818  /*
3819  * If the caller attempting to access a temporary schema expects the
3820  * creation of the namespace to be pending and should be enforced, then go
3821  * through the creation.
3822  */
3823  if (!force && OidIsValid(myTempNamespace))
3824  return;
3825 
3826  /*
3827  * The temporary tablespace does not exist yet and is wanted, so
3828  * initialize it.
3829  */
3831 }
#define OidIsValid(objectId)
Definition: c.h:764
static Oid myTempNamespace
Definition: namespace.c:172
static void InitTempTableNamespace(void)
Definition: namespace.c:3838
int MyXactFlags
Definition: xact.c:136
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition: xact.h:102

References InitTempTableNamespace(), myTempNamespace, MyXactFlags, OidIsValid, and XACT_FLAGS_ACCESSEDTEMPNAMESPACE.

Referenced by fetch_search_path(), LookupCreationNamespace(), QualifiedNameGetCreationNamespace(), and RangeVarGetCreationNamespace().

◆ assign_search_path()

void assign_search_path ( const char *  newval,
void *  extra 
)

Definition at line 4136 of file namespace.c.

4137 {
4138  /*
4139  * We mark the path as needing recomputation, but don't do anything until
4140  * it's needed. This avoids trying to do database access during GUC
4141  * initialization, or outside a transaction.
4142  */
4143  baseSearchPathValid = false;
4144 }
static bool baseSearchPathValid
Definition: namespace.c:155

References baseSearchPathValid.

◆ AtEOSubXact_Namespace()

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

Definition at line 4004 of file namespace.c.

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

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 3959 of file namespace.c.

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

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

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

◆ check_search_path()

bool check_search_path ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 4102 of file namespace.c.

4103 {
4104  char *rawname;
4105  List *namelist;
4106 
4107  /* Need a modifiable copy of string */
4108  rawname = pstrdup(*newval);
4109 
4110  /* Parse string into list of identifiers */
4111  if (!SplitIdentifierString(rawname, ',', &namelist))
4112  {
4113  /* syntax error in name list */
4114  GUC_check_errdetail("List syntax is invalid.");
4115  pfree(rawname);
4116  list_free(namelist);
4117  return false;
4118  }
4119 
4120  /*
4121  * We used to try to check that the named schemas exist, but there are
4122  * many valid use-cases for having search_path settings that include
4123  * schemas that don't exist; and often, we are not inside a transaction
4124  * here and so can't consult the system catalogs anyway. So now, the only
4125  * requirement is syntactic validity of the identifier list.
4126  */
4127 
4128  pfree(rawname);
4129  list_free(namelist);
4130 
4131  return true;
4132 }
#define newval
#define GUC_check_errdetail
Definition: guc.h:436
void list_free(List *list)
Definition: list.c:1545
char * pstrdup(const char *in)
Definition: mcxt.c:1644
void pfree(void *pointer)
Definition: mcxt.c:1456
Definition: pg_list.h:54
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3454

References GUC_check_errdetail, list_free(), newval, pfree(), pstrdup(), and SplitIdentifierString().

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2992 of file namespace.c.

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

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

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

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3262 of file namespace.c.

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

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

Referenced by do_autovacuum().

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2039 of file namespace.c.

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

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

Referenced by CollationIsVisible().

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2073 of file namespace.c.

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

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

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

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2124 of file namespace.c.

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

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

Referenced by ConversionIsVisible().

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2156 of file namespace.c.

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

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

Referenced by getObjectDescription(), and pg_conversion_is_visible().

◆ CopySearchPathMatcher()

SearchPathMatcher* CopySearchPathMatcher ( SearchPathMatcher path)

Definition at line 3421 of file namespace.c.

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

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

Referenced by CopyCachedPlan().

◆ DeconstructQualifiedName()

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

Definition at line 2834 of file namespace.c.

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

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

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4215 of file namespace.c.

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

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

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

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4255 of file namespace.c.

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

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

Referenced by make_oper_cache_key().

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3612 of file namespace.c.

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

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

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

◆ FuncnameGetCandidates()

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

Definition at line 934 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1438 of file namespace.c.

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

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

Referenced by format_procedure_extended(), and pg_function_is_visible().

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3503 of file namespace.c.

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

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

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

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 3557 of file namespace.c.

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

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

Referenced by get_object_address().

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2203 of file namespace.c.

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

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

Referenced by AlterStatistics(), and get_object_address().

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2704 of file namespace.c.

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

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

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

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2451 of file namespace.c.

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

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

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

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2325 of file namespace.c.

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

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

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

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2578 of file namespace.c.

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

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

Referenced by DefineTSDictionary(), and get_object_address().

◆ GetSearchPathMatcher()

SearchPathMatcher* GetSearchPathMatcher ( MemoryContext  context)

Definition at line 3384 of file namespace.c.

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

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

Referenced by CompleteCachedPlan(), and RevalidateCachedQuery().

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3299 of file namespace.c.

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

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

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

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3338 of file namespace.c.

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

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3324 of file namespace.c.

3325 {
3327  return myTempToastNamespace;
3328 }

References Assert(), myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4152 of file namespace.c.

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

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

Referenced by InitPostgres().

◆ InitTempTableNamespace()

static void InitTempTableNamespace ( void  )
static

Definition at line 3838 of file namespace.c.

3839 {
3840  char namespaceName[NAMEDATALEN];
3841  Oid namespaceId;
3842  Oid toastspaceId;
3843 
3845 
3846  /*
3847  * First, do permission check to see if we are authorized to make temp
3848  * tables. We use a nonstandard error message here since "databasename:
3849  * permission denied" might be a tad cryptic.
3850  *
3851  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
3852  * that's necessary since current user ID could change during the session.
3853  * But there's no need to make the namespace in the first place until a
3854  * temp table creation request is made by someone with appropriate rights.
3855  */
3856  if (object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(),
3858  ereport(ERROR,
3859  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3860  errmsg("permission denied to create temporary tables in database \"%s\"",
3862 
3863  /*
3864  * Do not allow a Hot Standby session to make temp tables. Aside from
3865  * problems with modifying the system catalogs, there is a naming
3866  * conflict: pg_temp_N belongs to the session with BackendId N on the
3867  * primary, not to a hot standby session with the same BackendId. We
3868  * should not be able to get here anyway due to XactReadOnly checks, but
3869  * let's just make real sure. Note that this also backstops various
3870  * operations that allow XactReadOnly transactions to modify temp tables;
3871  * they'd need RecoveryInProgress checks if not for this.
3872  */
3873  if (RecoveryInProgress())
3874  ereport(ERROR,
3875  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3876  errmsg("cannot create temporary tables during recovery")));
3877 
3878  /* Parallel workers can't create temporary tables, either. */
3879  if (IsParallelWorker())
3880  ereport(ERROR,
3881  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3882  errmsg("cannot create temporary tables during a parallel operation")));
3883 
3884  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
3885 
3886  namespaceId = get_namespace_oid(namespaceName, true);
3887  if (!OidIsValid(namespaceId))
3888  {
3889  /*
3890  * First use of this temp namespace in this database; create it. The
3891  * temp namespaces are always owned by the superuser. We leave their
3892  * permissions at default --- i.e., no access except to superuser ---
3893  * to ensure that unprivileged users can't peek at other backends'
3894  * temp tables. This works because the places that access the temp
3895  * namespace for my own backend skip permissions checks on it.
3896  */
3897  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3898  true);
3899  /* Advance command counter to make namespace visible */
3901  }
3902  else
3903  {
3904  /*
3905  * If the namespace already exists, clean it out (in case the former
3906  * owner crashed without doing so).
3907  */
3908  RemoveTempRelations(namespaceId);
3909  }
3910 
3911  /*
3912  * If the corresponding toast-table namespace doesn't exist yet, create
3913  * it. (We assume there is no need to clean it out if it does exist, since
3914  * dropping a parent table should make its toast table go away.)
3915  */
3916  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
3917  MyBackendId);
3918 
3919  toastspaceId = get_namespace_oid(namespaceName, true);
3920  if (!OidIsValid(toastspaceId))
3921  {
3922  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3923  true);
3924  /* Advance command counter to make namespace visible */
3926  }
3927 
3928  /*
3929  * Okay, we've prepared the temp namespace ... but it's not committed yet,
3930  * so all our work could be undone by transaction rollback. Set flag for
3931  * AtEOXact_Namespace to know what to do.
3932  */
3933  myTempNamespace = namespaceId;
3934  myTempToastNamespace = toastspaceId;
3935 
3936  /*
3937  * Mark MyProc as owning this namespace which other processes can use to
3938  * decide if a temporary namespace is in use or not. We assume that
3939  * assignment of namespaceId is an atomic operation. Even if it is not,
3940  * the temporary relation which resulted in the creation of this temporary
3941  * namespace is still locked until the current transaction commits, and
3942  * its pg_namespace row is not visible yet. However it does not matter:
3943  * this flag makes the namespace as being in use, so no objects created on
3944  * it would be removed concurrently.
3945  */
3946  MyProc->tempNamespaceId = namespaceId;
3947 
3948  /* It should not be done already. */
3951 
3952  baseSearchPathValid = false; /* need to rebuild list */
3953 }
@ ACLCHECK_OK
Definition: acl.h:182
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3760
BackendId MyBackendId
Definition: globals.c:85
#define IsParallelWorker()
Definition: parallel.h:61
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3068
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4043
#define ACL_CREATE_TEMP
Definition: parsenodes.h:93
#define NAMEDATALEN
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
Definition: pg_namespace.c:43
#define snprintf
Definition: port.h:238
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:780
void CommandCounterIncrement(void)
Definition: xact.c:1078
bool RecoveryInProgress(void)
Definition: xlog.c:5948

References ACL_CREATE_TEMP, ACLCHECK_OK, Assert(), baseSearchPathValid, CommandCounterIncrement(), ereport, errcode(), errmsg(), ERROR, get_database_name(), get_namespace_oid(), GetCurrentSubTransactionId(), GetUserId(), InvalidSubTransactionId, IsParallelWorker, MyBackendId, MyDatabaseId, MyProc, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, NAMEDATALEN, NamespaceCreate(), object_aclcheck(), OidIsValid, RecoveryInProgress(), RemoveTempRelations(), snprintf, and PGPROC::tempNamespaceId.

Referenced by AccessTempTableNamespace().

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3220 of file namespace.c.

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

References get_namespace_name(), and pfree().

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

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3243 of file namespace.c.

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

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3182 of file namespace.c.

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

References myTempNamespace, and OidIsValid.

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

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3206 of file namespace.c.

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

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3194 of file namespace.c.

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

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

◆ lookup_collation()

static Oid lookup_collation ( const char *  collname,
Oid  collnamespace,
int32  encoding 
)
static

Definition at line 1988 of file namespace.c.

1989 {
1990  Oid collid;
1991  HeapTuple colltup;
1992  Form_pg_collation collform;
1993 
1994  /* Check for encoding-specific entry (exact match) */
1995  collid = GetSysCacheOid3(COLLNAMEENCNSP, Anum_pg_collation_oid,
1996  PointerGetDatum(collname),
1998  ObjectIdGetDatum(collnamespace));
1999  if (OidIsValid(collid))
2000  return collid;
2001 
2002  /*
2003  * Check for any-encoding entry. This takes a bit more work: while libc
2004  * collations with collencoding = -1 do work with all encodings, ICU
2005  * collations only work with certain encodings, so we have to check that
2006  * aspect before deciding it's a match.
2007  */
2008  colltup = SearchSysCache3(COLLNAMEENCNSP,
2009  PointerGetDatum(collname),
2010  Int32GetDatum(-1),
2011  ObjectIdGetDatum(collnamespace));
2012  if (!HeapTupleIsValid(colltup))
2013  return InvalidOid;
2014  collform = (Form_pg_collation) GETSTRUCT(colltup);
2015  if (collform->collprovider == COLLPROVIDER_ICU)
2016  {
2018  collid = collform->oid;
2019  else
2020  collid = InvalidOid;
2021  }
2022  else
2023  {
2024  collid = collform->oid;
2025  }
2026  ReleaseSysCache(colltup);
2027  return collid;
2028 }
bool is_encoding_supported_by_icu(int encoding)
Definition: encnames.c:462
int32 encoding
Definition: pg_database.h:41
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:842
@ COLLNAMEENCNSP
Definition: syscache.h:49
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:204

References collid, COLLNAMEENCNSP, encoding, GETSTRUCT, GetSysCacheOid3, HeapTupleIsValid, Int32GetDatum(), InvalidOid, is_encoding_supported_by_icu(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), ReleaseSysCache(), and SearchSysCache3().

Referenced by CollationGetCollid(), and get_collation_oid().

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2961 of file namespace.c.

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

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

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

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2918 of file namespace.c.

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

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

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

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2888 of file namespace.c.

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

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

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

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( const List names)

Definition at line 3087 of file namespace.c.

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

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

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

◆ MatchNamedCall()

static bool MatchNamedCall ( HeapTuple  proctup,
int  nargs,
List argnames,
bool  include_out_arguments,
int  pronargs,
int **  argnumbers 
)
static

Definition at line 1327 of file namespace.c.

1330 {
1331  Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
1332  int numposargs = nargs - list_length(argnames);
1333  int pronallargs;
1334  Oid *p_argtypes;
1335  char **p_argnames;
1336  char *p_argmodes;
1337  bool arggiven[FUNC_MAX_ARGS];
1338  bool isnull;
1339  int ap; /* call args position */
1340  int pp; /* proargs position */
1341  ListCell *lc;
1342 
1343  Assert(argnames != NIL);
1344  Assert(numposargs >= 0);
1345  Assert(nargs <= pronargs);
1346 
1347  /* Ignore this function if its proargnames is null */
1348  (void) SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proargnames,
1349  &isnull);
1350  if (isnull)
1351  return false;
1352 
1353  /* OK, let's extract the argument names and types */
1354  pronallargs = get_func_arg_info(proctup,
1355  &p_argtypes, &p_argnames, &p_argmodes);
1356  Assert(p_argnames != NULL);
1357 
1358  Assert(include_out_arguments ? (pronargs == pronallargs) : (pronargs <= pronallargs));
1359 
1360  /* initialize state for matching */
1361  *argnumbers = (int *) palloc(pronargs * sizeof(int));
1362  memset(arggiven, false, pronargs * sizeof(bool));
1363 
1364  /* there are numposargs positional args before the named args */
1365  for (ap = 0; ap < numposargs; ap++)
1366  {
1367  (*argnumbers)[ap] = ap;
1368  arggiven[ap] = true;
1369  }
1370 
1371  /* now examine the named args */
1372  foreach(lc, argnames)
1373  {
1374  char *argname = (char *) lfirst(lc);
1375  bool found;
1376  int i;
1377 
1378  pp = 0;
1379  found = false;
1380  for (i = 0; i < pronallargs; i++)
1381  {
1382  /* consider only input params, except with include_out_arguments */
1383  if (!include_out_arguments &&
1384  p_argmodes &&
1385  (p_argmodes[i] != FUNC_PARAM_IN &&
1386  p_argmodes[i] != FUNC_PARAM_INOUT &&
1387  p_argmodes[i] != FUNC_PARAM_VARIADIC))
1388  continue;
1389  if (p_argnames[i] && strcmp(p_argnames[i], argname) == 0)
1390  {
1391  /* fail if argname matches a positional argument */
1392  if (arggiven[pp])
1393  return false;
1394  arggiven[pp] = true;
1395  (*argnumbers)[ap] = pp;
1396  found = true;
1397  break;
1398  }
1399  /* increase pp only for considered parameters */
1400  pp++;
1401  }
1402  /* if name isn't in proargnames, fail */
1403  if (!found)
1404  return false;
1405  ap++;
1406  }
1407 
1408  Assert(ap == nargs); /* processed all actual parameters */
1409 
1410  /* Check for default arguments */
1411  if (nargs < pronargs)
1412  {
1413  int first_arg_with_default = pronargs - procform->pronargdefaults;
1414 
1415  for (pp = numposargs; pp < pronargs; pp++)
1416  {
1417  if (arggiven[pp])
1418  continue;
1419  /* fail if arg not given and no default available */
1420  if (pp < first_arg_with_default)
1421  return false;
1422  (*argnumbers)[ap++] = pp;
1423  }
1424  }
1425 
1426  Assert(ap == pronargs); /* processed all function parameters */
1427 
1428  return true;
1429 }
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition: funcapi.c:1371
@ FUNC_PARAM_IN
Definition: parsenodes.h:3316
@ FUNC_PARAM_INOUT
Definition: parsenodes.h:3318
@ FUNC_PARAM_VARIADIC
Definition: parsenodes.h:3319
#define FUNC_MAX_ARGS
#define lfirst(lc)
Definition: pg_list.h:172

References Assert(), FUNC_MAX_ARGS, FUNC_PARAM_IN, FUNC_PARAM_INOUT, FUNC_PARAM_VARIADIC, get_func_arg_info(), GETSTRUCT, i, lfirst, list_length(), NIL, palloc(), PROCOID, pronargs, and SysCacheGetAttr().

Referenced by FuncnameGetCandidates().

◆ NameListToQuotedString()

char* NameListToQuotedString ( const List names)

Definition at line 3161 of file namespace.c.

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

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

◆ NameListToString()

char* NameListToString ( const List names)

Definition at line 3127 of file namespace.c.

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

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

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

◆ NamespaceCallback()

static void NamespaceCallback ( Datum  arg,
int  cacheid,
uint32  hashvalue 
)
static

Definition at line 4197 of file namespace.c.

4198 {
4199  /* Force search path to be recomputed on next use */
4200  baseSearchPathValid = false;
4201 }

References baseSearchPathValid.

Referenced by InitializeSearchPath().

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1858 of file namespace.c.

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

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

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

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1825 of file namespace.c.

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

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

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

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1772 of file namespace.c.

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

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

Referenced by format_operator_extended(), and pg_operator_is_visible().

◆ OpernameGetCandidates()

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

Definition at line 1611 of file namespace.c.

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

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

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

◆ OpernameGetOprid()

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

Definition at line 1508 of file namespace.c.

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

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

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

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1941 of file namespace.c.

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

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1908 of file namespace.c.

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

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

◆ pg_collation_is_visible()

Datum pg_collation_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4358 of file namespace.c.

4359 {
4360  Oid oid = PG_GETARG_OID(0);
4361 
4363  PG_RETURN_NULL();
4364 
4366 }
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool CollationIsVisible(Oid collid)
Definition: namespace.c:2073
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:191

References CollationIsVisible(), COLLOID, ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and SearchSysCacheExists1.

◆ pg_conversion_is_visible()

Datum pg_conversion_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4369 of file namespace.c.

4370 {
4371  Oid oid = PG_GETARG_OID(0);
4372 
4374  PG_RETURN_NULL();
4375 
4377 }
bool ConversionIsVisible(Oid conid)
Definition: namespace.c:2156

References ConversionIsVisible(), CONVOID, ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and SearchSysCacheExists1.

◆ pg_function_is_visible()

Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4314 of file namespace.c.

4315 {
4316  Oid oid = PG_GETARG_OID(0);
4317 
4319  PG_RETURN_NULL();
4320 
4322 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1438

References FunctionIsVisible(), ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, PROCOID, and SearchSysCacheExists1.

◆ pg_is_other_temp_schema()

Datum pg_is_other_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4441 of file namespace.c.

4442 {
4443  Oid oid = PG_GETARG_OID(0);
4444 
4446 }
bool isOtherTempNamespace(Oid namespaceId)
Definition: namespace.c:3243

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

◆ pg_my_temp_schema()

Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4435 of file namespace.c.

4436 {
4438 }
#define PG_RETURN_OID(x)
Definition: fmgr.h:360

References myTempNamespace, and PG_RETURN_OID.

◆ pg_opclass_is_visible()

Datum pg_opclass_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4336 of file namespace.c.

4337 {
4338  Oid oid = PG_GETARG_OID(0);
4339 
4341  PG_RETURN_NULL();
4342 
4344 }
bool OpclassIsVisible(Oid opcid)
Definition: namespace.c:1858

References CLAOID, ObjectIdGetDatum(), OpclassIsVisible(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and SearchSysCacheExists1.

◆ pg_operator_is_visible()

Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4325 of file namespace.c.

4326 {
4327  Oid oid = PG_GETARG_OID(0);
4328 
4330  PG_RETURN_NULL();
4331 
4333 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1772

References ObjectIdGetDatum(), OperatorIsVisible(), OPEROID, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and SearchSysCacheExists1.

◆ pg_opfamily_is_visible()

Datum pg_opfamily_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4347 of file namespace.c.

4348 {
4349  Oid oid = PG_GETARG_OID(0);
4350 
4352  PG_RETURN_NULL();
4353 
4355 }
bool OpfamilyIsVisible(Oid opfid)
Definition: namespace.c:1941

References ObjectIdGetDatum(), OpfamilyIsVisible(), OPFAMILYOID, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and SearchSysCacheExists1.

◆ pg_statistics_obj_is_visible()

Datum pg_statistics_obj_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4380 of file namespace.c.

4381 {
4382  Oid oid = PG_GETARG_OID(0);
4383 
4385  PG_RETURN_NULL();
4386 
4388 }
bool StatisticsObjIsVisible(Oid relid)
Definition: namespace.c:2260
@ STATEXTOID
Definition: syscache.h:96

References ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, STATEXTOID, and StatisticsObjIsVisible().

◆ pg_table_is_visible()

Datum pg_table_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4292 of file namespace.c.

4293 {
4294  Oid oid = PG_GETARG_OID(0);
4295 
4297  PG_RETURN_NULL();
4298 
4300 }
bool RelationIsVisible(Oid relid)
Definition: namespace.c:693
@ RELOID
Definition: syscache.h:89

References ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, RelationIsVisible(), RELOID, and SearchSysCacheExists1.

◆ pg_ts_config_is_visible()

Datum pg_ts_config_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4424 of file namespace.c.

4425 {
4426  Oid oid = PG_GETARG_OID(0);
4427 
4429  PG_RETURN_NULL();
4430 
4432 }
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2762
@ TSCONFIGOID
Definition: syscache.h:106

References ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, TSConfigIsVisible(), and TSCONFIGOID.

◆ pg_ts_dict_is_visible()

Datum pg_ts_dict_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4402 of file namespace.c.

4403 {
4404  Oid oid = PG_GETARG_OID(0);
4405 
4407  PG_RETURN_NULL();
4408 
4410 }
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2509
@ TSDICTOID
Definition: syscache.h:108

References ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, TSDictionaryIsVisible(), and TSDICTOID.

◆ pg_ts_parser_is_visible()

Datum pg_ts_parser_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4391 of file namespace.c.

4392 {
4393  Oid oid = PG_GETARG_OID(0);
4394 
4396  PG_RETURN_NULL();
4397 
4399 }
bool TSParserIsVisible(Oid prsId)
Definition: namespace.c:2383
@ TSPARSEROID
Definition: syscache.h:110

References ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, TSParserIsVisible(), and TSPARSEROID.

◆ pg_ts_template_is_visible()

Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4413 of file namespace.c.

4414 {
4415  Oid oid = PG_GETARG_OID(0);
4416 
4418  PG_RETURN_NULL();
4419 
4421 }
bool TSTemplateIsVisible(Oid tmplId)
Definition: namespace.c:2636
@ TSTEMPLATEOID
Definition: syscache.h:112

References ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, TSTemplateIsVisible(), and TSTEMPLATEOID.

◆ pg_type_is_visible()

Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4303 of file namespace.c.

4304 {
4305  Oid oid = PG_GETARG_OID(0);
4306 
4308  PG_RETURN_NULL();
4309 
4311 }
bool TypeIsVisible(Oid typid)
Definition: namespace.c:801
@ TYPEOID
Definition: syscache.h:114

References ObjectIdGetDatum(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, TypeIsVisible(), and TYPEOID.

◆ QualifiedNameGetCreationNamespace()

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

Definition at line 3020 of file namespace.c.

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

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

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

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 626 of file namespace.c.

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

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 519 of file namespace.c.

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

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 434 of file namespace.c.

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

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

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

◆ RangeVarGetRelidExtended()

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

Definition at line 221 of file namespace.c.

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

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

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

◆ recomputeNamespacePath()

static void recomputeNamespacePath ( void  )
static

Definition at line 3639 of file namespace.c.

3640 {
3641  Oid roleid = GetUserId();
3642  char *rawname;
3643  List *namelist;
3644  List *oidlist;
3645  List *newpath;
3646  ListCell *l;
3647  bool temp_missing;
3648  Oid firstNS;
3649  bool pathChanged;
3650  MemoryContext oldcxt;
3651 
3652  /* Do nothing if path is already valid. */
3653  if (baseSearchPathValid && namespaceUser == roleid)
3654  return;
3655 
3656  /* Need a modifiable copy of namespace_search_path string */
3657  rawname = pstrdup(namespace_search_path);
3658 
3659  /* Parse string into list of identifiers */
3660  if (!SplitIdentifierString(rawname, ',', &namelist))
3661  {
3662  /* syntax error in name list */
3663  /* this should not happen if GUC checked check_search_path */
3664  elog(ERROR, "invalid list syntax");
3665  }
3666 
3667  /*
3668  * Convert the list of names to a list of OIDs. If any names are not
3669  * recognizable or we don't have read access, just leave them out of the
3670  * list. (We can't raise an error, since the search_path setting has
3671  * already been accepted.) Don't make duplicate entries, either.
3672  */
3673  oidlist = NIL;
3674  temp_missing = false;
3675  foreach(l, namelist)
3676  {
3677  char *curname = (char *) lfirst(l);
3678  Oid namespaceId;
3679 
3680  if (strcmp(curname, "$user") == 0)
3681  {
3682  /* $user --- substitute namespace matching user name, if any */
3683  HeapTuple tuple;
3684 
3685  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
3686  if (HeapTupleIsValid(tuple))
3687  {
3688  char *rname;
3689 
3690  rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
3691  namespaceId = get_namespace_oid(rname, true);
3692  ReleaseSysCache(tuple);
3693  if (OidIsValid(namespaceId) &&
3694  !list_member_oid(oidlist, namespaceId) &&
3695  object_aclcheck(NamespaceRelationId, namespaceId, roleid,
3696  ACL_USAGE) == ACLCHECK_OK &&
3697  InvokeNamespaceSearchHook(namespaceId, false))
3698  oidlist = lappend_oid(oidlist, namespaceId);
3699  }
3700  }
3701  else if (strcmp(curname, "pg_temp") == 0)
3702  {
3703  /* pg_temp --- substitute temp namespace, if any */
3705  {
3706  if (!list_member_oid(oidlist, myTempNamespace) &&
3708  oidlist = lappend_oid(oidlist, myTempNamespace);
3709  }
3710  else
3711  {
3712  /* If it ought to be the creation namespace, set flag */
3713  if (oidlist == NIL)
3714  temp_missing = true;
3715  }
3716  }
3717  else
3718  {
3719  /* normal namespace reference */
3720  namespaceId = get_namespace_oid(curname, true);
3721  if (OidIsValid(namespaceId) &&
3722  !list_member_oid(oidlist, namespaceId) &&
3723  object_aclcheck(NamespaceRelationId, namespaceId, roleid,
3724  ACL_USAGE) == ACLCHECK_OK &&
3725  InvokeNamespaceSearchHook(namespaceId, false))
3726  oidlist = lappend_oid(oidlist, namespaceId);
3727  }
3728  }
3729 
3730  /*
3731  * Remember the first member of the explicit list. (Note: this is
3732  * nominally wrong if temp_missing, but we need it anyway to distinguish
3733  * explicit from implicit mention of pg_catalog.)
3734  */
3735  if (oidlist == NIL)
3736  firstNS = InvalidOid;
3737  else
3738  firstNS = linitial_oid(oidlist);
3739 
3740  /*
3741  * Add any implicitly-searched namespaces to the list. Note these go on
3742  * the front, not the back; also notice that we do not check USAGE
3743  * permissions for these.
3744  */
3745  if (!list_member_oid(oidlist, PG_CATALOG_NAMESPACE))
3746  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3747 
3748  if (OidIsValid(myTempNamespace) &&
3749  !list_member_oid(oidlist, myTempNamespace))
3750  oidlist = lcons_oid(myTempNamespace, oidlist);
3751 
3752  /*
3753  * We want to detect the case where the effective value of the base search
3754  * path variables didn't change. As long as we're doing so, we can avoid
3755  * copying the OID list unnecessarily.
3756  */
3757  if (baseCreationNamespace == firstNS &&
3758  baseTempCreationPending == temp_missing &&
3759  equal(oidlist, baseSearchPath))
3760  {
3761  pathChanged = false;
3762  }
3763  else
3764  {
3765  pathChanged = true;
3766 
3767  /* Must save OID list in permanent storage. */
3769  newpath = list_copy(oidlist);
3770  MemoryContextSwitchTo(oldcxt);
3771 
3772  /* Now safe to assign to state variables. */
3774  baseSearchPath = newpath;
3775  baseCreationNamespace = firstNS;
3776  baseTempCreationPending = temp_missing;
3777  }
3778 
3779  /* Mark the path valid. */
3780  baseSearchPathValid = true;
3781  namespaceUser = roleid;
3782 
3783  /* And make it active. */
3787 
3788  /*
3789  * Bump the generation only if something actually changed. (Notice that
3790  * what we compared to was the old state of the base path variables.)
3791  */
3792  if (pathChanged)
3794 
3795  /* Clean up. */
3796  pfree(rawname);
3797  list_free(namelist);
3798  list_free(oidlist);
3799 }
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:223
List * lappend_oid(List *list, Oid datum)
Definition: list.c:374
List * lcons_oid(Oid datum, List *list)
Definition: list.c:530
char * namespace_search_path
Definition: namespace.c:182
NameData rolname
Definition: pg_authid.h:34
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56

References ACL_USAGE, ACLCHECK_OK, activeCreationNamespace, activePathGeneration, activeSearchPath, activeTempCreationPending, AUTHOID, baseCreationNamespace, baseSearchPath, baseSearchPathValid, baseTempCreationPending, elog(), equal(), ERROR, get_namespace_oid(), GETSTRUCT, GetUserId(), HeapTupleIsValid, InvalidOid, InvokeNamespaceSearchHook, lappend_oid(), lcons_oid(), lfirst, linitial_oid, list_copy(), list_free(), list_member_oid(), MemoryContextSwitchTo(), myTempNamespace, namespace_search_path, namespaceUser, NameStr, NIL, object_aclcheck(), ObjectIdGetDatum(), OidIsValid, pfree(), pstrdup(), ReleaseSysCache(), rolname, SearchSysCache1(), SplitIdentifierString(), and TopMemoryContext.

Referenced by CollationGetCollid(), CollationIsVisible(), ConversionGetConid(), ConversionIsVisible(), fetch_search_path(), fetch_search_path_array(), FindDefaultConversionProc(), FuncnameGetCandidates(), FunctionIsVisible(), 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(), GetSearchPathMatcher(), OpclassIsVisible(), OpclassnameGetOpcid(), OperatorIsVisible(), OpernameGetCandidates(), OpernameGetOprid(), OpfamilyIsVisible(), OpfamilynameGetOpfid(), QualifiedNameGetCreationNamespace(), RangeVarGetCreationNamespace(), RelationIsVisible(), RelnameGetRelid(), SearchPathMatchesCurrentEnvironment(), StatisticsObjIsVisible(), TSConfigIsVisible(), TSDictionaryIsVisible(), TSParserIsVisible(), TSTemplateIsVisible(), TypeIsVisible(), and TypenameGetTypidExtended().

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 693 of file namespace.c.

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

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

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

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 665 of file namespace.c.

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

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

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

◆ RemoveTempRelations()

static void RemoveTempRelations ( Oid  tempNamespaceId)
static

Definition at line 4043 of file namespace.c.

4044 {
4045  ObjectAddress object;
4046 
4047  /*
4048  * We want to get rid of everything in the target namespace, but not the
4049  * namespace itself (deleting it only to recreate it later would be a
4050  * waste of cycles). Hence, specify SKIP_ORIGINAL. It's also an INTERNAL
4051  * deletion, and we want to not drop any extensions that might happen to
4052  * own temp objects.
4053  */
4054  object.classId = NamespaceRelationId;
4055  object.objectId = tempNamespaceId;
4056  object.objectSubId = 0;
4057 
4058  performDeletion(&object, DROP_CASCADE,
4063 }
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
Definition: dependency.c:328
#define PERFORM_DELETION_SKIP_EXTENSIONS
Definition: dependency.h:140
#define PERFORM_DELETION_QUIETLY
Definition: dependency.h:138
#define PERFORM_DELETION_SKIP_ORIGINAL
Definition: dependency.h:139
#define PERFORM_DELETION_INTERNAL
Definition: dependency.h:136
@ DROP_CASCADE
Definition: parsenodes.h:2194

References ObjectAddress::classId, DROP_CASCADE, PERFORM_DELETION_INTERNAL, PERFORM_DELETION_QUIETLY, PERFORM_DELETION_SKIP_EXTENSIONS, PERFORM_DELETION_SKIP_ORIGINAL, and performDeletion().

Referenced by InitTempTableNamespace(), RemoveTempRelationsCallback(), and ResetTempTableNamespace().

◆ RemoveTempRelationsCallback()

static void RemoveTempRelationsCallback ( int  code,
Datum  arg 
)
static

Definition at line 4069 of file namespace.c.

4070 {
4071  if (OidIsValid(myTempNamespace)) /* should always be true */
4072  {
4073  /* Need to ensure we have a usable transaction. */
4077 
4079 
4082  }
4083 }
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:197
void PushActiveSnapshot(Snapshot snapshot)
Definition: snapmgr.c:629
void PopActiveSnapshot(void)
Definition: snapmgr.c:724
void StartTransactionCommand(void)
Definition: xact.c:2937
void CommitTransactionCommand(void)
Definition: xact.c:3034
void AbortOutOfAnyTransaction(void)
Definition: xact.c:4712

References AbortOutOfAnyTransaction(), CommitTransactionCommand(), GetTransactionSnapshot(), myTempNamespace, OidIsValid, PopActiveSnapshot(), PushActiveSnapshot(), RemoveTempRelations(), and StartTransactionCommand().

Referenced by AtEOXact_Namespace().

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4089 of file namespace.c.

4090 {
4093 }

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

◆ SearchPathMatchesCurrentEnvironment()

bool SearchPathMatchesCurrentEnvironment ( SearchPathMatcher path)

Definition at line 3443 of file namespace.c.

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

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

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

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3354 of file namespace.c.

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

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

Referenced by ParallelWorkerMain().

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  relid)

Definition at line 2260 of file namespace.c.

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

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

Referenced by getObjectDescription(), and pg_statistics_obj_is_visible().

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 2762 of file namespace.c.

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

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

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

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2509 of file namespace.c.

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

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

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

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2383 of file namespace.c.

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

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

Referenced by getObjectDescription(), and pg_ts_parser_is_visible().

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 2636 of file namespace.c.

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

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

Referenced by getObjectDescription(), and pg_ts_template_is_visible().

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 801 of file namespace.c.

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

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

Referenced by format_type_extended(), and pg_type_is_visible().

◆ TypenameGetTypid()

Oid TypenameGetTypid ( const char *  typname)

Definition at line 756 of file namespace.c.

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

References TypenameGetTypidExtended(), and typname.

◆ TypenameGetTypidExtended()

Oid TypenameGetTypidExtended ( const char *  typname,
bool  temp_ok 
)

Definition at line 769 of file namespace.c.

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

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

Referenced by LookupTypeNameExtended(), and TypenameGetTypid().

Variable Documentation

◆ activeCreationNamespace

◆ activePathGeneration

uint64 activePathGeneration = 1
static

◆ activeSearchPath

◆ activeTempCreationPending

◆ baseCreationNamespace

Oid baseCreationNamespace = InvalidOid
static

Definition at line 148 of file namespace.c.

Referenced by InitializeSearchPath(), and recomputeNamespacePath().

◆ baseSearchPath

List* baseSearchPath = NIL
static

Definition at line 146 of file namespace.c.

Referenced by InitializeSearchPath(), and recomputeNamespacePath().

◆ baseSearchPathValid

◆ baseTempCreationPending

bool baseTempCreationPending = false
static

Definition at line 150 of file namespace.c.

Referenced by InitializeSearchPath(), and recomputeNamespacePath().

◆ myTempNamespace

◆ myTempNamespaceSubID

◆ myTempToastNamespace

◆ namespace_search_path

char* namespace_search_path = NULL

Definition at line 182 of file namespace.c.

Referenced by CreateSchemaCommand(), and recomputeNamespacePath().

◆ namespaceUser

Oid namespaceUser = InvalidOid
static

Definition at line 152 of file namespace.c.

Referenced by InitializeSearchPath(), and recomputeNamespacePath().