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)
 
Oid TypenameGetTypidExtended (const char *typname, bool temp_ok)
 
bool TypeIsVisible (Oid typid)
 
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool missing_ok)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok)
 
bool OperatorIsVisible (Oid oprid)
 
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
 
bool OpclassIsVisible (Oid opcid)
 
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
 
bool OpfamilyIsVisible (Oid opfid)
 
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 3854 of file namespace.c.

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

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

3855 {
3856  /*
3857  * Make note that this temporary namespace has been accessed in this
3858  * transaction.
3859  */
3861 
3862  /*
3863  * If the caller attempting to access a temporary schema expects the
3864  * creation of the namespace to be pending and should be enforced, then go
3865  * through the creation.
3866  */
3867  if (!force && OidIsValid(myTempNamespace))
3868  return;
3869 
3870  /*
3871  * The temporary tablespace does not exist yet and is wanted, so
3872  * initialize it.
3873  */
3875 }
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:3882
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition: xact.h:97

◆ assign_search_path()

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

Definition at line 4231 of file namespace.c.

References baseSearchPathValid.

4232 {
4233  /*
4234  * We mark the path as needing recomputation, but don't do anything until
4235  * it's needed. This avoids trying to do database access during GUC
4236  * initialization, or outside a transaction.
4237  */
4238  baseSearchPathValid = false;
4239 }
static bool baseSearchPathValid
Definition: namespace.c:152

◆ AtEOSubXact_Namespace()

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

Definition at line 4069 of file namespace.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

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

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4003 of file namespace.c.

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

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

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

◆ check_search_path()

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

Definition at line 4197 of file namespace.c.

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

4198 {
4199  char *rawname;
4200  List *namelist;
4201 
4202  /* Need a modifiable copy of string */
4203  rawname = pstrdup(*newval);
4204 
4205  /* Parse string into list of identifiers */
4206  if (!SplitIdentifierString(rawname, ',', &namelist))
4207  {
4208  /* syntax error in name list */
4209  GUC_check_errdetail("List syntax is invalid.");
4210  pfree(rawname);
4211  list_free(namelist);
4212  return false;
4213  }
4214 
4215  /*
4216  * We used to try to check that the named schemas exist, but there are
4217  * many valid use-cases for having search_path settings that include
4218  * schemas that don't exist; and often, we are not inside a transaction
4219  * here and so can't consult the system catalogs anyway. So now, the only
4220  * requirement is syntactic validity of the identifier list.
4221  */
4222 
4223  pfree(rawname);
4224  list_free(namelist);
4225 
4226  return true;
4227 }
#define GUC_check_errdetail
Definition: guc.h:409
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:1373
Definition: pg_list.h:50

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2959 of file namespace.c.

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

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

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

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2006 of file namespace.c.

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

Referenced by CollationIsVisible().

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

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2040 of file namespace.c.

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

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

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

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2091 of file namespace.c.

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

Referenced by ConversionIsVisible().

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

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2123 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_conversion_is_visible().

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

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3388 of file namespace.c.

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

Referenced by CopyCachedPlan().

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

◆ DeconstructQualifiedName()

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

Definition at line 2801 of file namespace.c.

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

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

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4305 of file namespace.c.

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

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

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

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4345 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

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

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3673 of file namespace.c.

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

Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().

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

◆ FuncnameGetCandidates()

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

Definition at line 934 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1405 of file namespace.c.

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

Referenced by format_procedure_internal(), and pg_function_is_visible().

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

◆ get_collation_oid()

Oid get_collation_oid ( List name,
bool  missing_ok 
)

Definition at line 3564 of file namespace.c.

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

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

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

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

Referenced by get_object_address().

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

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

Definition at line 3035 of file namespace.c.

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

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

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

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2170 of file namespace.c.

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

Referenced by AlterStatistics(), and get_object_address().

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

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2671 of file namespace.c.

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

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

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

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2418 of file namespace.c.

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

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

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

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2292 of file namespace.c.

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

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

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

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2545 of file namespace.c.

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

Referenced by DefineTSDictionary(), and get_object_address().

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

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3352 of file namespace.c.

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

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

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

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3266 of file namespace.c.

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

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

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

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3305 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

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

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3291 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

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

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4247 of file namespace.c.

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

Referenced by InitPostgres().

4248 {
4250  {
4251  /*
4252  * In bootstrap mode, the search path must be 'pg_catalog' so that
4253  * tables are created in the proper namespace; ignore the GUC setting.
4254  */
4255  MemoryContext oldcxt;
4256 
4258  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4259  MemoryContextSwitchTo(oldcxt);
4260  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4261  baseTempCreationPending = false;
4262  baseSearchPathValid = true;
4267  }
4268  else
4269  {
4270  /*
4271  * In normal mode, arrange for a callback on any syscache invalidation
4272  * of pg_namespace rows.
4273  */
4276  (Datum) 0);
4277  /* Force search path to be recomputed on next use */
4278  baseSearchPathValid = false;
4279  }
4280 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid GetUserId(void)
Definition: miscinit.c:380
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static Oid namespaceUser
Definition: namespace.c:149
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool baseTempCreationPending
Definition: namespace.c:147
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4287
static bool activeTempCreationPending
Definition: namespace.c:139
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static Oid baseCreationNamespace
Definition: namespace.c:145
static List * baseSearchPath
Definition: namespace.c:143
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1426
uintptr_t Datum
Definition: postgres.h:367
#define list_make1_oid(x1)
Definition: pg_list.h:249
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374
static List * activeSearchPath
Definition: namespace.c:133

◆ InitTempTableNamespace()

static void InitTempTableNamespace ( void  )
static

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

3883 {
3884  char namespaceName[NAMEDATALEN];
3885  Oid namespaceId;
3886  Oid toastspaceId;
3887 
3889 
3890  /*
3891  * First, do permission check to see if we are authorized to make temp
3892  * tables. We use a nonstandard error message here since "databasename:
3893  * permission denied" might be a tad cryptic.
3894  *
3895  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
3896  * that's necessary since current user ID could change during the session.
3897  * But there's no need to make the namespace in the first place until a
3898  * temp table creation request is made by someone with appropriate rights.
3899  */
3902  ereport(ERROR,
3903  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3904  errmsg("permission denied to create temporary tables in database \"%s\"",
3906 
3907  /*
3908  * Do not allow a Hot Standby session to make temp tables. Aside from
3909  * problems with modifying the system catalogs, there is a naming
3910  * conflict: pg_temp_N belongs to the session with BackendId N on the
3911  * master, not to a hot standby session with the same BackendId. We
3912  * should not be able to get here anyway due to XactReadOnly checks, but
3913  * let's just make real sure. Note that this also backstops various
3914  * operations that allow XactReadOnly transactions to modify temp tables;
3915  * they'd need RecoveryInProgress checks if not for this.
3916  */
3917  if (RecoveryInProgress())
3918  ereport(ERROR,
3919  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3920  errmsg("cannot create temporary tables during recovery")));
3921 
3922  /* Parallel workers can't create temporary tables, either. */
3923  if (IsParallelWorker())
3924  ereport(ERROR,
3925  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3926  errmsg("cannot create temporary tables during a parallel operation")));
3927 
3928  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
3929 
3930  namespaceId = get_namespace_oid(namespaceName, true);
3931  if (!OidIsValid(namespaceId))
3932  {
3933  /*
3934  * First use of this temp namespace in this database; create it. The
3935  * temp namespaces are always owned by the superuser. We leave their
3936  * permissions at default --- i.e., no access except to superuser ---
3937  * to ensure that unprivileged users can't peek at other backends'
3938  * temp tables. This works because the places that access the temp
3939  * namespace for my own backend skip permissions checks on it.
3940  */
3941  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3942  true);
3943  /* Advance command counter to make namespace visible */
3945  }
3946  else
3947  {
3948  /*
3949  * If the namespace already exists, clean it out (in case the former
3950  * owner crashed without doing so).
3951  */
3952  RemoveTempRelations(namespaceId);
3953  }
3954 
3955  /*
3956  * If the corresponding toast-table namespace doesn't exist yet, create
3957  * it. (We assume there is no need to clean it out if it does exist, since
3958  * dropping a parent table should make its toast table go away.)
3959  */
3960  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
3961  MyBackendId);
3962 
3963  toastspaceId = get_namespace_oid(namespaceName, true);
3964  if (!OidIsValid(toastspaceId))
3965  {
3966  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3967  true);
3968  /* Advance command counter to make namespace visible */
3970  }
3971 
3972  /*
3973  * Okay, we've prepared the temp namespace ... but it's not committed yet,
3974  * so all our work could be undone by transaction rollback. Set flag for
3975  * AtEOXact_Namespace to know what to do.
3976  */
3977  myTempNamespace = namespaceId;
3978  myTempToastNamespace = toastspaceId;
3979 
3980  /*
3981  * Mark MyProc as owning this namespace which other processes can use to
3982  * decide if a temporary namespace is in use or not. We assume that
3983  * assignment of namespaceId is an atomic operation. Even if it is not,
3984  * the temporary relation which resulted in the creation of this temporary
3985  * namespace is still locked until the current transaction commits, and
3986  * its pg_namespace row is not visible yet. However it does not matter:
3987  * this flag makes the namespace as being in use, so no objects created on
3988  * it would be removed concurrently.
3989  */
3990  MyProc->tempNamespaceId = namespaceId;
3991 
3992  /* It should not be done already. */
3995 
3996  baseSearchPathValid = false; /* need to rebuild list */
3997 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3035
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:7898
#define OidIsValid(objectId)
Definition: c.h:638
#define NAMEDATALEN
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2099
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:4140
#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 3187 of file namespace.c.

References get_namespace_name(), and pfree().

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

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

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3210 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

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

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3149 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

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

◆ isTempNamespaceInUse()

bool isTempNamespaceInUse ( Oid  namespaceId)

Definition at line 3229 of file namespace.c.

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

Referenced by do_autovacuum().

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

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3173 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

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

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3161 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

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

◆ lookup_collation()

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

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

1956 {
1957  Oid collid;
1958  HeapTuple colltup;
1959  Form_pg_collation collform;
1960 
1961  /* Check for encoding-specific entry (exact match) */
1962  collid = GetSysCacheOid3(COLLNAMEENCNSP, Anum_pg_collation_oid,
1963  PointerGetDatum(collname),
1965  ObjectIdGetDatum(collnamespace));
1966  if (OidIsValid(collid))
1967  return collid;
1968 
1969  /*
1970  * Check for any-encoding entry. This takes a bit more work: while libc
1971  * collations with collencoding = -1 do work with all encodings, ICU
1972  * collations only work with certain encodings, so we have to check that
1973  * aspect before deciding it's a match.
1974  */
1975  colltup = SearchSysCache3(COLLNAMEENCNSP,
1976  PointerGetDatum(collname),
1977  Int32GetDatum(-1),
1978  ObjectIdGetDatum(collnamespace));
1979  if (!HeapTupleIsValid(colltup))
1980  return InvalidOid;
1981  collform = (Form_pg_collation) GETSTRUCT(colltup);
1982  if (collform->collprovider == COLLPROVIDER_ICU)
1983  {
1985  collid = collform->oid;
1986  else
1987  collid = InvalidOid;
1988  }
1989  else
1990  {
1991  collid = collform->oid;
1992  }
1993  ReleaseSysCache(colltup);
1994  return collid;
1995 }
#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 2928 of file namespace.c.

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

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

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

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2885 of file namespace.c.

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

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

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

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2855 of file namespace.c.

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

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

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

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 3054 of file namespace.c.

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

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

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

◆ MatchNamedCall()

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

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

1299 {
1300  Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
1301  int pronargs = procform->pronargs;
1302  int numposargs = nargs - list_length(argnames);
1303  int pronallargs;
1304  Oid *p_argtypes;
1305  char **p_argnames;
1306  char *p_argmodes;
1307  bool arggiven[FUNC_MAX_ARGS];
1308  bool isnull;
1309  int ap; /* call args position */
1310  int pp; /* proargs position */
1311  ListCell *lc;
1312 
1313  Assert(argnames != NIL);
1314  Assert(numposargs >= 0);
1315  Assert(nargs <= pronargs);
1316 
1317  /* Ignore this function if its proargnames is null */
1318  (void) SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proargnames,
1319  &isnull);
1320  if (isnull)
1321  return false;
1322 
1323  /* OK, let's extract the argument names and types */
1324  pronallargs = get_func_arg_info(proctup,
1325  &p_argtypes, &p_argnames, &p_argmodes);
1326  Assert(p_argnames != NULL);
1327 
1328  /* initialize state for matching */
1329  *argnumbers = (int *) palloc(pronargs * sizeof(int));
1330  memset(arggiven, false, pronargs * sizeof(bool));
1331 
1332  /* there are numposargs positional args before the named args */
1333  for (ap = 0; ap < numposargs; ap++)
1334  {
1335  (*argnumbers)[ap] = ap;
1336  arggiven[ap] = true;
1337  }
1338 
1339  /* now examine the named args */
1340  foreach(lc, argnames)
1341  {
1342  char *argname = (char *) lfirst(lc);
1343  bool found;
1344  int i;
1345 
1346  pp = 0;
1347  found = false;
1348  for (i = 0; i < pronallargs; i++)
1349  {
1350  /* consider only input parameters */
1351  if (p_argmodes &&
1352  (p_argmodes[i] != FUNC_PARAM_IN &&
1353  p_argmodes[i] != FUNC_PARAM_INOUT &&
1354  p_argmodes[i] != FUNC_PARAM_VARIADIC))
1355  continue;
1356  if (p_argnames[i] && strcmp(p_argnames[i], argname) == 0)
1357  {
1358  /* fail if argname matches a positional argument */
1359  if (arggiven[pp])
1360  return false;
1361  arggiven[pp] = true;
1362  (*argnumbers)[ap] = pp;
1363  found = true;
1364  break;
1365  }
1366  /* increase pp only for input parameters */
1367  pp++;
1368  }
1369  /* if name isn't in proargnames, fail */
1370  if (!found)
1371  return false;
1372  ap++;
1373  }
1374 
1375  Assert(ap == nargs); /* processed all actual parameters */
1376 
1377  /* Check for default arguments */
1378  if (nargs < pronargs)
1379  {
1380  int first_arg_with_default = pronargs - procform->pronargdefaults;
1381 
1382  for (pp = numposargs; pp < pronargs; pp++)
1383  {
1384  if (arggiven[pp])
1385  continue;
1386  /* fail if arg not given and no default available */
1387  if (pp < first_arg_with_default)
1388  return false;
1389  (*argnumbers)[ap++] = pp;
1390  }
1391  }
1392 
1393  Assert(ap == pronargs); /* processed all function parameters */
1394 
1395  return true;
1396 }
#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 3128 of file namespace.c.

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

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

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3094 of file namespace.c.

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

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

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

◆ NamespaceCallback()

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

Definition at line 4287 of file namespace.c.

References baseSearchPathValid.

Referenced by InitializeSearchPath().

4288 {
4289  /* Force search path to be recomputed on next use */
4290  baseSearchPathValid = false;
4291 }
static bool baseSearchPathValid
Definition: namespace.c:152

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1825 of file namespace.c.

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

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

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

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1792 of file namespace.c.

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

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

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

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1739 of file namespace.c.

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

Referenced by format_operator_internal(), and pg_operator_is_visible().

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

◆ OpernameGetCandidates()

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

Definition at line 1579 of file namespace.c.

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

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

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

◆ OpernameGetOprid()

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

Definition at line 1476 of file namespace.c.

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

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

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

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1908 of file namespace.c.

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

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

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1875 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

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

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3404 of file namespace.c.

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

Referenced by RevalidateCachedQuery().

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

◆ pg_collation_is_visible()

Datum pg_collation_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4448 of file namespace.c.

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

4449 {
4450  Oid oid = PG_GETARG_OID(0);
4451 
4453  PG_RETURN_NULL();
4454 
4456 }
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:2040
#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 4459 of file namespace.c.

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

4460 {
4461  Oid oid = PG_GETARG_OID(0);
4462 
4464  PG_RETURN_NULL();
4465 
4467 }
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:2123
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_function_is_visible()

Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4404 of file namespace.c.

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

4405 {
4406  Oid oid = PG_GETARG_OID(0);
4407 
4409  PG_RETURN_NULL();
4410 
4412 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1405
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 4531 of file namespace.c.

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

4532 {
4533  Oid oid = PG_GETARG_OID(0);
4534 
4536 }
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:3210

◆ pg_my_temp_schema()

Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4525 of file namespace.c.

References myTempNamespace, and PG_RETURN_OID.

4526 {
4528 }
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 4426 of file namespace.c.

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

4427 {
4428  Oid oid = PG_GETARG_OID(0);
4429 
4431  PG_RETURN_NULL();
4432 
4434 }
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:1825
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_operator_is_visible()

Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4415 of file namespace.c.

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

4416 {
4417  Oid oid = PG_GETARG_OID(0);
4418 
4420  PG_RETURN_NULL();
4421 
4423 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1739
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 4437 of file namespace.c.

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

4438 {
4439  Oid oid = PG_GETARG_OID(0);
4440 
4442  PG_RETURN_NULL();
4443 
4445 }
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:1908
#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 4470 of file namespace.c.

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

4471 {
4472  Oid oid = PG_GETARG_OID(0);
4473 
4475  PG_RETURN_NULL();
4476 
4478 }
bool StatisticsObjIsVisible(Oid relid)
Definition: namespace.c:2227
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 4382 of file namespace.c.

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

4383 {
4384  Oid oid = PG_GETARG_OID(0);
4385 
4387  PG_RETURN_NULL();
4388 
4390 }
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 4514 of file namespace.c.

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

4515 {
4516  Oid oid = PG_GETARG_OID(0);
4517 
4519  PG_RETURN_NULL();
4520 
4522 }
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:2729
#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 4492 of file namespace.c.

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

4493 {
4494  Oid oid = PG_GETARG_OID(0);
4495 
4497  PG_RETURN_NULL();
4498 
4500 }
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:2476
#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 4481 of file namespace.c.

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

4482 {
4483  Oid oid = PG_GETARG_OID(0);
4484 
4486  PG_RETURN_NULL();
4487 
4489 }
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:2350
#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 4503 of file namespace.c.

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

4504 {
4505  Oid oid = PG_GETARG_OID(0);
4506 
4508  PG_RETURN_NULL();
4509 
4511 }
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:2603
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ pg_type_is_visible()

Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4393 of file namespace.c.

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

4394 {
4395  Oid oid = PG_GETARG_OID(0);
4396 
4398  PG_RETURN_NULL();
4399 
4401 }
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:808
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3523 of file namespace.c.

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

Referenced by CreateSchemaCommand().

3524 {
3525  OverrideStackEntry *entry;
3526 
3527  /* Sanity checks. */
3528  if (overrideStack == NIL)
3529  elog(ERROR, "bogus PopOverrideSearchPath call");
3531  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3532  elog(ERROR, "bogus PopOverrideSearchPath call");
3533 
3534  /* Pop the stack and free storage. */
3536  list_free(entry->searchPath);
3537  pfree(entry);
3538 
3539  /* Activate the next level down. */
3540  if (overrideStack)
3541  {
3543  activeSearchPath = entry->searchPath;
3545  activeTempCreationPending = false; /* XXX is this OK? */
3546  }
3547  else
3548  {
3549  /* If not baseSearchPathValid, this is useless but harmless */
3553  }
3554 }
#define NIL
Definition: pg_list.h:65
static List * overrideStack
Definition: namespace.c:163
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:1031
#define linitial(l)
Definition: pg_list.h:195
#define ERROR
Definition: elog.h:43
static bool baseTempCreationPending
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
static List * baseSearchPath
Definition: namespace.c:143
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:842
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1373
#define elog(elevel,...)
Definition: elog.h:226
List * list_delete_first(List *list)
Definition: list.c:857

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3464 of file namespace.c.

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

Referenced by CreateSchemaCommand().

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

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 2987 of file namespace.c.

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

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

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

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 633 of file namespace.c.

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

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

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

◆ RangeVarGetAndCheckCreationNamespace()

Oid RangeVarGetAndCheckCreationNamespace ( RangeVar 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:2099
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3094
#define NoLock
Definition: lockdefs.h:34
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:963
#define ereport(elevel, rest)
Definition: elog.h:141
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:984
AclResult
Definition: acl.h:177
Oid MyDatabaseId
Definition: globals.c:85
uint64 SharedInvalidMessageCounter
Definition: sinval.c:26
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:732
bool pg_class_ownercheck(Oid class_oid, Oid roleid)
Definition: aclchk.c:4755
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374
int errmsg(const char *fmt,...)
Definition: elog.c:784
ObjectType get_relkind_objtype(char relkind)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:108
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:3035
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3854
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
static void recomputeNamespacePath(void)
Definition: namespace.c:3700
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
static Oid activeCreationNamespace
Definition: namespace.c:136
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2099
static bool activeTempCreationPending
Definition: namespace.c:139
#define ereport(elevel, rest)
Definition: elog.h:141
Oid MyDatabaseId
Definition: globals.c:85
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:784
char * catalogname
Definition: primnodes.h:66

◆ RangeVarGetRelidExtended()

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

Definition at line 228 of file namespace.c.

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

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

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