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)
 
TempNamespaceStatus checkTempNamespaceStatus (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 uint64 activePathGeneration = 1
 
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:691
#define offsetof(type, field)
Definition: c.h:661

Referenced by OpernameGetCandidates().

Function Documentation

◆ AccessTempTableNamespace()

static void AccessTempTableNamespace ( bool  force)
static

Definition at line 3915 of file namespace.c.

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

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

3916 {
3917  /*
3918  * Make note that this temporary namespace has been accessed in this
3919  * transaction.
3920  */
3922 
3923  /*
3924  * If the caller attempting to access a temporary schema expects the
3925  * creation of the namespace to be pending and should be enforced, then go
3926  * through the creation.
3927  */
3928  if (!force && OidIsValid(myTempNamespace))
3929  return;
3930 
3931  /*
3932  * The temporary tablespace does not exist yet and is wanted, so
3933  * initialize it.
3934  */
3936 }
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:644
int MyXactFlags
Definition: xact.c:119
static void InitTempTableNamespace(void)
Definition: namespace.c:3943
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition: xact.h:97

◆ assign_search_path()

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

Definition at line 4308 of file namespace.c.

References baseSearchPathValid.

4309 {
4310  /*
4311  * We mark the path as needing recomputation, but don't do anything until
4312  * it's needed. This avoids trying to do database access during GUC
4313  * initialization, or outside a transaction.
4314  */
4315  baseSearchPathValid = false;
4316 }
static bool baseSearchPathValid
Definition: namespace.c:160

◆ AtEOSubXact_Namespace()

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

Definition at line 4132 of file namespace.c.

References activeCreationNamespace, activePathGeneration, 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().

4134 {
4135  OverrideStackEntry *entry;
4136 
4137  if (myTempNamespaceSubID == mySubid)
4138  {
4139  if (isCommit)
4140  myTempNamespaceSubID = parentSubid;
4141  else
4142  {
4144  /* TEMP namespace creation failed, so reset state */
4147  baseSearchPathValid = false; /* need to rebuild list */
4148 
4149  /*
4150  * Reset the temporary namespace flag in MyProc. We assume that
4151  * this operation is atomic.
4152  *
4153  * Because this subtransaction is aborting, the pg_namespace row
4154  * is not visible to anyone else anyway, but that doesn't matter:
4155  * it's not a problem if objects contained in this namespace are
4156  * removed concurrently.
4157  */
4159  }
4160  }
4161 
4162  /*
4163  * Clean up if someone failed to do PopOverrideSearchPath
4164  */
4165  while (overrideStack)
4166  {
4169  break;
4170  if (isCommit)
4171  elog(WARNING, "leaked override search path");
4173  list_free(entry->searchPath);
4174  pfree(entry);
4175  /* Always bump generation --- see note in recomputeNamespacePath */
4177  }
4178 
4179  /* Activate the next level down. */
4180  if (overrideStack)
4181  {
4183  activeSearchPath = entry->searchPath;
4185  activeTempCreationPending = false; /* XXX is this OK? */
4186 
4187  /*
4188  * It's probably unnecessary to bump generation here, but this should
4189  * not be a performance-critical case, so better to be over-cautious.
4190  */
4192  }
4193  else
4194  {
4195  /* If not baseSearchPathValid, this is useless but harmless */
4199 
4200  /*
4201  * If we popped an override stack entry, then we already bumped the
4202  * generation above. If we did not, then the above assignments did
4203  * nothing and we need not bump the generation.
4204  */
4205  }
4206 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid tempNamespaceId
Definition: proc.h:124
PGPROC * MyProc
Definition: proc.c:67
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1056
#define linitial(l)
Definition: pg_list.h:195
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:151
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:842
#define InvalidSubTransactionId
Definition: c.h:519
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1376
#define elog(elevel,...)
Definition: elog.h:214
List * list_delete_first(List *list)
Definition: list.c:860

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4064 of file namespace.c.

References activeCreationNamespace, activePathGeneration, 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().

4065 {
4066  /*
4067  * If we abort the transaction in which a temp namespace was selected,
4068  * we'll have to do any creation or cleanout work over again. So, just
4069  * forget the namespace entirely until next time. On the other hand, if
4070  * we commit then register an exit callback to clean out the temp tables
4071  * at backend shutdown. (We only want to register the callback once per
4072  * session, so this is a good place to do it.)
4073  */
4074  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
4075  {
4076  if (isCommit)
4078  else
4079  {
4082  baseSearchPathValid = false; /* need to rebuild list */
4083 
4084  /*
4085  * Reset the temporary namespace flag in MyProc. We assume that
4086  * this operation is atomic.
4087  *
4088  * Because this transaction is aborting, the pg_namespace row is
4089  * not visible to anyone else anyway, but that doesn't matter:
4090  * it's not a problem if objects contained in this namespace are
4091  * removed concurrently.
4092  */
4094  }
4096  }
4097 
4098  /*
4099  * Clean up if someone failed to do PopOverrideSearchPath
4100  */
4101  if (overrideStack)
4102  {
4103  if (isCommit)
4104  elog(WARNING, "leaked override search path");
4105  while (overrideStack)
4106  {
4107  OverrideStackEntry *entry;
4108 
4111  list_free(entry->searchPath);
4112  pfree(entry);
4113  }
4114  /* If not baseSearchPathValid, this is useless but harmless */
4118  /* Always bump generation --- see note in recomputeNamespacePath */
4120  }
4121 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid tempNamespaceId
Definition: proc.h:124
PGPROC * MyProc
Definition: proc.c:67
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1056
#define linitial(l)
Definition: pg_list.h:195
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
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:192
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:151
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidSubTransactionId
Definition: c.h:519
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1376
#define elog(elevel,...)
Definition: elog.h:214
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4243
List * list_delete_first(List *list)
Definition: list.c:860

◆ check_search_path()

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

Definition at line 4274 of file namespace.c.

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

4275 {
4276  char *rawname;
4277  List *namelist;
4278 
4279  /* Need a modifiable copy of string */
4280  rawname = pstrdup(*newval);
4281 
4282  /* Parse string into list of identifiers */
4283  if (!SplitIdentifierString(rawname, ',', &namelist))
4284  {
4285  /* syntax error in name list */
4286  GUC_check_errdetail("List syntax is invalid.");
4287  pfree(rawname);
4288  list_free(namelist);
4289  return false;
4290  }
4291 
4292  /*
4293  * We used to try to check that the named schemas exist, but there are
4294  * many valid use-cases for having search_path settings that include
4295  * schemas that don't exist; and often, we are not inside a transaction
4296  * here and so can't consult the system catalogs anyway. So now, the only
4297  * requirement is syntactic validity of the identifier list.
4298  */
4299 
4300  pfree(rawname);
4301  list_free(namelist);
4302 
4303  return true;
4304 }
#define GUC_check_errdetail
Definition: guc.h:415
char * pstrdup(const char *in)
Definition: mcxt.c:1186
void pfree(void *pointer)
Definition: mcxt.c:1056
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3686
#define newval
void list_free(List *list)
Definition: list.c:1376
Definition: pg_list.h:50

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2967 of file namespace.c.

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

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

2968 {
2969  /* disallow renaming into or out of temp schemas */
2970  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2971  ereport(ERROR,
2972  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2973  errmsg("cannot move objects into or out of temporary schemas")));
2974 
2975  /* same for TOAST schema */
2976  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
2977  ereport(ERROR,
2978  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2979  errmsg("cannot move objects into or out of TOAST schema")));
2980 }
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3195

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3237 of file namespace.c.

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

Referenced by do_autovacuum().

3238 {
3239  PGPROC *proc;
3240  int backendId;
3241 
3243 
3244  backendId = GetTempNamespaceBackendId(namespaceId);
3245 
3246  /* No such namespace, or its name shows it's not temp? */
3247  if (backendId == InvalidBackendId)
3248  return TEMP_NAMESPACE_NOT_TEMP;
3249 
3250  /* Is the backend alive? */
3251  proc = BackendIdGetProc(backendId);
3252  if (proc == NULL)
3253  return TEMP_NAMESPACE_IDLE;
3254 
3255  /* Is the backend connected to the same database we are looking at? */
3256  if (proc->databaseId != MyDatabaseId)
3257  return TEMP_NAMESPACE_IDLE;
3258 
3259  /* Does the backend own the temporary namespace? */
3260  if (proc->tempNamespaceId != namespaceId)
3261  return TEMP_NAMESPACE_IDLE;
3262 
3263  /* Yup, so namespace is busy */
3264  return TEMP_NAMESPACE_IN_USE;
3265 }
Oid tempNamespaceId
Definition: proc.h:124
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3274
#define OidIsValid(objectId)
Definition: c.h:644
Oid databaseId
Definition: proc.h:121
#define InvalidBackendId
Definition: backendid.h:23
Oid MyDatabaseId
Definition: globals.c:85
#define Assert(condition)
Definition: c.h:738
Definition: proc.h:102
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:376

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2014 of file namespace.c.

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

Referenced by CollationIsVisible().

2015 {
2016  int32 dbencoding = GetDatabaseEncoding();
2017  ListCell *l;
2018 
2020 
2021  foreach(l, activeSearchPath)
2022  {
2023  Oid namespaceId = lfirst_oid(l);
2024  Oid collid;
2025 
2026  if (namespaceId == myTempNamespace)
2027  continue; /* do not look in temp namespace */
2028 
2029  collid = lookup_collation(collname, namespaceId, dbencoding);
2030  if (OidIsValid(collid))
2031  return collid;
2032  }
2033 
2034  /* Not found in path */
2035  return InvalidOid;
2036 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
signed int int32
Definition: c.h:355
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1963
int GetDatabaseEncoding(void)
Definition: mbutils.c:1151
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2048 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(), pg_collation_is_visible(), and regcollationout().

2049 {
2050  HeapTuple colltup;
2051  Form_pg_collation collform;
2052  Oid collnamespace;
2053  bool visible;
2054 
2055  colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
2056  if (!HeapTupleIsValid(colltup))
2057  elog(ERROR, "cache lookup failed for collation %u", collid);
2058  collform = (Form_pg_collation) GETSTRUCT(colltup);
2059 
2061 
2062  /*
2063  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2064  * the system namespace are surely in the path and so we needn't even do
2065  * list_member_oid() for them.
2066  */
2067  collnamespace = collform->collnamespace;
2068  if (collnamespace != PG_CATALOG_NAMESPACE &&
2069  !list_member_oid(activeSearchPath, collnamespace))
2070  visible = false;
2071  else
2072  {
2073  /*
2074  * If it is in the path, it might still not be visible; it could be
2075  * hidden by another collation of the same name earlier in the path,
2076  * or it might not work with the current DB encoding. So we must do a
2077  * slow check to see if this collation would be found by
2078  * CollationGetCollid.
2079  */
2080  char *collname = NameStr(collform->collname);
2081 
2082  visible = (CollationGetCollid(collname) == collid);
2083  }
2084 
2085  ReleaseSysCache(colltup);
2086 
2087  return visible;
2088 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid CollationGetCollid(const char *collname)
Definition: namespace.c:2014
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
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:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:615

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2099 of file namespace.c.

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

Referenced by ConversionIsVisible().

2100 {
2101  Oid conid;
2102  ListCell *l;
2103 
2105 
2106  foreach(l, activeSearchPath)
2107  {
2108  Oid namespaceId = lfirst_oid(l);
2109 
2110  if (namespaceId == myTempNamespace)
2111  continue; /* do not look in temp namespace */
2112 
2113  conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2114  PointerGetDatum(conname),
2115  ObjectIdGetDatum(namespaceId));
2116  if (OidIsValid(conid))
2117  return conid;
2118  }
2119 
2120  /* Not found in path */
2121  return InvalidOid;
2122 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#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:138
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

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

2132 {
2133  HeapTuple contup;
2134  Form_pg_conversion conform;
2135  Oid connamespace;
2136  bool visible;
2137 
2138  contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
2139  if (!HeapTupleIsValid(contup))
2140  elog(ERROR, "cache lookup failed for conversion %u", conid);
2141  conform = (Form_pg_conversion) GETSTRUCT(contup);
2142 
2144 
2145  /*
2146  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2147  * the system namespace are surely in the path and so we needn't even do
2148  * list_member_oid() for them.
2149  */
2150  connamespace = conform->connamespace;
2151  if (connamespace != PG_CATALOG_NAMESPACE &&
2152  !list_member_oid(activeSearchPath, connamespace))
2153  visible = false;
2154  else
2155  {
2156  /*
2157  * If it is in the path, it might still not be visible; it could be
2158  * hidden by another conversion of the same name earlier in the path.
2159  * So we must do a slow check to see if this conversion would be found
2160  * by ConversionGetConid.
2161  */
2162  char *conname = NameStr(conform->conname);
2163 
2164  visible = (ConversionGetConid(conname) == conid);
2165  }
2166 
2167  ReleaseSysCache(contup);
2168 
2169  return visible;
2170 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
Oid ConversionGetConid(const char *conname)
Definition: namespace.c:2099
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:61
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:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:615

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3397 of file namespace.c.

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

Referenced by CopyCachedPlan().

3398 {
3399  OverrideSearchPath *result;
3400 
3401  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3402  result->schemas = list_copy(path->schemas);
3403  result->addCatalog = path->addCatalog;
3404  result->addTemp = path->addTemp;
3405  result->generation = path->generation;
3406 
3407  return result;
3408 }
List * list_copy(const List *oldlist)
Definition: list.c:1403
void * palloc(Size size)
Definition: mcxt.c:949

◆ DeconstructQualifiedName()

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

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

2812 {
2813  char *catalogname;
2814  char *schemaname = NULL;
2815  char *objname = NULL;
2816 
2817  switch (list_length(names))
2818  {
2819  case 1:
2820  objname = strVal(linitial(names));
2821  break;
2822  case 2:
2823  schemaname = strVal(linitial(names));
2824  objname = strVal(lsecond(names));
2825  break;
2826  case 3:
2827  catalogname = strVal(linitial(names));
2828  schemaname = strVal(lsecond(names));
2829  objname = strVal(lthird(names));
2830 
2831  /*
2832  * We check the catalog name and then ignore it.
2833  */
2834  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2835  ereport(ERROR,
2836  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2837  errmsg("cross-database references are not implemented: %s",
2838  NameListToString(names))));
2839  break;
2840  default:
2841  ereport(ERROR,
2842  (errcode(ERRCODE_SYNTAX_ERROR),
2843  errmsg("improper qualified name (too many dotted names): %s",
2844  NameListToString(names))));
2845  break;
2846  }
2847 
2848  *nspname_p = schemaname;
2849  *objname_p = objname;
2850 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:610
#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:2155
char * NameListToString(List *names)
Definition: namespace.c:3102
Oid MyDatabaseId
Definition: globals.c:85
#define ereport(elevel,...)
Definition: elog.h:144
static int list_length(const List *l)
Definition: pg_list.h:169
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define lthird(l)
Definition: pg_list.h:205

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

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

4384 {
4385  List *result;
4386 
4388 
4389  /*
4390  * If the temp namespace should be first, force it to exist. This is so
4391  * that callers can trust the result to reflect the actual default
4392  * creation namespace. It's a bit bogus to do this here, since
4393  * current_schema() is supposedly a stable function without side-effects,
4394  * but the alternatives seem worse.
4395  */
4397  {
4400  }
4401 
4402  result = list_copy(activeSearchPath);
4403  if (!includeImplicit)
4404  {
4405  while (result && linitial_oid(result) != activeCreationNamespace)
4406  result = list_delete_first(result);
4407  }
4408 
4409  return result;
4410 }
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3915
List * list_copy(const List *oldlist)
Definition: list.c:1403
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
static Oid activeCreationNamespace
Definition: namespace.c:141
static bool activeTempCreationPending
Definition: namespace.c:144
#define linitial_oid(l)
Definition: pg_list.h:197
static List * activeSearchPath
Definition: namespace.c:138
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:860

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4423 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4424 {
4425  int count = 0;
4426  ListCell *l;
4427 
4429 
4430  foreach(l, activeSearchPath)
4431  {
4432  Oid namespaceId = lfirst_oid(l);
4433 
4434  if (namespaceId == myTempNamespace)
4435  continue; /* do not include temp namespace */
4436 
4437  if (count < sarray_len)
4438  sarray[count] = namespaceId;
4439  count++;
4440  }
4441 
4442  return count;
4443 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3710 of file namespace.c.

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

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

3711 {
3712  Oid proc;
3713  ListCell *l;
3714 
3716 
3717  foreach(l, activeSearchPath)
3718  {
3719  Oid namespaceId = lfirst_oid(l);
3720 
3721  if (namespaceId == myTempNamespace)
3722  continue; /* do not look in temp namespace */
3723 
3724  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3725  if (OidIsValid(proc))
3726  return proc;
3727  }
3728 
3729  /* Not found in path */
3730  return InvalidOid;
3731 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
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 942 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().

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1413 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_extended(), and pg_function_is_visible().

1414 {
1415  HeapTuple proctup;
1416  Form_pg_proc procform;
1417  Oid pronamespace;
1418  bool visible;
1419 
1420  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1421  if (!HeapTupleIsValid(proctup))
1422  elog(ERROR, "cache lookup failed for function %u", funcid);
1423  procform = (Form_pg_proc) GETSTRUCT(proctup);
1424 
1426 
1427  /*
1428  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1429  * the system namespace are surely in the path and so we needn't even do
1430  * list_member_oid() for them.
1431  */
1432  pronamespace = procform->pronamespace;
1433  if (pronamespace != PG_CATALOG_NAMESPACE &&
1434  !list_member_oid(activeSearchPath, pronamespace))
1435  visible = false;
1436  else
1437  {
1438  /*
1439  * If it is in the path, it might still not be visible; it could be
1440  * hidden by another proc of the same name and arguments earlier in
1441  * the path. So we must do a slow check to see if this is the same
1442  * proc that would be found by FuncnameGetCandidates.
1443  */
1444  char *proname = NameStr(procform->proname);
1445  int nargs = procform->pronargs;
1446  FuncCandidateList clist;
1447 
1448  visible = false;
1449 
1450  clist = FuncnameGetCandidates(list_make1(makeString(proname)),
1451  nargs, NIL, false, false, false);
1452 
1453  for (; clist; clist = clist->next)
1454  {
1455  if (memcmp(clist->args, procform->proargtypes.values,
1456  nargs * sizeof(Oid)) == 0)
1457  {
1458  /* Found the expected entry; is it the right proc? */
1459  visible = (clist->oid == funcid);
1460  break;
1461  }
1462  }
1463  }
1464 
1465  ReleaseSysCache(proctup);
1466 
1467  return visible;
1468 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:65
NameData proname
Definition: pg_proc.h:35
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#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:942
struct _FuncCandidateList * next
Definition: namespace.h:30
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:133
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:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:615

◆ get_collation_oid()

Oid get_collation_oid ( List name,
bool  missing_ok 
)

Definition at line 3601 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(), LookupCollation(), regcollationin(), and to_regcollation().

3602 {
3603  char *schemaname;
3604  char *collation_name;
3605  int32 dbencoding = GetDatabaseEncoding();
3606  Oid namespaceId;
3607  Oid colloid;
3608  ListCell *l;
3609 
3610  /* deconstruct the name list */
3611  DeconstructQualifiedName(name, &schemaname, &collation_name);
3612 
3613  if (schemaname)
3614  {
3615  /* use exact schema given */
3616  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3617  if (missing_ok && !OidIsValid(namespaceId))
3618  return InvalidOid;
3619 
3620  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3621  if (OidIsValid(colloid))
3622  return colloid;
3623  }
3624  else
3625  {
3626  /* search for it in search path */
3628 
3629  foreach(l, activeSearchPath)
3630  {
3631  namespaceId = lfirst_oid(l);
3632 
3633  if (namespaceId == myTempNamespace)
3634  continue; /* do not look in temp namespace */
3635 
3636  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3637  if (OidIsValid(colloid))
3638  return colloid;
3639  }
3640  }
3641 
3642  /* Not found in path */
3643  if (!missing_ok)
3644  ereport(ERROR,
3645  (errcode(ERRCODE_UNDEFINED_OBJECT),
3646  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3648  return InvalidOid;
3649 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2893
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2809
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
signed int int32
Definition: c.h:355
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1963
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3102
int GetDatabaseEncoding(void)
Definition: mbutils.c:1151
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1157
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ get_conversion_oid()

Oid get_conversion_oid ( List name,
bool  missing_ok 
)

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

3656 {
3657  char *schemaname;
3658  char *conversion_name;
3659  Oid namespaceId;
3660  Oid conoid = InvalidOid;
3661  ListCell *l;
3662 
3663  /* deconstruct the name list */
3664  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3665 
3666  if (schemaname)
3667  {
3668  /* use exact schema given */
3669  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3670  if (missing_ok && !OidIsValid(namespaceId))
3671  conoid = InvalidOid;
3672  else
3673  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3674  PointerGetDatum(conversion_name),
3675  ObjectIdGetDatum(namespaceId));
3676  }
3677  else
3678  {
3679  /* search for it in search path */
3681 
3682  foreach(l, activeSearchPath)
3683  {
3684  namespaceId = lfirst_oid(l);
3685 
3686  if (namespaceId == myTempNamespace)
3687  continue; /* do not look in temp namespace */
3688 
3689  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3690  PointerGetDatum(conversion_name),
3691  ObjectIdGetDatum(namespaceId));
3692  if (OidIsValid(conoid))
3693  return conoid;
3694  }
3695  }
3696 
3697  /* Not found in path */
3698  if (!OidIsValid(conoid) && !missing_ok)
3699  ereport(ERROR,
3700  (errcode(ERRCODE_UNDEFINED_OBJECT),
3701  errmsg("conversion \"%s\" does not exist",
3702  NameListToString(name))));
3703  return conoid;
3704 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2893
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2809
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3102
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:824
#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 3043 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().

3044 {
3045  Oid oid;
3046 
3047  oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid,
3048  CStringGetDatum(nspname));
3049  if (!OidIsValid(oid) && !missing_ok)
3050  ereport(ERROR,
3051  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3052  errmsg("schema \"%s\" does not exist", nspname)));
3053 
3054  return oid;
3055 }
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:192
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

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

2179 {
2180  char *schemaname;
2181  char *stats_name;
2182  Oid namespaceId;
2183  Oid stats_oid = InvalidOid;
2184  ListCell *l;
2185 
2186  /* deconstruct the name list */
2187  DeconstructQualifiedName(names, &schemaname, &stats_name);
2188 
2189  if (schemaname)
2190  {
2191  /* use exact schema given */
2192  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2193  if (missing_ok && !OidIsValid(namespaceId))
2194  stats_oid = InvalidOid;
2195  else
2196  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2197  PointerGetDatum(stats_name),
2198  ObjectIdGetDatum(namespaceId));
2199  }
2200  else
2201  {
2202  /* search for it in search path */
2204 
2205  foreach(l, activeSearchPath)
2206  {
2207  namespaceId = lfirst_oid(l);
2208 
2209  if (namespaceId == myTempNamespace)
2210  continue; /* do not look in temp namespace */
2211  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2212  PointerGetDatum(stats_name),
2213  ObjectIdGetDatum(namespaceId));
2214  if (OidIsValid(stats_oid))
2215  break;
2216  }
2217  }
2218 
2219  if (!OidIsValid(stats_oid) && !missing_ok)
2220  ereport(ERROR,
2221  (errcode(ERRCODE_UNDEFINED_OBJECT),
2222  errmsg("statistics object \"%s\" does not exist",
2223  NameListToString(names))));
2224 
2225  return stats_oid;
2226 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2893
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2809
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3102
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:824
#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 2679 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().

2680 {
2681  char *schemaname;
2682  char *config_name;
2683  Oid namespaceId;
2684  Oid cfgoid = InvalidOid;
2685  ListCell *l;
2686 
2687  /* deconstruct the name list */
2688  DeconstructQualifiedName(names, &schemaname, &config_name);
2689 
2690  if (schemaname)
2691  {
2692  /* use exact schema given */
2693  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2694  if (missing_ok && !OidIsValid(namespaceId))
2695  cfgoid = InvalidOid;
2696  else
2697  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2698  PointerGetDatum(config_name),
2699  ObjectIdGetDatum(namespaceId));
2700  }
2701  else
2702  {
2703  /* search for it in search path */
2705 
2706  foreach(l, activeSearchPath)
2707  {
2708  namespaceId = lfirst_oid(l);
2709 
2710  if (namespaceId == myTempNamespace)
2711  continue; /* do not look in temp namespace */
2712 
2713  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2714  PointerGetDatum(config_name),
2715  ObjectIdGetDatum(namespaceId));
2716  if (OidIsValid(cfgoid))
2717  break;
2718  }
2719  }
2720 
2721  if (!OidIsValid(cfgoid) && !missing_ok)
2722  ereport(ERROR,
2723  (errcode(ERRCODE_UNDEFINED_OBJECT),
2724  errmsg("text search configuration \"%s\" does not exist",
2725  NameListToString(names))));
2726 
2727  return cfgoid;
2728 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2893
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2809
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3102
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:824
#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 2426 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().

2427 {
2428  char *schemaname;
2429  char *dict_name;
2430  Oid namespaceId;
2431  Oid dictoid = InvalidOid;
2432  ListCell *l;
2433 
2434  /* deconstruct the name list */
2435  DeconstructQualifiedName(names, &schemaname, &dict_name);
2436 
2437  if (schemaname)
2438  {
2439  /* use exact schema given */
2440  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2441  if (missing_ok && !OidIsValid(namespaceId))
2442  dictoid = InvalidOid;
2443  else
2444  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2445  PointerGetDatum(dict_name),
2446  ObjectIdGetDatum(namespaceId));
2447  }
2448  else
2449  {
2450  /* search for it in search path */
2452 
2453  foreach(l, activeSearchPath)
2454  {
2455  namespaceId = lfirst_oid(l);
2456 
2457  if (namespaceId == myTempNamespace)
2458  continue; /* do not look in temp namespace */
2459 
2460  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2461  PointerGetDatum(dict_name),
2462  ObjectIdGetDatum(namespaceId));
2463  if (OidIsValid(dictoid))
2464  break;
2465  }
2466  }
2467 
2468  if (!OidIsValid(dictoid) && !missing_ok)
2469  ereport(ERROR,
2470  (errcode(ERRCODE_UNDEFINED_OBJECT),
2471  errmsg("text search dictionary \"%s\" does not exist",
2472  NameListToString(names))));
2473 
2474  return dictoid;
2475 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2893
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2809
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3102
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:824
#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 2300 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().

2301 {
2302  char *schemaname;
2303  char *parser_name;
2304  Oid namespaceId;
2305  Oid prsoid = InvalidOid;
2306  ListCell *l;
2307 
2308  /* deconstruct the name list */
2309  DeconstructQualifiedName(names, &schemaname, &parser_name);
2310 
2311  if (schemaname)
2312  {
2313  /* use exact schema given */
2314  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2315  if (missing_ok && !OidIsValid(namespaceId))
2316  prsoid = InvalidOid;
2317  else
2318  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2319  PointerGetDatum(parser_name),
2320  ObjectIdGetDatum(namespaceId));
2321  }
2322  else
2323  {
2324  /* search for it in search path */
2326 
2327  foreach(l, activeSearchPath)
2328  {
2329  namespaceId = lfirst_oid(l);
2330 
2331  if (namespaceId == myTempNamespace)
2332  continue; /* do not look in temp namespace */
2333 
2334  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2335  PointerGetDatum(parser_name),
2336  ObjectIdGetDatum(namespaceId));
2337  if (OidIsValid(prsoid))
2338  break;
2339  }
2340  }
2341 
2342  if (!OidIsValid(prsoid) && !missing_ok)
2343  ereport(ERROR,
2344  (errcode(ERRCODE_UNDEFINED_OBJECT),
2345  errmsg("text search parser \"%s\" does not exist",
2346  NameListToString(names))));
2347 
2348  return prsoid;
2349 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2893
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2809
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3102
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:824
#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 2553 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().

2554 {
2555  char *schemaname;
2556  char *template_name;
2557  Oid namespaceId;
2558  Oid tmploid = InvalidOid;
2559  ListCell *l;
2560 
2561  /* deconstruct the name list */
2562  DeconstructQualifiedName(names, &schemaname, &template_name);
2563 
2564  if (schemaname)
2565  {
2566  /* use exact schema given */
2567  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2568  if (missing_ok && !OidIsValid(namespaceId))
2569  tmploid = InvalidOid;
2570  else
2571  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2572  PointerGetDatum(template_name),
2573  ObjectIdGetDatum(namespaceId));
2574  }
2575  else
2576  {
2577  /* search for it in search path */
2579 
2580  foreach(l, activeSearchPath)
2581  {
2582  namespaceId = lfirst_oid(l);
2583 
2584  if (namespaceId == myTempNamespace)
2585  continue; /* do not look in temp namespace */
2586 
2587  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2588  PointerGetDatum(template_name),
2589  ObjectIdGetDatum(namespaceId));
2590  if (OidIsValid(tmploid))
2591  break;
2592  }
2593  }
2594 
2595  if (!OidIsValid(tmploid) && !missing_ok)
2596  ereport(ERROR,
2597  (errcode(ERRCODE_UNDEFINED_OBJECT),
2598  errmsg("text search template \"%s\" does not exist",
2599  NameListToString(names))));
2600 
2601  return tmploid;
2602 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2893
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2809
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * NameListToString(List *names)
Definition: namespace.c:3102
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:194
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3360 of file namespace.c.

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

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

3361 {
3362  OverrideSearchPath *result;
3363  List *schemas;
3364  MemoryContext oldcxt;
3365 
3367 
3368  oldcxt = MemoryContextSwitchTo(context);
3369 
3370  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3371  schemas = list_copy(activeSearchPath);
3372  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3373  {
3374  if (linitial_oid(schemas) == myTempNamespace)
3375  result->addTemp = true;
3376  else
3377  {
3378  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3379  result->addCatalog = true;
3380  }
3381  schemas = list_delete_first(schemas);
3382  }
3383  result->schemas = schemas;
3384  result->generation = activePathGeneration;
3385 
3386  MemoryContextSwitchTo(oldcxt);
3387 
3388  return result;
3389 }
static Oid myTempNamespace
Definition: namespace.c:188
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * list_copy(const List *oldlist)
Definition: list.c:1403
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
void * palloc0(Size size)
Definition: mcxt.c:980
#define Assert(condition)
Definition: c.h:738
#define linitial_oid(l)
Definition: pg_list.h:197
static List * activeSearchPath
Definition: namespace.c:138
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:860

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3274 of file namespace.c.

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

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

3275 {
3276  int result;
3277  char *nspname;
3278 
3279  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3280  nspname = get_namespace_name(namespaceId);
3281  if (!nspname)
3282  return InvalidBackendId; /* no such namespace? */
3283  if (strncmp(nspname, "pg_temp_", 8) == 0)
3284  result = atoi(nspname + 8);
3285  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3286  result = atoi(nspname + 14);
3287  else
3288  result = InvalidBackendId;
3289  pfree(nspname);
3290  return result;
3291 }
void pfree(void *pointer)
Definition: mcxt.c:1056
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3191
#define InvalidBackendId
Definition: backendid.h:23

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3313 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3314 {
3315  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3316  *tempNamespaceId = myTempNamespace;
3317  *tempToastNamespaceId = myTempToastNamespace;
3318 }
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3299 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3300 {
3302  return myTempToastNamespace;
3303 }
static Oid myTempToastNamespace
Definition: namespace.c:190
#define OidIsValid(objectId)
Definition: c.h:644
#define Assert(condition)
Definition: c.h:738

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4324 of file namespace.c.

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

Referenced by InitPostgres().

4325 {
4327  {
4328  /*
4329  * In bootstrap mode, the search path must be 'pg_catalog' so that
4330  * tables are created in the proper namespace; ignore the GUC setting.
4331  */
4332  MemoryContext oldcxt;
4333 
4335  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4336  MemoryContextSwitchTo(oldcxt);
4337  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4338  baseTempCreationPending = false;
4339  baseSearchPathValid = true;
4344  activePathGeneration++; /* pro forma */
4345  }
4346  else
4347  {
4348  /*
4349  * In normal mode, arrange for a callback on any syscache invalidation
4350  * of pg_namespace rows.
4351  */
4354  (Datum) 0);
4355  /* Force search path to be recomputed on next use */
4356  baseSearchPathValid = false;
4357  }
4358 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid GetUserId(void)
Definition: miscinit.c:448
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static Oid namespaceUser
Definition: namespace.c:157
static Oid activeCreationNamespace
Definition: namespace.c:141
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4365
static bool activeTempCreationPending
Definition: namespace.c:144
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static Oid baseCreationNamespace
Definition: namespace.c:153
static List * baseSearchPath
Definition: namespace.c:151
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:392
static List * activeSearchPath
Definition: namespace.c:138

◆ InitTempTableNamespace()

static void InitTempTableNamespace ( void  )
static

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

3944 {
3945  char namespaceName[NAMEDATALEN];
3946  Oid namespaceId;
3947  Oid toastspaceId;
3948 
3950 
3951  /*
3952  * First, do permission check to see if we are authorized to make temp
3953  * tables. We use a nonstandard error message here since "databasename:
3954  * permission denied" might be a tad cryptic.
3955  *
3956  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
3957  * that's necessary since current user ID could change during the session.
3958  * But there's no need to make the namespace in the first place until a
3959  * temp table creation request is made by someone with appropriate rights.
3960  */
3963  ereport(ERROR,
3964  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3965  errmsg("permission denied to create temporary tables in database \"%s\"",
3967 
3968  /*
3969  * Do not allow a Hot Standby session to make temp tables. Aside from
3970  * problems with modifying the system catalogs, there is a naming
3971  * conflict: pg_temp_N belongs to the session with BackendId N on the
3972  * primary, not to a hot standby session with the same BackendId. We
3973  * should not be able to get here anyway due to XactReadOnly checks, but
3974  * let's just make real sure. Note that this also backstops various
3975  * operations that allow XactReadOnly transactions to modify temp tables;
3976  * they'd need RecoveryInProgress checks if not for this.
3977  */
3978  if (RecoveryInProgress())
3979  ereport(ERROR,
3980  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3981  errmsg("cannot create temporary tables during recovery")));
3982 
3983  /* Parallel workers can't create temporary tables, either. */
3984  if (IsParallelWorker())
3985  ereport(ERROR,
3986  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3987  errmsg("cannot create temporary tables during a parallel operation")));
3988 
3989  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
3990 
3991  namespaceId = get_namespace_oid(namespaceName, true);
3992  if (!OidIsValid(namespaceId))
3993  {
3994  /*
3995  * First use of this temp namespace in this database; create it. The
3996  * temp namespaces are always owned by the superuser. We leave their
3997  * permissions at default --- i.e., no access except to superuser ---
3998  * to ensure that unprivileged users can't peek at other backends'
3999  * temp tables. This works because the places that access the temp
4000  * namespace for my own backend skip permissions checks on it.
4001  */
4002  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
4003  true);
4004  /* Advance command counter to make namespace visible */
4006  }
4007  else
4008  {
4009  /*
4010  * If the namespace already exists, clean it out (in case the former
4011  * owner crashed without doing so).
4012  */
4013  RemoveTempRelations(namespaceId);
4014  }
4015 
4016  /*
4017  * If the corresponding toast-table namespace doesn't exist yet, create
4018  * it. (We assume there is no need to clean it out if it does exist, since
4019  * dropping a parent table should make its toast table go away.)
4020  */
4021  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
4022  MyBackendId);
4023 
4024  toastspaceId = get_namespace_oid(namespaceName, true);
4025  if (!OidIsValid(toastspaceId))
4026  {
4027  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
4028  true);
4029  /* Advance command counter to make namespace visible */
4031  }
4032 
4033  /*
4034  * Okay, we've prepared the temp namespace ... but it's not committed yet,
4035  * so all our work could be undone by transaction rollback. Set flag for
4036  * AtEOXact_Namespace to know what to do.
4037  */
4038  myTempNamespace = namespaceId;
4039  myTempToastNamespace = toastspaceId;
4040 
4041  /*
4042  * Mark MyProc as owning this namespace which other processes can use to
4043  * decide if a temporary namespace is in use or not. We assume that
4044  * assignment of namespaceId is an atomic operation. Even if it is not,
4045  * the temporary relation which resulted in the creation of this temporary
4046  * namespace is still locked until the current transaction commits, and
4047  * its pg_namespace row is not visible yet. However it does not matter:
4048  * this flag makes the namespace as being in use, so no objects created on
4049  * it would be removed concurrently.
4050  */
4051  MyProc->tempNamespaceId = namespaceId;
4052 
4053  /* It should not be done already. */
4056 
4057  baseSearchPathValid = false; /* need to rebuild list */
4058 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3043
BackendId MyBackendId
Definition: globals.c:81
#define AssertState(condition)
Definition: c.h:741
Oid GetUserId(void)
Definition: miscinit.c:448
Oid tempNamespaceId
Definition: proc.h:124
PGPROC * MyProc
Definition: proc.c:67
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:8072
#define OidIsValid(objectId)
Definition: c.h:644
#define NAMEDATALEN
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
#define IsParallelWorker()
Definition: parallel.h:61
void CommandCounterIncrement(void)
Definition: xact.c:1006
Oid MyDatabaseId
Definition: globals.c:85
#define ereport(elevel,...)
Definition: elog.h:144
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4575
#define Assert(condition)
Definition: c.h:738
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4217
#define InvalidSubTransactionId
Definition: c.h:519
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define ACL_CREATE_TEMP
Definition: parsenodes.h:85
#define snprintf
Definition: port.h:193
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
Definition: pg_namespace.c:43

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3195 of file namespace.c.

References get_namespace_name(), and pfree().

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

3196 {
3197  bool result;
3198  char *nspname;
3199 
3200  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3201  nspname = get_namespace_name(namespaceId);
3202  if (!nspname)
3203  return false; /* no such namespace? */
3204  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3205  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3206  pfree(nspname);
3207  return result;
3208 }
void pfree(void *pointer)
Definition: mcxt.c:1056
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3191

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3218 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

3219 {
3220  /* If it's my own temp namespace, say "false" */
3221  if (isTempOrTempToastNamespace(namespaceId))
3222  return false;
3223  /* Else, if it's any temp namespace, say "true" */
3224  return isAnyTempNamespace(namespaceId);
3225 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3181
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3195

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3157 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

3158 {
3159  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3160  return true;
3161  return false;
3162 }
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:644

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3181 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

3182 {
3183  if (OidIsValid(myTempNamespace) &&
3184  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3185  return true;
3186  return false;
3187 }
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:644

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3169 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

3170 {
3171  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3172  return true;
3173  return false;
3174 }
static Oid myTempToastNamespace
Definition: namespace.c:190
#define OidIsValid(objectId)
Definition: c.h:644

◆ lookup_collation()

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

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

1964 {
1965  Oid collid;
1966  HeapTuple colltup;
1967  Form_pg_collation collform;
1968 
1969  /* Check for encoding-specific entry (exact match) */
1970  collid = GetSysCacheOid3(COLLNAMEENCNSP, Anum_pg_collation_oid,
1971  PointerGetDatum(collname),
1973  ObjectIdGetDatum(collnamespace));
1974  if (OidIsValid(collid))
1975  return collid;
1976 
1977  /*
1978  * Check for any-encoding entry. This takes a bit more work: while libc
1979  * collations with collencoding = -1 do work with all encodings, ICU
1980  * collations only work with certain encodings, so we have to check that
1981  * aspect before deciding it's a match.
1982  */
1983  colltup = SearchSysCache3(COLLNAMEENCNSP,
1984  PointerGetDatum(collname),
1985  Int32GetDatum(-1),
1986  ObjectIdGetDatum(collnamespace));
1987  if (!HeapTupleIsValid(colltup))
1988  return InvalidOid;
1989  collform = (Form_pg_collation) GETSTRUCT(colltup);
1990  if (collform->collprovider == COLLPROVIDER_ICU)
1991  {
1993  collid = collform->oid;
1994  else
1995  collid = InvalidOid;
1996  }
1997  else
1998  {
1999  collid = collform->oid;
2000  }
2001  ReleaseSysCache(colltup);
2002  return collid;
2003 }
#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:459
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
#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:1138
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#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 2936 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().

2937 {
2938  Oid namespaceId;
2939  AclResult aclresult;
2940 
2941  /* check for pg_temp alias */
2942  if (strcmp(nspname, "pg_temp") == 0)
2943  {
2944  /* Initialize temp namespace */
2945  AccessTempTableNamespace(false);
2946  return myTempNamespace;
2947  }
2948 
2949  namespaceId = get_namespace_oid(nspname, false);
2950 
2951  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2952  if (aclresult != ACLCHECK_OK)
2953  aclcheck_error(aclresult, OBJECT_SCHEMA,
2954  nspname);
2955 
2956  return namespaceId;
2957 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3043
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3915
Oid GetUserId(void)
Definition: miscinit.c:448
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4625
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
#define ACL_CREATE
Definition: parsenodes.h:84
AclResult
Definition: acl.h:177

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

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

2894 {
2895  Oid namespaceId;
2896  AclResult aclresult;
2897 
2898  /* check for pg_temp alias */
2899  if (strcmp(nspname, "pg_temp") == 0)
2900  {
2902  return myTempNamespace;
2903 
2904  /*
2905  * Since this is used only for looking up existing objects, there is
2906  * no point in trying to initialize the temp namespace here; and doing
2907  * so might create problems for some callers --- just fall through.
2908  */
2909  }
2910 
2911  namespaceId = get_namespace_oid(nspname, missing_ok);
2912  if (missing_ok && !OidIsValid(namespaceId))
2913  return InvalidOid;
2914 
2915  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
2916  if (aclresult != ACLCHECK_OK)
2917  aclcheck_error(aclresult, OBJECT_SCHEMA,
2918  nspname);
2919  /* Schema search hook for this lookup */
2920  InvokeNamespaceSearchHook(namespaceId, true);
2921 
2922  return namespaceId;
2923 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3043
Oid GetUserId(void)
Definition: miscinit.c:448
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4625
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:186
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
#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 2863 of file namespace.c.

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

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

2864 {
2865  /* check for pg_temp alias */
2866  if (strcmp(nspname, "pg_temp") == 0)
2867  {
2869  {
2871  return myTempNamespace;
2872  }
2873 
2874  /*
2875  * Since this is used only for looking up existing objects, there is
2876  * no point in trying to initialize the temp namespace here; and doing
2877  * so might create problems for some callers. Just report "not found".
2878  */
2879  return InvalidOid;
2880  }
2881 
2882  return get_namespace_oid(nspname, true);
2883 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3043
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:644
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:186
#define InvalidOid
Definition: postgres_ext.h:36

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( List names)

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

3063 {
3064  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3065 
3066  switch (list_length(names))
3067  {
3068  case 1:
3069  rel->relname = strVal(linitial(names));
3070  break;
3071  case 2:
3072  rel->schemaname = strVal(linitial(names));
3073  rel->relname = strVal(lsecond(names));
3074  break;
3075  case 3:
3076  rel->catalogname = strVal(linitial(names));
3077  rel->schemaname = strVal(lsecond(names));
3078  rel->relname = strVal(lthird(names));
3079  break;
3080  default:
3081  ereport(ERROR,
3082  (errcode(ERRCODE_SYNTAX_ERROR),
3083  errmsg("improper relation name (too many dotted names): %s",
3084  NameListToString(names))));
3085  break;
3086  }
3087 
3088  return rel;
3089 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:610
#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
char * NameListToString(List *names)
Definition: namespace.c:3102
#define ereport(elevel,...)
Definition: elog.h:144
static int list_length(const List *l)
Definition: pg_list.h:169
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define lthird(l)
Definition: pg_list.h:205
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:422
char * catalogname
Definition: primnodes.h:66

◆ MatchNamedCall()

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

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

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

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3136 of file namespace.c.

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

3137 {
3139  ListCell *l;
3140 
3141  initStringInfo(&string);
3142 
3143  foreach(l, names)
3144  {
3145  if (l != list_head(names))
3146  appendStringInfoChar(&string, '.');
3148  }
3149 
3150  return string.data;
3151 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10727
#define strVal(v)
Definition: value.h:54
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
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:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define lfirst(lc)
Definition: pg_list.h:190

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3102 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(), findTypeReceiveFunction(), findTypeSendFunction(), 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().

3103 {
3105  ListCell *l;
3106 
3107  initStringInfo(&string);
3108 
3109  foreach(l, names)
3110  {
3111  Node *name = (Node *) lfirst(l);
3112 
3113  if (l != list_head(names))
3114  appendStringInfoChar(&string, '.');
3115 
3116  if (IsA(name, String))
3117  appendStringInfoString(&string, strVal(name));
3118  else if (IsA(name, A_Star))
3119  appendStringInfoChar(&string, '*');
3120  else
3121  elog(ERROR, "unexpected node type in name list: %d",
3122  (int) nodeTag(name));
3123  }
3124 
3125  return string.data;
3126 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
Definition: nodes.h:529
#define strVal(v)
Definition: value.h:54
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
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:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define lfirst(lc)
Definition: pg_list.h:190
const char * name
Definition: encode.c:561
#define nodeTag(nodeptr)
Definition: nodes.h:534
#define elog(elevel,...)
Definition: elog.h:214

◆ NamespaceCallback()

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

Definition at line 4365 of file namespace.c.

References baseSearchPathValid.

Referenced by InitializeSearchPath().

4366 {
4367  /* Force search path to be recomputed on next use */
4368  baseSearchPathValid = false;
4369 }
static bool baseSearchPathValid
Definition: namespace.c:160

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

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

1834 {
1835  HeapTuple opctup;
1836  Form_pg_opclass opcform;
1837  Oid opcnamespace;
1838  bool visible;
1839 
1840  opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
1841  if (!HeapTupleIsValid(opctup))
1842  elog(ERROR, "cache lookup failed for opclass %u", opcid);
1843  opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1844 
1846 
1847  /*
1848  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1849  * the system namespace are surely in the path and so we needn't even do
1850  * list_member_oid() for them.
1851  */
1852  opcnamespace = opcform->opcnamespace;
1853  if (opcnamespace != PG_CATALOG_NAMESPACE &&
1854  !list_member_oid(activeSearchPath, opcnamespace))
1855  visible = false;
1856  else
1857  {
1858  /*
1859  * If it is in the path, it might still not be visible; it could be
1860  * hidden by another opclass of the same name earlier in the path. So
1861  * we must do a slow check to see if this opclass would be found by
1862  * OpclassnameGetOpcid.
1863  */
1864  char *opcname = NameStr(opcform->opcname);
1865 
1866  visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1867  }
1868 
1869  ReleaseSysCache(opctup);
1870 
1871  return visible;
1872 }
#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:1800
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
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:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:615
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1800 of file namespace.c.

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

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

1801 {
1802  Oid opcid;
1803  ListCell *l;
1804 
1806 
1807  foreach(l, activeSearchPath)
1808  {
1809  Oid namespaceId = lfirst_oid(l);
1810 
1811  if (namespaceId == myTempNamespace)
1812  continue; /* do not look in temp namespace */
1813 
1814  opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
1815  ObjectIdGetDatum(amid),
1816  PointerGetDatum(opcname),
1817  ObjectIdGetDatum(namespaceId));
1818  if (OidIsValid(opcid))
1819  return opcid;
1820  }
1821 
1822  /* Not found in path */
1823  return InvalidOid;
1824 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#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:138
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1747 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_extended(), and pg_operator_is_visible().

1748 {
1749  HeapTuple oprtup;
1750  Form_pg_operator oprform;
1751  Oid oprnamespace;
1752  bool visible;
1753 
1755  if (!HeapTupleIsValid(oprtup))
1756  elog(ERROR, "cache lookup failed for operator %u", oprid);
1757  oprform = (Form_pg_operator) GETSTRUCT(oprtup);
1758 
1760 
1761  /*
1762  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1763  * the system namespace are surely in the path and so we needn't even do
1764  * list_member_oid() for them.
1765  */
1766  oprnamespace = oprform->oprnamespace;
1767  if (oprnamespace != PG_CATALOG_NAMESPACE &&
1768  !list_member_oid(activeSearchPath, oprnamespace))
1769  visible = false;
1770  else
1771  {
1772  /*
1773  * If it is in the path, it might still not be visible; it could be
1774  * hidden by another operator of the same name and arguments earlier
1775  * in the path. So we must do a slow check to see if this is the same
1776  * operator that would be found by OpernameGetOprid.
1777  */
1778  char *oprname = NameStr(oprform->oprname);
1779 
1780  visible = (OpernameGetOprid(list_make1(makeString(oprname)),
1781  oprform->oprleft, oprform->oprright)
1782  == oprid);
1783  }
1784 
1785  ReleaseSysCache(oprtup);
1786 
1787  return visible;
1788 }
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:3737
#define list_make1(x1)
Definition: pg_list.h:227
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1484
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
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:83
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:615

◆ OpernameGetCandidates()

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

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

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

1485 {
1486  char *schemaname;
1487  char *opername;
1488  CatCList *catlist;
1489  ListCell *l;
1490 
1491  /* deconstruct the name list */
1492  DeconstructQualifiedName(names, &schemaname, &opername);
1493 
1494  if (schemaname)
1495  {
1496  /* search only in exact schema given */
1497  Oid namespaceId;
1498 
1499  namespaceId = LookupExplicitNamespace(schemaname, true);
1500  if (OidIsValid(namespaceId))
1501  {
1502  HeapTuple opertup;
1503 
1504  opertup = SearchSysCache4(OPERNAMENSP,
1505  CStringGetDatum(opername),
1506  ObjectIdGetDatum(oprleft),
1507  ObjectIdGetDatum(oprright),
1508  ObjectIdGetDatum(namespaceId));
1509  if (HeapTupleIsValid(opertup))
1510  {
1511  Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup);
1512  Oid result = operclass->oid;
1513 
1514  ReleaseSysCache(opertup);
1515  return result;
1516  }
1517  }
1518 
1519  return InvalidOid;
1520  }
1521 
1522  /* Search syscache by name and argument types */
1523  catlist = SearchSysCacheList3(OPERNAMENSP,
1524  CStringGetDatum(opername),
1525  ObjectIdGetDatum(oprleft),
1526  ObjectIdGetDatum(oprright));
1527 
1528  if (catlist->n_members == 0)
1529  {
1530  /* no hope, fall out early */
1531  ReleaseSysCacheList(catlist);
1532  return InvalidOid;
1533  }
1534 
1535  /*
1536  * We have to find the list member that is first in the search path, if
1537  * there's more than one. This doubly-nested loop looks ugly, but in
1538  * practice there should usually be few catlist members.
1539  */
1541 
1542  foreach(l, activeSearchPath)
1543  {
1544  Oid namespaceId = lfirst_oid(l);
1545  int i;
1546 
1547  if (namespaceId == myTempNamespace)
1548  continue; /* do not look in temp namespace */
1549 
1550  for (i = 0; i < catlist->n_members; i++)
1551  {
1552  HeapTuple opertup = &catlist->members[i]->tuple;
1553  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1554 
1555  if (operform->oprnamespace == namespaceId)
1556  {
1557  Oid result = operform->oid;
1558 
1559  ReleaseSysCacheList(catlist);
1560  return result;
1561  }
1562  }
1563  }
1564 
1565  ReleaseSysCacheList(catlist);
1566  return InvalidOid;
1567 }
int n_members
Definition: catcache.h:176
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2893
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
static Oid myTempNamespace
Definition: namespace.c:188
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2809
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
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:1149
#define ReleaseSysCacheList(x)
Definition: syscache.h:217
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
static List * activeSearchPath
Definition: namespace.c:138
#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 1916 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().

1917 {
1918  HeapTuple opftup;
1919  Form_pg_opfamily opfform;
1920  Oid opfnamespace;
1921  bool visible;
1922 
1923  opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
1924  if (!HeapTupleIsValid(opftup))
1925  elog(ERROR, "cache lookup failed for opfamily %u", opfid);
1926  opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
1927 
1929 
1930  /*
1931  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1932  * the system namespace are surely in the path and so we needn't even do
1933  * list_member_oid() for them.
1934  */
1935  opfnamespace = opfform->opfnamespace;
1936  if (opfnamespace != PG_CATALOG_NAMESPACE &&
1937  !list_member_oid(activeSearchPath, opfnamespace))
1938  visible = false;
1939  else
1940  {
1941  /*
1942  * If it is in the path, it might still not be visible; it could be
1943  * hidden by another opfamily of the same name earlier in the path. So
1944  * we must do a slow check to see if this opfamily would be found by
1945  * OpfamilynameGetOpfid.
1946  */
1947  char *opfname = NameStr(opfform->opfname);
1948 
1949  visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
1950  }
1951 
1952  ReleaseSysCache(opftup);
1953 
1954  return visible;
1955 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
Definition: namespace.c:1883
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
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:138
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:615

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1883 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

1884 {
1885  Oid opfid;
1886  ListCell *l;
1887 
1889 
1890  foreach(l, activeSearchPath)
1891  {
1892  Oid namespaceId = lfirst_oid(l);
1893 
1894  if (namespaceId == myTempNamespace)
1895  continue; /* do not look in temp namespace */
1896 
1897  opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
1898  ObjectIdGetDatum(amid),
1899  PointerGetDatum(opfname),
1900  ObjectIdGetDatum(namespaceId));
1901  if (OidIsValid(opfid))
1902  return opfid;
1903  }
1904 
1905  /* Not found in path */
1906  return InvalidOid;
1907 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
#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:138
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3419 of file namespace.c.

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

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

3420 {
3421  ListCell *lc,
3422  *lcp;
3423 
3425 
3426  /* Quick out if already known equal to active path. */
3427  if (path->generation == activePathGeneration)
3428  return true;
3429 
3430  /* We scan down the activeSearchPath to see if it matches the input. */
3432 
3433  /* If path->addTemp, first item should be my temp namespace. */
3434  if (path->addTemp)
3435  {
3436  if (lc && lfirst_oid(lc) == myTempNamespace)
3437  lc = lnext(activeSearchPath, lc);
3438  else
3439  return false;
3440  }
3441  /* If path->addCatalog, next item should be pg_catalog. */
3442  if (path->addCatalog)
3443  {
3444  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3445  lc = lnext(activeSearchPath, lc);
3446  else
3447  return false;
3448  }
3449  /* We should now be looking at the activeCreationNamespace. */
3450  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3451  return false;
3452  /* The remainder of activeSearchPath should match path->schemas. */
3453  foreach(lcp, path->schemas)
3454  {
3455  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3456  lc = lnext(activeSearchPath, lc);
3457  else
3458  return false;
3459  }
3460  if (lc)
3461  return false;
3462 
3463  /*
3464  * Update path->generation so that future tests will return quickly, so
3465  * long as the active search path doesn't change.
3466  */
3468 
3469  return true;
3470 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
static Oid myTempNamespace
Definition: namespace.c:188
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
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:138
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ pg_collation_is_visible()

Datum pg_collation_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4526 of file namespace.c.

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

4527 {
4528  Oid oid = PG_GETARG_OID(0);
4529 
4531  PG_RETURN_NULL();
4532 
4534 }
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:275
bool CollationIsVisible(Oid collid)
Definition: namespace.c:2048
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_conversion_is_visible()

Datum pg_conversion_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4537 of file namespace.c.

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

4538 {
4539  Oid oid = PG_GETARG_OID(0);
4540 
4542  PG_RETURN_NULL();
4543 
4545 }
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:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
bool ConversionIsVisible(Oid conid)
Definition: namespace.c:2131
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_function_is_visible()

Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4482 of file namespace.c.

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

4483 {
4484  Oid oid = PG_GETARG_OID(0);
4485 
4487  PG_RETURN_NULL();
4488 
4490 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1413
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:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_is_other_temp_schema()

Datum pg_is_other_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4609 of file namespace.c.

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

4610 {
4611  Oid oid = PG_GETARG_OID(0);
4612 
4614 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
bool isOtherTempNamespace(Oid namespaceId)
Definition: namespace.c:3218

◆ pg_my_temp_schema()

Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4603 of file namespace.c.

References myTempNamespace, and PG_RETURN_OID.

4604 {
4606 }
static Oid myTempNamespace
Definition: namespace.c:188
#define PG_RETURN_OID(x)
Definition: fmgr.h:359

◆ pg_opclass_is_visible()

Datum pg_opclass_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4504 of file namespace.c.

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

4505 {
4506  Oid oid = PG_GETARG_OID(0);
4507 
4509  PG_RETURN_NULL();
4510 
4512 }
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:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
bool OpclassIsVisible(Oid opcid)
Definition: namespace.c:1833
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_operator_is_visible()

Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4493 of file namespace.c.

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

4494 {
4495  Oid oid = PG_GETARG_OID(0);
4496 
4498  PG_RETURN_NULL();
4499 
4501 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1747
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:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_opfamily_is_visible()

Datum pg_opfamily_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4515 of file namespace.c.

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

4516 {
4517  Oid oid = PG_GETARG_OID(0);
4518 
4520  PG_RETURN_NULL();
4521 
4523 }
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:275
bool OpfamilyIsVisible(Oid opfid)
Definition: namespace.c:1916
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_statistics_obj_is_visible()

Datum pg_statistics_obj_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4548 of file namespace.c.

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

4549 {
4550  Oid oid = PG_GETARG_OID(0);
4551 
4553  PG_RETURN_NULL();
4554 
4556 }
bool StatisticsObjIsVisible(Oid relid)
Definition: namespace.c:2235
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:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_table_is_visible()

Datum pg_table_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4460 of file namespace.c.

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

4461 {
4462  Oid oid = PG_GETARG_OID(0);
4463 
4465  PG_RETURN_NULL();
4466 
4468 }
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:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
bool RelationIsVisible(Oid relid)
Definition: namespace.c:708
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_ts_config_is_visible()

Datum pg_ts_config_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4592 of file namespace.c.

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

4593 {
4594  Oid oid = PG_GETARG_OID(0);
4595 
4597  PG_RETURN_NULL();
4598 
4600 }
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:2737
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_ts_dict_is_visible()

Datum pg_ts_dict_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4570 of file namespace.c.

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

4571 {
4572  Oid oid = PG_GETARG_OID(0);
4573 
4575  PG_RETURN_NULL();
4576 
4578 }
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:275
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2484
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_ts_parser_is_visible()

Datum pg_ts_parser_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4559 of file namespace.c.

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

4560 {
4561  Oid oid = PG_GETARG_OID(0);
4562 
4564  PG_RETURN_NULL();
4565 
4567 }
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:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
bool TSParserIsVisible(Oid prsId)
Definition: namespace.c:2358
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_ts_template_is_visible()

Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4581 of file namespace.c.

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

4582 {
4583  Oid oid = PG_GETARG_OID(0);
4584 
4586  PG_RETURN_NULL();
4587 
4589 }
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:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
bool TSTemplateIsVisible(Oid tmplId)
Definition: namespace.c:2611
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ pg_type_is_visible()

Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4471 of file namespace.c.

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

4472 {
4473  Oid oid = PG_GETARG_OID(0);
4474 
4476  PG_RETURN_NULL();
4477 
4479 }
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:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
bool TypeIsVisible(Oid typid)
Definition: namespace.c:816
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3557 of file namespace.c.

References activeCreationNamespace, activePathGeneration, 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().

3558 {
3559  OverrideStackEntry *entry;
3560 
3561  /* Sanity checks. */
3562  if (overrideStack == NIL)
3563  elog(ERROR, "bogus PopOverrideSearchPath call");
3565  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3566  elog(ERROR, "bogus PopOverrideSearchPath call");
3567 
3568  /* Pop the stack and free storage. */
3570  list_free(entry->searchPath);
3571  pfree(entry);
3572 
3573  /* Activate the next level down. */
3574  if (overrideStack)
3575  {
3577  activeSearchPath = entry->searchPath;
3579  activeTempCreationPending = false; /* XXX is this OK? */
3580  }
3581  else
3582  {
3583  /* If not baseSearchPathValid, this is useless but harmless */
3587  }
3588 
3589  /* As above, the generation always increments. */
3591 }
#define NIL
Definition: pg_list.h:65
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1056
#define linitial(l)
Definition: pg_list.h:195
#define ERROR
Definition: elog.h:43
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
static List * baseSearchPath
Definition: namespace.c:151
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:842
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1376
#define elog(elevel,...)
Definition: elog.h:214
List * list_delete_first(List *list)
Definition: list.c:860

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3490 of file namespace.c.

References activeCreationNamespace, activePathGeneration, 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().

3491 {
3492  OverrideStackEntry *entry;
3493  List *oidlist;
3494  Oid firstNS;
3495  MemoryContext oldcxt;
3496 
3497  /*
3498  * Copy the list for safekeeping, and insert implicitly-searched
3499  * namespaces as needed. This code should track recomputeNamespacePath.
3500  */
3502 
3503  oidlist = list_copy(newpath->schemas);
3504 
3505  /*
3506  * Remember the first member of the explicit list.
3507  */
3508  if (oidlist == NIL)
3509  firstNS = InvalidOid;
3510  else
3511  firstNS = linitial_oid(oidlist);
3512 
3513  /*
3514  * Add any implicitly-searched namespaces to the list. Note these go on
3515  * the front, not the back; also notice that we do not check USAGE
3516  * permissions for these.
3517  */
3518  if (newpath->addCatalog)
3519  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3520 
3521  if (newpath->addTemp && OidIsValid(myTempNamespace))
3522  oidlist = lcons_oid(myTempNamespace, oidlist);
3523 
3524  /*
3525  * Build the new stack entry, then insert it at the head of the list.
3526  */
3527  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3528  entry->searchPath = oidlist;
3529  entry->creationNamespace = firstNS;
3531 
3532  overrideStack = lcons(entry, overrideStack);
3533 
3534  /* And make it active. */
3535  activeSearchPath = entry->searchPath;
3537  activeTempCreationPending = false; /* XXX is this OK? */
3538 
3539  /*
3540  * We always increment activePathGeneration when pushing/popping an
3541  * override path. In current usage, these actions always change the
3542  * effective path state, so there's no value in checking to see if it
3543  * didn't change.
3544  */
3546 
3547  MemoryContextSwitchTo(oldcxt);
3548 }
#define NIL
Definition: pg_list.h:65
static Oid myTempNamespace
Definition: namespace.c:188
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static List * overrideStack
Definition: namespace.c:171
List * list_copy(const List *oldlist)
Definition: list.c:1403
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:644
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:144
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:138
void * palloc(Size size)
Definition: mcxt.c:949
Definition: pg_list.h:50

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

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

2996 {
2997  char *schemaname;
2998  Oid namespaceId;
2999 
3000  /* deconstruct the name list */
3001  DeconstructQualifiedName(names, &schemaname, objname_p);
3002 
3003  if (schemaname)
3004  {
3005  /* check for pg_temp alias */
3006  if (strcmp(schemaname, "pg_temp") == 0)
3007  {
3008  /* Initialize temp namespace */
3009  AccessTempTableNamespace(false);
3010  return myTempNamespace;
3011  }
3012  /* use exact schema given */
3013  namespaceId = get_namespace_oid(schemaname, false);
3014  /* we do not check for USAGE rights here! */
3015  }
3016  else
3017  {
3018  /* use the default creation namespace */
3021  {
3022  /* Need to initialize temp namespace */
3024  return myTempNamespace;
3025  }
3026  namespaceId = activeCreationNamespace;
3027  if (!OidIsValid(namespaceId))
3028  ereport(ERROR,
3029  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3030  errmsg("no schema has been selected to create in")));
3031  }
3032 
3033  return namespaceId;
3034 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3043
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3915
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2809
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
static Oid activeCreationNamespace
Definition: namespace.c:141
#define ERROR
Definition: elog.h:43
static bool activeTempCreationPending
Definition: namespace.c:144
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 641 of file namespace.c.

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

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

642 {
643  switch (newRelation->relpersistence)
644  {
645  case RELPERSISTENCE_TEMP:
646  if (!isTempOrTempToastNamespace(nspid))
647  {
648  if (isAnyTempNamespace(nspid))
649  ereport(ERROR,
650  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
651  errmsg("cannot create relations in temporary schemas of other sessions")));
652  else
653  ereport(ERROR,
654  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
655  errmsg("cannot create temporary relation in non-temporary schema")));
656  }
657  break;
658  case RELPERSISTENCE_PERMANENT:
659  if (isTempOrTempToastNamespace(nspid))
660  newRelation->relpersistence = RELPERSISTENCE_TEMP;
661  else if (isAnyTempNamespace(nspid))
662  ereport(ERROR,
663  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
664  errmsg("cannot create relations in temporary schemas of other sessions")));
665  break;
666  default:
667  if (isAnyTempNamespace(nspid))
668  ereport(ERROR,
669  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
670  errmsg("only temporary relations may be created in temporary schemas")));
671  }
672 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3181
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:824
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3195

◆ RangeVarGetAndCheckCreationNamespace()

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

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

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

450 {
451  Oid namespaceId;
452 
453  /*
454  * We check the catalog name and then ignore it.
455  */
456  if (newRelation->catalogname)
457  {
458  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
459  ereport(ERROR,
460  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
461  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
462  newRelation->catalogname, newRelation->schemaname,
463  newRelation->relname)));
464  }
465 
466  if (newRelation->schemaname)
467  {
468  /* check for pg_temp alias */
469  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
470  {
471  /* Initialize temp namespace */
473  return myTempNamespace;
474  }
475  /* use exact schema given */
476  namespaceId = get_namespace_oid(newRelation->schemaname, false);
477  /* we do not check for USAGE rights here! */
478  }
479  else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
480  {
481  /* Initialize temp namespace */
483  return myTempNamespace;
484  }
485  else
486  {
487  /* use the default creation namespace */
490  {
491  /* Need to initialize temp namespace */
493  return myTempNamespace;
494  }
495  namespaceId = activeCreationNamespace;
496  if (!OidIsValid(namespaceId))
497  ereport(ERROR,
498  (errcode(ERRCODE_UNDEFINED_SCHEMA),
499  errmsg("no schema has been selected to create in")));
500  }
501 
502  /* Note: callers will check for CREATE rights when appropriate */
503 
504  return namespaceId;
505 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3043
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3915
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
static void recomputeNamespacePath(void)
Definition: namespace.c:3737
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
static Oid activeCreationNamespace
Definition: namespace.c:141
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
static bool activeTempCreationPending
Definition: namespace.c:144
Oid MyDatabaseId
Definition: globals.c:85
#define ereport(elevel,...)
Definition: elog.h:144
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:824
char * catalogname
Definition: primnodes.h:66

◆ RangeVarGetRelidExtended()

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

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

239 {
240  uint64 inval_count;
241  Oid relId;
242  Oid oldRelId = InvalidOid;
243  bool retry = false;
244  bool missing_ok = (flags & RVR_MISSING_OK) != 0;
245 
246  /* verify that flags do no conflict */
247  Assert(!((flags & RVR_NOWAIT) && (flags & RVR_SKIP_LOCKED)));
248 
249  /*
250  * We check the catalog name and then ignore it.
251  */
252  if (relation->catalogname)
253  {
254  if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
255  ereport(ERROR,
256  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
257  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
258  relation->catalogname, relation->schemaname,
259  relation->relname)));
260  }
261 
262  /*
263  * DDL operations can change the results of a name lookup. Since all such
264  * operations will generate invalidation messages, we keep track of
265  * whether any such messages show up while we're performing the operation,
266  * and retry until either (1) no more invalidation messages show up or (2)
267  * the answer doesn't change.
268  *
269  * But if lockmode = NoLock, then we assume that either the caller is OK
270  * with the answer changing under them, or that they already hold some
271  * appropriate lock, and therefore return the first answer we get without
272  * checking for invalidation messages. Also, if the requested lock is
273  * already held, LockRelationOid will not AcceptInvalidationMessages, so
274  * we may fail to notice a change. We could protect against that case by
275  * calling AcceptInvalidationMessages() before beginning this loop, but
276  * that would add a significant amount overhead, so for now we don't.
277  */
278  for (;;)
279  {
280  /*
281  * Remember this value, so that, after looking up the relation name
282  * and locking its OID, we can check whether any invalidation messages
283  * have been processed that might require a do-over.
284  */
285  inval_count = SharedInvalidMessageCounter;
286 
287  /*
288  * Some non-default relpersistence value may have been specified. The
289  * parser never generates such a RangeVar in simple DML, but it can
290  * happen in contexts such as "CREATE TEMP TABLE foo (f1 int PRIMARY
291  * KEY)". Such a command will generate an added CREATE INDEX
292  * operation, which must be careful to find the temp table, even when
293  * pg_temp is not first in the search path.
294  */
295  if (relation->relpersistence == RELPERSISTENCE_TEMP)
296  {
298  relId = InvalidOid; /* this probably can't happen? */
299  else
300  {
301  if (relation->schemaname)
302  {
303  Oid namespaceId;
304 
305  namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
306 
307  /*
308  * For missing_ok, allow a non-existent schema name to
309  * return InvalidOid.
310  */
311  if (namespaceId != myTempNamespace)
312  ereport(ERROR,
313  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
314  errmsg("temporary tables cannot specify a schema name")));
315  }
316 
317  relId = get_relname_relid(relation->relname, myTempNamespace);
318  }
319  }
320  else if (relation->schemaname)
321  {
322  Oid namespaceId;
323 
324  /* use exact schema given */