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_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.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/syscache.h"
#include "utils/varlena.h"
Include dependency graph for namespace.c:

Go to the source code of this file.

Data Structures

struct  OverrideStackEntry
 

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, 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)
 
bool TypeIsVisible (Oid typid)
 
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool missing_ok)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok)
 
bool OperatorIsVisible (Oid oprid)
 
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
 
bool OpclassIsVisible (Oid opcid)
 
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
 
bool OpfamilyIsVisible (Oid opfid)
 
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 (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 (List *names, char **objname_p)
 
Oid get_namespace_oid (const char *nspname, bool missing_ok)
 
RangeVarmakeRangeVarFromNameList (List *names)
 
char * NameListToString (List *names)
 
char * NameListToQuotedString (List *names)
 
bool isTempNamespace (Oid namespaceId)
 
bool isTempToastNamespace (Oid namespaceId)
 
bool isTempOrTempToastNamespace (Oid namespaceId)
 
bool isAnyTempNamespace (Oid namespaceId)
 
bool isOtherTempNamespace (Oid namespaceId)
 
bool isTempNamespaceInUse (Oid namespaceId)
 
int GetTempNamespaceBackendId (Oid namespaceId)
 
Oid GetTempToastNamespace (void)
 
void GetTempNamespaceState (Oid *tempNamespaceId, Oid *tempToastNamespaceId)
 
void SetTempNamespaceState (Oid tempNamespaceId, Oid tempToastNamespaceId)
 
OverrideSearchPathGetOverrideSearchPath (MemoryContext context)
 
OverrideSearchPathCopyOverrideSearchPath (OverrideSearchPath *path)
 
bool OverrideSearchPathMatchesCurrent (OverrideSearchPath *path)
 
void PushOverrideSearchPath (OverrideSearchPath *newpath)
 
void PopOverrideSearchPath (void)
 
Oid get_collation_oid (List *name, bool missing_ok)
 
Oid get_conversion_oid (List *name, 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 ListbaseSearchPath = NIL
 
static Oid baseCreationNamespace = InvalidOid
 
static bool baseTempCreationPending = false
 
static Oid namespaceUser = InvalidOid
 
static bool baseSearchPathValid = true
 
static ListoverrideStack = NIL
 
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:
2 * sizeof(Oid))
unsigned int Oid
Definition: postgres_ext.h:31
#define MAXALIGN(LEN)
Definition: c.h:685
#define offsetof(type, field)
Definition: c.h:655

Referenced by OpernameGetCandidates().

Function Documentation

◆ AccessTempTableNamespace()

static void AccessTempTableNamespace ( bool  force)
static

Definition at line 3841 of file namespace.c.

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

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

3842 {
3843  /*
3844  * Make note that this temporary namespace has been accessed in this
3845  * transaction.
3846  */
3848 
3849  /*
3850  * If the caller attempting to access a temporary schema expects the
3851  * creation of the namespace to be pending and should be enforced, then go
3852  * through the creation.
3853  */
3854  if (!force && OidIsValid(myTempNamespace))
3855  return;
3856 
3857  /*
3858  * The temporary tablespace does not exist yet and is wanted, so
3859  * initialize it.
3860  */
3862 }
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:638
int MyXactFlags
Definition: xact.c:119
static void InitTempTableNamespace(void)
Definition: namespace.c:3869
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition: xact.h:97

◆ assign_search_path()

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

Definition at line 4218 of file namespace.c.

References baseSearchPathValid.

4219 {
4220  /*
4221  * We mark the path as needing recomputation, but don't do anything until
4222  * it's needed. This avoids trying to do database access during GUC
4223  * initialization, or outside a transaction.
4224  */
4225  baseSearchPathValid = false;
4226 }
static bool baseSearchPathValid
Definition: namespace.c:152

◆ AtEOSubXact_Namespace()

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

Definition at line 4056 of file namespace.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

4058 {
4059  OverrideStackEntry *entry;
4060 
4061  if (myTempNamespaceSubID == mySubid)
4062  {
4063  if (isCommit)
4064  myTempNamespaceSubID = parentSubid;
4065  else
4066  {
4068  /* TEMP namespace creation failed, so reset state */
4071  baseSearchPathValid = false; /* need to rebuild list */
4072 
4073  /*
4074  * Reset the temporary namespace flag in MyProc. We assume that
4075  * this operation is atomic.
4076  *
4077  * Because this subtransaction is aborting, the pg_namespace row
4078  * is not visible to anyone else anyway, but that doesn't matter:
4079  * it's not a problem if objects contained in this namespace are
4080  * removed concurrently.
4081  */
4083  }
4084  }
4085 
4086  /*
4087  * Clean up if someone failed to do PopOverrideSearchPath
4088  */
4089  while (overrideStack)
4090  {
4093  break;
4094  if (isCommit)
4095  elog(WARNING, "leaked override search path");
4097  list_free(entry->searchPath);
4098  pfree(entry);
4099  }
4100 
4101  /* Activate the next level down. */
4102  if (overrideStack)
4103  {
4105  activeSearchPath = entry->searchPath;
4107  activeTempCreationPending = false; /* XXX is this OK? */
4108  }
4109  else
4110  {
4111  /* If not baseSearchPathValid, this is useless but harmless */
4115  }
4116 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid tempNamespaceId
Definition: proc.h:117
PGPROC * MyProc
Definition: proc.c:68
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
static List * overrideStack
Definition: namespace.c:163
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:1031
#define linitial(l)
Definition: pg_list.h:195
static bool baseTempCreationPending
Definition: namespace.c:147
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:143
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:842
#define InvalidSubTransactionId
Definition: c.h:513
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1330
#define elog(elevel,...)
Definition: elog.h:226
List * list_delete_first(List *list)
Definition: list.c:866

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 3990 of file namespace.c.

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

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

3991 {
3992  /*
3993  * If we abort the transaction in which a temp namespace was selected,
3994  * we'll have to do any creation or cleanout work over again. So, just
3995  * forget the namespace entirely until next time. On the other hand, if
3996  * we commit then register an exit callback to clean out the temp tables
3997  * at backend shutdown. (We only want to register the callback once per
3998  * session, so this is a good place to do it.)
3999  */
4000  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
4001  {
4002  if (isCommit)
4004  else
4005  {
4008  baseSearchPathValid = false; /* need to rebuild list */
4009 
4010  /*
4011  * Reset the temporary namespace flag in MyProc. We assume that
4012  * this operation is atomic.
4013  *
4014  * Because this transaction is aborting, the pg_namespace row is
4015  * not visible to anyone else anyway, but that doesn't matter:
4016  * it's not a problem if objects contained in this namespace are
4017  * removed concurrently.
4018  */
4020  }
4022  }
4023 
4024  /*
4025  * Clean up if someone failed to do PopOverrideSearchPath
4026  */
4027  if (overrideStack)
4028  {
4029  if (isCommit)
4030  elog(WARNING, "leaked override search path");
4031  while (overrideStack)
4032  {
4033  OverrideStackEntry *entry;
4034 
4037  list_free(entry->searchPath);
4038  pfree(entry);
4039  }
4040  /* If not baseSearchPathValid, this is useless but harmless */
4044  }
4045 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid tempNamespaceId
Definition: proc.h:117
PGPROC * MyProc
Definition: proc.c:68
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
static List * overrideStack
Definition: namespace.c:163
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:1031
#define linitial(l)
Definition: pg_list.h:195
static bool baseTempCreationPending
Definition: namespace.c:147
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:143
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidSubTransactionId
Definition: c.h:513
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1330
#define elog(elevel,...)
Definition: elog.h:226
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4153
List * list_delete_first(List *list)
Definition: list.c:866

◆ check_search_path()

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

Definition at line 4184 of file namespace.c.

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

4185 {
4186  char *rawname;
4187  List *namelist;
4188 
4189  /* Need a modifiable copy of string */
4190  rawname = pstrdup(*newval);
4191 
4192  /* Parse string into list of identifiers */
4193  if (!SplitIdentifierString(rawname, ',', &namelist))
4194  {
4195  /* syntax error in name list */
4196  GUC_check_errdetail("List syntax is invalid.");
4197  pfree(rawname);
4198  list_free(namelist);
4199  return false;
4200  }
4201 
4202  /*
4203  * We used to try to check that the named schemas exist, but there are
4204  * many valid use-cases for having search_path settings that include
4205  * schemas that don't exist; and often, we are not inside a transaction
4206  * here and so can't consult the system catalogs anyway. So now, the only
4207  * requirement is syntactic validity of the identifier list.
4208  */
4209 
4210  pfree(rawname);
4211  list_free(namelist);
4212 
4213  return true;
4214 }
#define GUC_check_errdetail
Definition: guc.h:415
char * pstrdup(const char *in)
Definition: mcxt.c:1161
void pfree(void *pointer)
Definition: mcxt.c:1031
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3669
#define newval
void list_free(List *list)
Definition: list.c:1330
Definition: pg_list.h:50

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2946 of file namespace.c.

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

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

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

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 1993 of file namespace.c.

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

Referenced by CollationIsVisible().

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

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2027 of file namespace.c.

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

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

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

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2078 of file namespace.c.

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

Referenced by ConversionIsVisible().

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

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2110 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_conversion_is_visible().

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

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3375 of file namespace.c.

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

Referenced by CopyCachedPlan().

3376 {
3377  OverrideSearchPath *result;
3378 
3379  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3380  result->schemas = list_copy(path->schemas);
3381  result->addCatalog = path->addCatalog;
3382  result->addTemp = path->addTemp;
3383 
3384  return result;
3385 }
List * list_copy(const List *oldlist)
Definition: list.c:1357
void * palloc(Size size)
Definition: mcxt.c:924

◆ DeconstructQualifiedName()

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

Definition at line 2788 of file namespace.c.

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

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

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4292 of file namespace.c.

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

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

4293 {
4294  List *result;
4295 
4297 
4298  /*
4299  * If the temp namespace should be first, force it to exist. This is so
4300  * that callers can trust the result to reflect the actual default
4301  * creation namespace. It's a bit bogus to do this here, since
4302  * current_schema() is supposedly a stable function without side-effects,
4303  * but the alternatives seem worse.
4304  */
4306  {
4309  }
4310 
4311  result = list_copy(activeSearchPath);
4312  if (!includeImplicit)
4313  {
4314  while (result && linitial_oid(result) != activeCreationNamespace)
4315  result = list_delete_first(result);
4316  }
4317 
4318  return result;
4319 }
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3841
List * list_copy(const List *oldlist)
Definition: list.c:1357
static void recomputeNamespacePath(void)
Definition: namespace.c:3687
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool activeTempCreationPending
Definition: namespace.c:139
#define linitial_oid(l)
Definition: pg_list.h:197
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:866

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4332 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4333 {
4334  int count = 0;
4335  ListCell *l;
4336 
4338 
4339  foreach(l, activeSearchPath)
4340  {
4341  Oid namespaceId = lfirst_oid(l);
4342 
4343  if (namespaceId == myTempNamespace)
4344  continue; /* do not include temp namespace */
4345 
4346  if (count < sarray_len)
4347  sarray[count] = namespaceId;
4348  count++;
4349  }
4350 
4351  return count;
4352 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3687
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3660 of file namespace.c.

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

Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().

3661 {
3662  Oid proc;
3663  ListCell *l;
3664 
3666 
3667  foreach(l, activeSearchPath)
3668  {
3669  Oid namespaceId = lfirst_oid(l);
3670 
3671  if (namespaceId == myTempNamespace)
3672  continue; /* do not look in temp namespace */
3673 
3674  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3675  if (OidIsValid(proc))
3676  return proc;
3677  }
3678 
3679  /* Not found in path */
3680  return InvalidOid;
3681 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3687
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ FuncnameGetCandidates()

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

Definition at line 921 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1392 of file namespace.c.

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

Referenced by format_procedure_internal(), and pg_function_is_visible().

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

◆ get_collation_oid()

Oid get_collation_oid ( List name,
bool  missing_ok 
)

Definition at line 3551 of file namespace.c.

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

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

3552 {
3553  char *schemaname;
3554  char *collation_name;
3555  int32 dbencoding = GetDatabaseEncoding();
3556  Oid namespaceId;
3557  Oid colloid;
3558  ListCell *l;
3559 
3560  /* deconstruct the name list */
3561  DeconstructQualifiedName(name, &schemaname, &collation_name);
3562 
3563  if (schemaname)
3564  {
3565  /* use exact schema given */
3566  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3567  if (missing_ok && !OidIsValid(namespaceId))
3568  return InvalidOid;
3569 
3570  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3571  if (OidIsValid(colloid))
3572  return colloid;
3573  }
3574  else
3575  {
3576  /* search for it in search path */
3578 
3579  foreach(l, activeSearchPath)
3580  {
3581  namespaceId = lfirst_oid(l);
3582 
3583  if (namespaceId == myTempNamespace)
3584  continue; /* do not look in temp namespace */
3585 
3586  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3587  if (OidIsValid(colloid))
3588  return colloid;
3589  }
3590  }
3591 
3592  /* Not found in path */
3593  if (!missing_ok)
3594  ereport(ERROR,
3595  (errcode(ERRCODE_UNDEFINED_OBJECT),
3596  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3598  return InvalidOid;
3599 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
signed int int32
Definition: c.h:346
static void recomputeNamespacePath(void)
Definition: namespace.c:3687
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1942
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
char * NameListToString(List *names)
Definition: namespace.c:3081
int GetDatabaseEncoding(void)
Definition: mbutils.c:996
#define InvalidOid
Definition: postgres_ext.h:36
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1002
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ get_conversion_oid()

Oid get_conversion_oid ( List name,
bool  missing_ok 
)

Definition at line 3605 of file namespace.c.

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

Referenced by get_object_address().

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

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

Definition at line 3022 of file namespace.c.

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

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

3023 {
3024  Oid oid;
3025 
3026  oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid,
3027  CStringGetDatum(nspname));
3028  if (!OidIsValid(oid) && !missing_ok)
3029  ereport(ERROR,
3030  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3031  errmsg("schema \"%s\" does not exist", nspname)));
3032 
3033  return oid;
3034 }
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:192
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2157 of file namespace.c.

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

Referenced by get_object_address().

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

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2658 of file namespace.c.

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

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

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

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2405 of file namespace.c.

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

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

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

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2279 of file namespace.c.

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

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

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

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2532 of file namespace.c.

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

Referenced by DefineTSDictionary(), and get_object_address().

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

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3339 of file namespace.c.

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

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

3340 {
3341  OverrideSearchPath *result;
3342  List *schemas;
3343  MemoryContext oldcxt;
3344 
3346 
3347  oldcxt = MemoryContextSwitchTo(context);
3348 
3349  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3350  schemas = list_copy(activeSearchPath);
3351  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3352  {
3353  if (linitial_oid(schemas) == myTempNamespace)
3354  result->addTemp = true;
3355  else
3356  {
3357  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3358  result->addCatalog = true;
3359  }
3360  schemas = list_delete_first(schemas);
3361  }
3362  result->schemas = schemas;
3363 
3364  MemoryContextSwitchTo(oldcxt);
3365 
3366  return result;
3367 }
static Oid myTempNamespace
Definition: namespace.c:180
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * list_copy(const List *oldlist)
Definition: list.c:1357
static void recomputeNamespacePath(void)
Definition: namespace.c:3687
static Oid activeCreationNamespace
Definition: namespace.c:136
void * palloc0(Size size)
Definition: mcxt.c:955
#define Assert(condition)
Definition: c.h:732
#define linitial_oid(l)
Definition: pg_list.h:197
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:866

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3253 of file namespace.c.

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

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

3254 {
3255  int result;
3256  char *nspname;
3257 
3258  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3259  nspname = get_namespace_name(namespaceId);
3260  if (!nspname)
3261  return InvalidBackendId; /* no such namespace? */
3262  if (strncmp(nspname, "pg_temp_", 8) == 0)
3263  result = atoi(nspname + 8);
3264  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3265  result = atoi(nspname + 14);
3266  else
3267  result = InvalidBackendId;
3268  pfree(nspname);
3269  return result;
3270 }
void pfree(void *pointer)
Definition: mcxt.c:1031
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
#define InvalidBackendId
Definition: backendid.h:23

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3292 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3293 {
3294  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3295  *tempNamespaceId = myTempNamespace;
3296  *tempToastNamespaceId = myTempToastNamespace;
3297 }
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3278 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

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

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4234 of file namespace.c.

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

Referenced by InitPostgres().

4235 {
4237  {
4238  /*
4239  * In bootstrap mode, the search path must be 'pg_catalog' so that
4240  * tables are created in the proper namespace; ignore the GUC setting.
4241  */
4242  MemoryContext oldcxt;
4243 
4245  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4246  MemoryContextSwitchTo(oldcxt);
4247  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4248  baseTempCreationPending = false;
4249  baseSearchPathValid = true;
4254  }
4255  else
4256  {
4257  /*
4258  * In normal mode, arrange for a callback on any syscache invalidation
4259  * of pg_namespace rows.
4260  */
4263  (Datum) 0);
4264  /* Force search path to be recomputed on next use */
4265  baseSearchPathValid = false;
4266  }
4267 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid GetUserId(void)
Definition: miscinit.c:380
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static Oid namespaceUser
Definition: namespace.c:149
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool baseTempCreationPending
Definition: namespace.c:147
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4274
static bool activeTempCreationPending
Definition: namespace.c:139
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static Oid baseCreationNamespace
Definition: namespace.c:145
static List * baseSearchPath
Definition: namespace.c:143
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1426
uintptr_t Datum
Definition: postgres.h:367
#define list_make1_oid(x1)
Definition: pg_list.h:249
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374
static List * activeSearchPath
Definition: namespace.c:133

◆ InitTempTableNamespace()

static void InitTempTableNamespace ( void  )
static

Definition at line 3869 of file namespace.c.

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

Referenced by AccessTempTableNamespace().

3870 {
3871  char namespaceName[NAMEDATALEN];
3872  Oid namespaceId;
3873  Oid toastspaceId;
3874 
3876 
3877  /*
3878  * First, do permission check to see if we are authorized to make temp
3879  * tables. We use a nonstandard error message here since "databasename:
3880  * permission denied" might be a tad cryptic.
3881  *
3882  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
3883  * that's necessary since current user ID could change during the session.
3884  * But there's no need to make the namespace in the first place until a
3885  * temp table creation request is made by someone with appropriate rights.
3886  */
3889  ereport(ERROR,
3890  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3891  errmsg("permission denied to create temporary tables in database \"%s\"",
3893 
3894  /*
3895  * Do not allow a Hot Standby session to make temp tables. Aside from
3896  * problems with modifying the system catalogs, there is a naming
3897  * conflict: pg_temp_N belongs to the session with BackendId N on the
3898  * master, not to a hot standby session with the same BackendId. We
3899  * should not be able to get here anyway due to XactReadOnly checks, but
3900  * let's just make real sure. Note that this also backstops various
3901  * operations that allow XactReadOnly transactions to modify temp tables;
3902  * they'd need RecoveryInProgress checks if not for this.
3903  */
3904  if (RecoveryInProgress())
3905  ereport(ERROR,
3906  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3907  errmsg("cannot create temporary tables during recovery")));
3908 
3909  /* Parallel workers can't create temporary tables, either. */
3910  if (IsParallelWorker())
3911  ereport(ERROR,
3912  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3913  errmsg("cannot create temporary tables during a parallel operation")));
3914 
3915  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
3916 
3917  namespaceId = get_namespace_oid(namespaceName, true);
3918  if (!OidIsValid(namespaceId))
3919  {
3920  /*
3921  * First use of this temp namespace in this database; create it. The
3922  * temp namespaces are always owned by the superuser. We leave their
3923  * permissions at default --- i.e., no access except to superuser ---
3924  * to ensure that unprivileged users can't peek at other backends'
3925  * temp tables. This works because the places that access the temp
3926  * namespace for my own backend skip permissions checks on it.
3927  */
3928  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3929  true);
3930  /* Advance command counter to make namespace visible */
3932  }
3933  else
3934  {
3935  /*
3936  * If the namespace already exists, clean it out (in case the former
3937  * owner crashed without doing so).
3938  */
3939  RemoveTempRelations(namespaceId);
3940  }
3941 
3942  /*
3943  * If the corresponding toast-table namespace doesn't exist yet, create
3944  * it. (We assume there is no need to clean it out if it does exist, since
3945  * dropping a parent table should make its toast table go away.)
3946  */
3947  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
3948  MyBackendId);
3949 
3950  toastspaceId = get_namespace_oid(namespaceName, true);
3951  if (!OidIsValid(toastspaceId))
3952  {
3953  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3954  true);
3955  /* Advance command counter to make namespace visible */
3957  }
3958 
3959  /*
3960  * Okay, we've prepared the temp namespace ... but it's not committed yet,
3961  * so all our work could be undone by transaction rollback. Set flag for
3962  * AtEOXact_Namespace to know what to do.
3963  */
3964  myTempNamespace = namespaceId;
3965  myTempToastNamespace = toastspaceId;
3966 
3967  /*
3968  * Mark MyProc as owning this namespace which other processes can use to
3969  * decide if a temporary namespace is in use or not. We assume that
3970  * assignment of namespaceId is an atomic operation. Even if it is not,
3971  * the temporary relation which resulted in the creation of this temporary
3972  * namespace is still locked until the current transaction commits, and
3973  * its pg_namespace row is not visible yet. However it does not matter:
3974  * this flag makes the namespace as being in use, so no objects created on
3975  * it would be removed concurrently.
3976  */
3977  MyProc->tempNamespaceId = namespaceId;
3978 
3979  /* It should not be done already. */
3982 
3983  baseSearchPathValid = false; /* need to rebuild list */
3984 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3022
BackendId MyBackendId
Definition: globals.c:81
#define AssertState(condition)
Definition: c.h:735
Oid GetUserId(void)
Definition: miscinit.c:380
Oid tempNamespaceId
Definition: proc.h:117
PGPROC * MyProc
Definition: proc.c:68
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:7895
#define OidIsValid(objectId)
Definition: c.h:638
#define NAMEDATALEN
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2078
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
#define ereport(elevel, rest)
Definition: elog.h:141
#define IsParallelWorker()
Definition: parallel.h:60
void CommandCounterIncrement(void)
Definition: xact.c:1003
Oid MyDatabaseId
Definition: globals.c:85
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4643
#define Assert(condition)
Definition: c.h:732
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4127
#define InvalidSubTransactionId
Definition: c.h:513
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define ACL_CREATE_TEMP
Definition: parsenodes.h:85
#define snprintf
Definition: port.h:192
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
Definition: pg_namespace.c:43

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3174 of file namespace.c.

References get_namespace_name(), and pfree().

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

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

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3197 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

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

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3136 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

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

◆ isTempNamespaceInUse()

bool isTempNamespaceInUse ( Oid  namespaceId)

Definition at line 3216 of file namespace.c.

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

Referenced by do_autovacuum().

3217 {
3218  PGPROC *proc;
3219  int backendId;
3220 
3222 
3223  backendId = GetTempNamespaceBackendId(namespaceId);
3224 
3225  if (backendId == InvalidBackendId ||
3226  backendId == MyBackendId)
3227  return false;
3228 
3229  /* Is the backend alive? */
3230  proc = BackendIdGetProc(backendId);
3231  if (proc == NULL)
3232  return false;
3233 
3234  /* Is the backend connected to the same database we are looking at? */
3235  if (proc->databaseId != MyDatabaseId)
3236  return false;
3237 
3238  /* Does the backend own the temporary namespace? */
3239  if (proc->tempNamespaceId != namespaceId)
3240  return false;
3241 
3242  /* all good to go */
3243  return true;
3244 }
BackendId MyBackendId
Definition: globals.c:81
Oid tempNamespaceId
Definition: proc.h:117
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3253
#define OidIsValid(objectId)
Definition: c.h:638
Oid databaseId
Definition: proc.h:114
#define InvalidBackendId
Definition: backendid.h:23
Oid MyDatabaseId
Definition: globals.c:85
#define Assert(condition)
Definition: c.h:732
Definition: proc.h:95
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:377

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3160 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

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

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3148 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

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

◆ lookup_collation()

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

Definition at line 1942 of file namespace.c.

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

Referenced by CollationGetCollid(), and get_collation_oid().

1943 {
1944  Oid collid;
1945  HeapTuple colltup;
1946  Form_pg_collation collform;
1947 
1948  /* Check for encoding-specific entry (exact match) */
1949  collid = GetSysCacheOid3(COLLNAMEENCNSP, Anum_pg_collation_oid,
1950  PointerGetDatum(collname),
1952  ObjectIdGetDatum(collnamespace));
1953  if (OidIsValid(collid))
1954  return collid;
1955 
1956  /*
1957  * Check for any-encoding entry. This takes a bit more work: while libc
1958  * collations with collencoding = -1 do work with all encodings, ICU
1959  * collations only work with certain encodings, so we have to check that
1960  * aspect before deciding it's a match.
1961  */
1962  colltup = SearchSysCache3(COLLNAMEENCNSP,
1963  PointerGetDatum(collname),
1964  Int32GetDatum(-1),
1965  ObjectIdGetDatum(collnamespace));
1966  if (!HeapTupleIsValid(colltup))
1967  return InvalidOid;
1968  collform = (Form_pg_collation) GETSTRUCT(colltup);
1969  if (collform->collprovider == COLLPROVIDER_ICU)
1970  {
1972  collid = collform->oid;
1973  else
1974  collid = InvalidOid;
1975  }
1976  else
1977  {
1978  collid = collform->oid;
1979  }
1980  ReleaseSysCache(colltup);
1981  return collid;
1982 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define PointerGetDatum(X)
Definition: postgres.h:556
bool is_encoding_supported_by_icu(int encoding)
Definition: encnames.c:455
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:196
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:1146
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int32 encoding
Definition: pg_database.h:41
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:51
#define Int32GetDatum(X)
Definition: postgres.h:479

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2915 of file namespace.c.

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

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

2916 {
2917  Oid namespaceId;
2918  AclResult aclresult;
2919 
2920  /* check for pg_temp alias */
2921  if (strcmp(nspname, "pg_temp") == 0)
2922  {
2923  /* Initialize temp namespace */
2924  AccessTempTableNamespace(false);
2925  return myTempNamespace;
2926  }
2927 
2928  namespaceId = get_namespace_oid(nspname, false);
2929 
2930  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2931  if (aclresult != ACLCHECK_OK)
2932  aclcheck_error(aclresult, OBJECT_SCHEMA,
2933  nspname);
2934 
2935  return namespaceId;
2936 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3022
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3841
Oid GetUserId(void)
Definition: miscinit.c:380
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4693
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
#define ACL_CREATE
Definition: parsenodes.h:84
AclResult
Definition: acl.h:178

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2872 of file namespace.c.

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

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

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

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2842 of file namespace.c.

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

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

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

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 3041 of file namespace.c.

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

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

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

◆ MatchNamedCall()

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

Definition at line 1284 of file namespace.c.

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().

1286 {
1287  Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
1288  int pronargs = procform->pronargs;
1289  int numposargs = nargs - list_length(argnames);
1290  int pronallargs;
1291  Oid *p_argtypes;
1292  char **p_argnames;
1293  char *p_argmodes;
1294  bool arggiven[FUNC_MAX_ARGS];
1295  bool isnull;
1296  int ap; /* call args position */
1297  int pp; /* proargs position */
1298  ListCell *lc;
1299 
1300  Assert(argnames != NIL);
1301  Assert(numposargs >= 0);
1302  Assert(nargs <= pronargs);
1303 
1304  /* Ignore this function if its proargnames is null */
1305  (void) SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proargnames,
1306  &isnull);
1307  if (isnull)
1308  return false;
1309 
1310  /* OK, let's extract the argument names and types */
1311  pronallargs = get_func_arg_info(proctup,
1312  &p_argtypes, &p_argnames, &p_argmodes);
1313  Assert(p_argnames != NULL);
1314 
1315  /* initialize state for matching */
1316  *argnumbers = (int *) palloc(pronargs * sizeof(int));
1317  memset(arggiven, false, pronargs * sizeof(bool));
1318 
1319  /* there are numposargs positional args before the named args */
1320  for (ap = 0; ap < numposargs; ap++)
1321  {
1322  (*argnumbers)[ap] = ap;
1323  arggiven[ap] = true;
1324  }
1325 
1326  /* now examine the named args */
1327  foreach(lc, argnames)
1328  {
1329  char *argname = (char *) lfirst(lc);
1330  bool found;
1331  int i;
1332 
1333  pp = 0;
1334  found = false;
1335  for (i = 0; i < pronallargs; i++)
1336  {
1337  /* consider only input parameters */
1338  if (p_argmodes &&
1339  (p_argmodes[i] != FUNC_PARAM_IN &&
1340  p_argmodes[i] != FUNC_PARAM_INOUT &&
1341  p_argmodes[i] != FUNC_PARAM_VARIADIC))
1342  continue;
1343  if (p_argnames[i] && strcmp(p_argnames[i], argname) == 0)
1344  {
1345  /* fail if argname matches a positional argument */
1346  if (arggiven[pp])
1347  return false;
1348  arggiven[pp] = true;
1349  (*argnumbers)[ap] = pp;
1350  found = true;
1351  break;
1352  }
1353  /* increase pp only for input parameters */
1354  pp++;
1355  }
1356  /* if name isn't in proargnames, fail */
1357  if (!found)
1358  return false;
1359  ap++;
1360  }
1361 
1362  Assert(ap == nargs); /* processed all actual parameters */
1363 
1364  /* Check for default arguments */
1365  if (nargs < pronargs)
1366  {
1367  int first_arg_with_default = pronargs - procform->pronargdefaults;
1368 
1369  for (pp = numposargs; pp < pronargs; pp++)
1370  {
1371  if (arggiven[pp])
1372  continue;
1373  /* fail if arg not given and no default available */
1374  if (pp < first_arg_with_default)
1375  return false;
1376  (*argnumbers)[ap++] = pp;
1377  }
1378  }
1379 
1380  Assert(ap == pronargs); /* processed all function parameters */
1381 
1382  return true;
1383 }
#define NIL
Definition: pg_list.h:65
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition: funcapi.c:831
int16 pronargs
Definition: pg_proc.h:82
unsigned int Oid
Definition: postgres_ext.h:31
#define FUNC_MAX_ARGS
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1385
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:134
#define Assert(condition)
Definition: c.h:732
#define lfirst(lc)
Definition: pg_list.h:190
static int list_length(const List *l)
Definition: pg_list.h:169
void * palloc(Size size)
Definition: mcxt.c:924
int i

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3115 of file namespace.c.

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

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

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3081 of file namespace.c.

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

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

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

◆ NamespaceCallback()

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

Definition at line 4274 of file namespace.c.

References baseSearchPathValid.

Referenced by InitializeSearchPath().

4275 {
4276  /* Force search path to be recomputed on next use */
4277  baseSearchPathValid = false;
4278 }
static bool baseSearchPathValid
Definition: namespace.c:152

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1812 of file namespace.c.

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

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

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

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1779 of file namespace.c.

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

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

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

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1726 of file namespace.c.

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

Referenced by format_operator_internal(), and pg_operator_is_visible().

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

◆ OpernameGetCandidates()

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

Definition at line 1566 of file namespace.c.

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

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

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

◆ OpernameGetOprid()

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

Definition at line 1463 of file namespace.c.

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

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

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

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1895 of file namespace.c.

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

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

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1862 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

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

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3391 of file namespace.c.

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

Referenced by RevalidateCachedQuery().

3392 {
3393  ListCell *lc,
3394  *lcp;
3395 
3397 
3398  /* We scan down the activeSearchPath to see if it matches the input. */
3400 
3401  /* If path->addTemp, first item should be my temp namespace. */
3402  if (path->addTemp)
3403  {
3404  if (lc && lfirst_oid(lc) == myTempNamespace)
3405  lc = lnext(activeSearchPath, lc);
3406  else
3407  return false;
3408  }
3409  /* If path->addCatalog, next item should be pg_catalog. */
3410  if (path->addCatalog)
3411  {
3412  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3413  lc = lnext(activeSearchPath, lc);
3414  else
3415  return false;
3416  }
3417  /* We should now be looking at the activeCreationNamespace. */
3418  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3419  return false;
3420  /* The remainder of activeSearchPath should match path->schemas. */
3421  foreach(lcp, path->schemas)
3422  {
3423  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3424  lc = lnext(activeSearchPath, lc);
3425  else
3426  return false;
3427  }
3428  if (lc)
3429  return false;
3430  return true;
3431 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
static Oid myTempNamespace
Definition: namespace.c:180
static void recomputeNamespacePath(void)
Definition: namespace.c:3687
static Oid activeCreationNamespace
Definition: namespace.c:136
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ pg_collation_is_visible()

Datum pg_collation_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4435 of file namespace.c.

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

4436 {
4437  Oid oid = PG_GETARG_OID(0);
4438 
4440  PG_RETURN_NULL();
4441 
4443 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
bool CollationIsVisible(Oid collid)
Definition: namespace.c:2027
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_conversion_is_visible()

Datum pg_conversion_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4446 of file namespace.c.

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

4447 {
4448  Oid oid = PG_GETARG_OID(0);
4449 
4451  PG_RETURN_NULL();
4452 
4454 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
bool ConversionIsVisible(Oid conid)
Definition: namespace.c:2110
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_function_is_visible()

Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4391 of file namespace.c.

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

4392 {
4393  Oid oid = PG_GETARG_OID(0);
4394 
4396  PG_RETURN_NULL();
4397 
4399 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1392
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_is_other_temp_schema()

Datum pg_is_other_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4518 of file namespace.c.

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

4519 {
4520  Oid oid = PG_GETARG_OID(0);
4521 
4523 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
bool isOtherTempNamespace(Oid namespaceId)
Definition: namespace.c:3197

◆ pg_my_temp_schema()

Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4512 of file namespace.c.

References myTempNamespace, and PG_RETURN_OID.

4513 {
4515 }
static Oid myTempNamespace
Definition: namespace.c:180
#define PG_RETURN_OID(x)
Definition: fmgr.h:350

◆ pg_opclass_is_visible()

Datum pg_opclass_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4413 of file namespace.c.

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

4414 {
4415  Oid oid = PG_GETARG_OID(0);
4416 
4418  PG_RETURN_NULL();
4419 
4421 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
bool OpclassIsVisible(Oid opcid)
Definition: namespace.c:1812
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_operator_is_visible()

Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4402 of file namespace.c.

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

4403 {
4404  Oid oid = PG_GETARG_OID(0);
4405 
4407  PG_RETURN_NULL();
4408 
4410 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1726
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_opfamily_is_visible()

Datum pg_opfamily_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4424 of file namespace.c.

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

4425 {
4426  Oid oid = PG_GETARG_OID(0);
4427 
4429  PG_RETURN_NULL();
4430 
4432 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
bool OpfamilyIsVisible(Oid opfid)
Definition: namespace.c:1895
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_statistics_obj_is_visible()

Datum pg_statistics_obj_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4457 of file namespace.c.

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

4458 {
4459  Oid oid = PG_GETARG_OID(0);
4460 
4462  PG_RETURN_NULL();
4463 
4465 }
bool StatisticsObjIsVisible(Oid relid)
Definition: namespace.c:2214
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_table_is_visible()

Datum pg_table_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4369 of file namespace.c.

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

4370 {
4371  Oid oid = PG_GETARG_OID(0);
4372 
4374  PG_RETURN_NULL();
4375 
4377 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
bool RelationIsVisible(Oid relid)
Definition: namespace.c:700
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_ts_config_is_visible()

Datum pg_ts_config_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4501 of file namespace.c.

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

4502 {
4503  Oid oid = PG_GETARG_OID(0);
4504 
4506  PG_RETURN_NULL();
4507 
4509 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2716
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_ts_dict_is_visible()

Datum pg_ts_dict_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4479 of file namespace.c.

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

4480 {
4481  Oid oid = PG_GETARG_OID(0);
4482 
4484  PG_RETURN_NULL();
4485 
4487 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2463
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_ts_parser_is_visible()

Datum pg_ts_parser_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4468 of file namespace.c.

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

4469 {
4470  Oid oid = PG_GETARG_OID(0);
4471 
4473  PG_RETURN_NULL();
4474 
4476 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
bool TSParserIsVisible(Oid prsId)
Definition: namespace.c:2337
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_ts_template_is_visible()

Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4490 of file namespace.c.

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

4491 {
4492  Oid oid = PG_GETARG_OID(0);
4493 
4495  PG_RETURN_NULL();
4496 
4498 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
bool TSTemplateIsVisible(Oid tmplId)
Definition: namespace.c:2590
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_type_is_visible()

Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4380 of file namespace.c.

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

4381 {
4382  Oid oid = PG_GETARG_OID(0);
4383 
4385  PG_RETURN_NULL();
4386 
4388 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
bool TypeIsVisible(Oid typid)
Definition: namespace.c:795
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3510 of file namespace.c.

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

Referenced by CreateSchemaCommand().

3511 {
3512  OverrideStackEntry *entry;
3513 
3514  /* Sanity checks. */
3515  if (overrideStack == NIL)
3516  elog(ERROR, "bogus PopOverrideSearchPath call");
3518  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3519  elog(ERROR, "bogus PopOverrideSearchPath call");
3520 
3521  /* Pop the stack and free storage. */
3523  list_free(entry->searchPath);
3524  pfree(entry);
3525 
3526  /* Activate the next level down. */
3527  if (overrideStack)
3528  {
3530  activeSearchPath = entry->searchPath;
3532  activeTempCreationPending = false; /* XXX is this OK? */
3533  }
3534  else
3535  {
3536  /* If not baseSearchPathValid, this is useless but harmless */
3540  }
3541 }
#define NIL
Definition: pg_list.h:65
static List * overrideStack
Definition: namespace.c:163
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:1031
#define linitial(l)
Definition: pg_list.h:195
#define ERROR
Definition: elog.h:43
static bool baseTempCreationPending
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
static List * baseSearchPath
Definition: namespace.c:143
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:842
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1330
#define elog(elevel,...)
Definition: elog.h:226
List * list_delete_first(List *list)
Definition: list.c:866

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3451 of file namespace.c.

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

Referenced by CreateSchemaCommand().

3452 {
3453  OverrideStackEntry *entry;
3454  List *oidlist;
3455  Oid firstNS;
3456  MemoryContext oldcxt;
3457 
3458  /*
3459  * Copy the list for safekeeping, and insert implicitly-searched
3460  * namespaces as needed. This code should track recomputeNamespacePath.
3461  */
3463 
3464  oidlist = list_copy(newpath->schemas);
3465 
3466  /*
3467  * Remember the first member of the explicit list.
3468  */
3469  if (oidlist == NIL)
3470  firstNS = InvalidOid;
3471  else
3472  firstNS = linitial_oid(oidlist);
3473 
3474  /*
3475  * Add any implicitly-searched namespaces to the list. Note these go on
3476  * the front, not the back; also notice that we do not check USAGE
3477  * permissions for these.
3478  */
3479  if (newpath->addCatalog)
3480  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3481 
3482  if (newpath->addTemp && OidIsValid(myTempNamespace))
3483  oidlist = lcons_oid(myTempNamespace, oidlist);
3484 
3485  /*
3486  * Build the new stack entry, then insert it at the head of the list.
3487  */
3488  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3489  entry->searchPath = oidlist;
3490  entry->creationNamespace = firstNS;
3492 
3493  overrideStack = lcons(entry, overrideStack);
3494 
3495  /* And make it active. */
3496  activeSearchPath = entry->searchPath;
3498  activeTempCreationPending = false; /* XXX is this OK? */
3499 
3500  MemoryContextSwitchTo(oldcxt);
3501 }
#define NIL
Definition: pg_list.h:65
static Oid myTempNamespace
Definition: namespace.c:180
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static List * overrideStack
Definition: namespace.c:163
List * list_copy(const List *oldlist)
Definition: list.c:1357
List * lcons_oid(Oid datum, List *list)
Definition: list.c:536
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool activeTempCreationPending
Definition: namespace.c:139
MemoryContext TopMemoryContext
Definition: mcxt.c:44
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:842
List * lcons(void *datum, List *list)
Definition: list.c:500
#define linitial_oid(l)
Definition: pg_list.h:197
static List * activeSearchPath
Definition: namespace.c:133
void * palloc(Size size)
Definition: mcxt.c:924
Definition: pg_list.h:50

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 2974 of file namespace.c.

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

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

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

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 633 of file namespace.c.

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

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 526 of file namespace.c.

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

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 441 of file namespace.c.

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

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

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

◆ RangeVarGetRelidExtended()

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

Definition at line 228 of file namespace.c.

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

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

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