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

Go to the source code of this file.

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, bool include_out_arguments, int pronargs, int **argnumbers)
 
Oid RangeVarGetRelidExtended (const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
 
Oid RangeVarGetCreationNamespace (const RangeVar *newRelation)
 
Oid RangeVarGetAndCheckCreationNamespace (RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
 
void RangeVarAdjustRelationPersistence (RangeVar *newRelation, Oid nspid)
 
Oid RelnameGetRelid (const char *relname)
 
bool RelationIsVisible (Oid relid)
 
Oid TypenameGetTypid (const char *typname)
 
Oid TypenameGetTypidExtended (const char *typname, bool temp_ok)
 
bool TypeIsVisible (Oid typid)
 
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok)
 
bool OperatorIsVisible (Oid oprid)
 
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
 
bool OpclassIsVisible (Oid opcid)
 
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
 
bool OpfamilyIsVisible (Oid opfid)
 
static Oid lookup_collation (const char *collname, Oid collnamespace, int32 encoding)
 
Oid CollationGetCollid (const char *collname)
 
bool CollationIsVisible (Oid collid)
 
Oid ConversionGetConid (const char *conname)
 
bool ConversionIsVisible (Oid conid)
 
Oid get_statistics_object_oid (List *names, bool missing_ok)
 
bool StatisticsObjIsVisible (Oid relid)
 
Oid get_ts_parser_oid (List *names, bool missing_ok)
 
bool TSParserIsVisible (Oid prsId)
 
Oid get_ts_dict_oid (List *names, bool missing_ok)
 
bool TSDictionaryIsVisible (Oid dictId)
 
Oid get_ts_template_oid (List *names, bool missing_ok)
 
bool TSTemplateIsVisible (Oid tmplId)
 
Oid get_ts_config_oid (List *names, bool missing_ok)
 
bool TSConfigIsVisible (Oid cfgid)
 
void DeconstructQualifiedName (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 *collname, bool missing_ok)
 
Oid get_conversion_oid (List *conname, bool missing_ok)
 
Oid FindDefaultConversionProc (int32 for_encoding, int32 to_encoding)
 
void AtEOXact_Namespace (bool isCommit, bool parallel)
 
void AtEOSubXact_Namespace (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void ResetTempTableNamespace (void)
 
bool check_search_path (char **newval, void **extra, GucSource source)
 
void assign_search_path (const char *newval, void *extra)
 
void InitializeSearchPath (void)
 
Listfetch_search_path (bool includeImplicit)
 
int fetch_search_path_array (Oid *sarray, int sarray_len)
 
Datum pg_table_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_type_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_function_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_operator_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_opclass_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_opfamily_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_collation_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_conversion_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_statistics_obj_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_parser_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_dict_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_template_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_config_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_my_temp_schema (PG_FUNCTION_ARGS)
 
Datum pg_is_other_temp_schema (PG_FUNCTION_ARGS)
 

Variables

static ListactiveSearchPath = NIL
 
static Oid activeCreationNamespace = InvalidOid
 
static bool activeTempCreationPending = false
 
static uint64 activePathGeneration = 1
 
static ListbaseSearchPath = NIL
 
static Oid baseCreationNamespace = InvalidOid
 
static bool baseTempCreationPending = false
 
static Oid namespaceUser = InvalidOid
 
static bool baseSearchPathValid = true
 
static 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:
MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
2 * sizeof(Oid))
#define MAXALIGN(LEN)
Definition: c.h:747
unsigned int Oid
Definition: postgres_ext.h:31

Function Documentation

◆ AccessTempTableNamespace()

static void AccessTempTableNamespace ( bool  force)
static

Definition at line 3958 of file namespace.c.

3959 {
3960  /*
3961  * Make note that this temporary namespace has been accessed in this
3962  * transaction.
3963  */
3965 
3966  /*
3967  * If the caller attempting to access a temporary schema expects the
3968  * creation of the namespace to be pending and should be enforced, then go
3969  * through the creation.
3970  */
3971  if (!force && OidIsValid(myTempNamespace))
3972  return;
3973 
3974  /*
3975  * The temporary tablespace does not exist yet and is wanted, so
3976  * initialize it.
3977  */
3979 }
#define OidIsValid(objectId)
Definition: c.h:711
static Oid myTempNamespace
Definition: namespace.c:190
static void InitTempTableNamespace(void)
Definition: namespace.c:3986
int MyXactFlags
Definition: xact.c:135
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition: xact.h:102

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

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

◆ assign_search_path()

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

Definition at line 4353 of file namespace.c.

4354 {
4355  /*
4356  * We mark the path as needing recomputation, but don't do anything until
4357  * it's needed. This avoids trying to do database access during GUC
4358  * initialization, or outside a transaction.
4359  */
4360  baseSearchPathValid = false;
4361 }
static bool baseSearchPathValid
Definition: namespace.c:162

References baseSearchPathValid.

◆ AtEOSubXact_Namespace()

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

Definition at line 4175 of file namespace.c.

4177 {
4178  OverrideStackEntry *entry;
4179 
4180  if (myTempNamespaceSubID == mySubid)
4181  {
4182  if (isCommit)
4183  myTempNamespaceSubID = parentSubid;
4184  else
4185  {
4187  /* TEMP namespace creation failed, so reset state */
4190  baseSearchPathValid = false; /* need to rebuild list */
4191 
4192  /*
4193  * Reset the temporary namespace flag in MyProc. We assume that
4194  * this operation is atomic.
4195  *
4196  * Because this subtransaction is aborting, the pg_namespace row
4197  * is not visible to anyone else anyway, but that doesn't matter:
4198  * it's not a problem if objects contained in this namespace are
4199  * removed concurrently.
4200  */
4202  }
4203  }
4204 
4205  /*
4206  * Clean up if someone failed to do PopOverrideSearchPath
4207  */
4208  while (overrideStack)
4209  {
4212  break;
4213  if (isCommit)
4214  elog(WARNING, "leaked override search path");
4216  list_free(entry->searchPath);
4217  pfree(entry);
4218  /* Always bump generation --- see note in recomputeNamespacePath */
4220  }
4221 
4222  /* Activate the next level down. */
4223  if (overrideStack)
4224  {
4226  activeSearchPath = entry->searchPath;
4228  activeTempCreationPending = false; /* XXX is this OK? */
4229 
4230  /*
4231  * It's probably unnecessary to bump generation here, but this should
4232  * not be a performance-critical case, so better to be over-cautious.
4233  */
4235  }
4236  else
4237  {
4238  /* If not baseSearchPathValid, this is useless but harmless */
4242 
4243  /*
4244  * If we popped an override stack entry, then we already bumped the
4245  * generation above. If we did not, then the above assignments did
4246  * nothing and we need not bump the generation.
4247  */
4248  }
4249 }
#define InvalidSubTransactionId
Definition: c.h:594
#define WARNING
Definition: elog.h:32
List * list_delete_first(List *list)
Definition: list.c:942
void list_free(List *list)
Definition: list.c:1545
void pfree(void *pointer)
Definition: mcxt.c:1306
static bool baseTempCreationPending
Definition: namespace.c:157
static Oid baseCreationNamespace
Definition: namespace.c:155
static Oid activeCreationNamespace
Definition: namespace.c:143
static List * activeSearchPath
Definition: namespace.c:140
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:194
static Oid myTempToastNamespace
Definition: namespace.c:192
static List * overrideStack
Definition: namespace.c:173
static bool activeTempCreationPending
Definition: namespace.c:146
static uint64 activePathGeneration
Definition: namespace.c:149
static List * baseSearchPath
Definition: namespace.c:153
#define linitial(l)
Definition: pg_list.h:176
#define InvalidOid
Definition: postgres_ext.h:36
PGPROC * MyProc
Definition: proc.c:68
Oid tempNamespaceId
Definition: proc.h:201
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:913

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4107 of file namespace.c.

4108 {
4109  /*
4110  * If we abort the transaction in which a temp namespace was selected,
4111  * we'll have to do any creation or cleanout work over again. So, just
4112  * forget the namespace entirely until next time. On the other hand, if
4113  * we commit then register an exit callback to clean out the temp tables
4114  * at backend shutdown. (We only want to register the callback once per
4115  * session, so this is a good place to do it.)
4116  */
4117  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
4118  {
4119  if (isCommit)
4121  else
4122  {
4125  baseSearchPathValid = false; /* need to rebuild list */
4126 
4127  /*
4128  * Reset the temporary namespace flag in MyProc. We assume that
4129  * this operation is atomic.
4130  *
4131  * Because this transaction is aborting, the pg_namespace row is
4132  * not visible to anyone else anyway, but that doesn't matter:
4133  * it's not a problem if objects contained in this namespace are
4134  * removed concurrently.
4135  */
4137  }
4139  }
4140 
4141  /*
4142  * Clean up if someone failed to do PopOverrideSearchPath
4143  */
4144  if (overrideStack)
4145  {
4146  if (isCommit)
4147  elog(WARNING, "leaked override search path");
4148  while (overrideStack)
4149  {
4150  OverrideStackEntry *entry;
4151 
4154  list_free(entry->searchPath);
4155  pfree(entry);
4156  }
4157  /* If not baseSearchPathValid, this is useless but harmless */
4161  /* Always bump generation --- see note in recomputeNamespacePath */
4163  }
4164 }
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4286

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

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

◆ check_search_path()

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

Definition at line 4319 of file namespace.c.

4320 {
4321  char *rawname;
4322  List *namelist;
4323 
4324  /* Need a modifiable copy of string */
4325  rawname = pstrdup(*newval);
4326 
4327  /* Parse string into list of identifiers */
4328  if (!SplitIdentifierString(rawname, ',', &namelist))
4329  {
4330  /* syntax error in name list */
4331  GUC_check_errdetail("List syntax is invalid.");
4332  pfree(rawname);
4333  list_free(namelist);
4334  return false;
4335  }
4336 
4337  /*
4338  * We used to try to check that the named schemas exist, but there are
4339  * many valid use-cases for having search_path settings that include
4340  * schemas that don't exist; and often, we are not inside a transaction
4341  * here and so can't consult the system catalogs anyway. So now, the only
4342  * requirement is syntactic validity of the identifier list.
4343  */
4344 
4345  pfree(rawname);
4346  list_free(namelist);
4347 
4348  return true;
4349 }
#define newval
#define GUC_check_errdetail
Definition: guc.h:434
char * pstrdup(const char *in)
Definition: mcxt.c:1483
Definition: pg_list.h:52
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3712

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

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 3010 of file namespace.c.

3011 {
3012  /* disallow renaming into or out of temp schemas */
3013  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
3014  ereport(ERROR,
3015  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3016  errmsg("cannot move objects into or out of temporary schemas")));
3017 
3018  /* same for TOAST schema */
3019  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
3020  ereport(ERROR,
3021  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3022  errmsg("cannot move objects into or out of TOAST schema")));
3023 }
int errcode(int sqlerrcode)
Definition: elog.c:695
int errmsg(const char *fmt,...)
Definition: elog.c:906
#define ERROR
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:145
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3238

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

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

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3280 of file namespace.c.

3281 {
3282  PGPROC *proc;
3283  int backendId;
3284 
3286 
3287  backendId = GetTempNamespaceBackendId(namespaceId);
3288 
3289  /* No such namespace, or its name shows it's not temp? */
3290  if (backendId == InvalidBackendId)
3291  return TEMP_NAMESPACE_NOT_TEMP;
3292 
3293  /* Is the backend alive? */
3294  proc = BackendIdGetProc(backendId);
3295  if (proc == NULL)
3296  return TEMP_NAMESPACE_IDLE;
3297 
3298  /* Is the backend connected to the same database we are looking at? */
3299  if (proc->databaseId != MyDatabaseId)
3300  return TEMP_NAMESPACE_IDLE;
3301 
3302  /* Does the backend own the temporary namespace? */
3303  if (proc->tempNamespaceId != namespaceId)
3304  return TEMP_NAMESPACE_IDLE;
3305 
3306  /* Yup, so namespace is busy */
3307  return TEMP_NAMESPACE_IN_USE;
3308 }
#define InvalidBackendId
Definition: backendid.h:23
Oid MyDatabaseId
Definition: globals.c:89
Assert(fmt[strlen(fmt) - 1] !='\n')
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3317
@ TEMP_NAMESPACE_IN_USE
Definition: namespace.h:48
@ TEMP_NAMESPACE_NOT_TEMP
Definition: namespace.h:46
@ TEMP_NAMESPACE_IDLE
Definition: namespace.h:47
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:385
Definition: proc.h:162
Oid databaseId
Definition: proc.h:198

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

Referenced by do_autovacuum().

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2057 of file namespace.c.

2058 {
2059  int32 dbencoding = GetDatabaseEncoding();
2060  ListCell *l;
2061 
2063 
2064  foreach(l, activeSearchPath)
2065  {
2066  Oid namespaceId = lfirst_oid(l);
2067  Oid collid;
2068 
2069  if (namespaceId == myTempNamespace)
2070  continue; /* do not look in temp namespace */
2071 
2072  collid = lookup_collation(collname, namespaceId, dbencoding);
2073  if (OidIsValid(collid))
2074  return collid;
2075  }
2076 
2077  /* Not found in path */
2078  return InvalidOid;
2079 }
signed int int32
Definition: c.h:430
int GetDatabaseEncoding(void)
Definition: mbutils.c:1210
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:2006
static void recomputeNamespacePath(void)
Definition: namespace.c:3780
#define lfirst_oid(lc)
Definition: pg_list.h:172

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

Referenced by CollationIsVisible().

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2091 of file namespace.c.

2092 {
2093  HeapTuple colltup;
2094  Form_pg_collation collform;
2095  Oid collnamespace;
2096  bool visible;
2097 
2098  colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
2099  if (!HeapTupleIsValid(colltup))
2100  elog(ERROR, "cache lookup failed for collation %u", collid);
2101  collform = (Form_pg_collation) GETSTRUCT(colltup);
2102 
2104 
2105  /*
2106  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2107  * the system namespace are surely in the path and so we needn't even do
2108  * list_member_oid() for them.
2109  */
2110  collnamespace = collform->collnamespace;
2111  if (collnamespace != PG_CATALOG_NAMESPACE &&
2112  !list_member_oid(activeSearchPath, collnamespace))
2113  visible = false;
2114  else
2115  {
2116  /*
2117  * If it is in the path, it might still not be visible; it could be
2118  * hidden by another collation of the same name earlier in the path,
2119  * or it might not work with the current DB encoding. So we must do a
2120  * slow check to see if this collation would be found by
2121  * CollationGetCollid.
2122  */
2123  char *collname = NameStr(collform->collname);
2124 
2125  visible = (CollationGetCollid(collname) == collid);
2126  }
2127 
2128  ReleaseSysCache(colltup);
2129 
2130  return visible;
2131 }
#define NameStr(name)
Definition: c.h:682
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:721
Oid CollationGetCollid(const char *collname)
Definition: namespace.c:2057
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:57
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:600
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1221
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1173
@ COLLOID
Definition: syscache.h:50

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

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2142 of file namespace.c.

2143 {
2144  Oid conid;
2145  ListCell *l;
2146 
2148 
2149  foreach(l, activeSearchPath)
2150  {
2151  Oid namespaceId = lfirst_oid(l);
2152 
2153  if (namespaceId == myTempNamespace)
2154  continue; /* do not look in temp namespace */
2155 
2156  conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2157  PointerGetDatum(conname),
2158  ObjectIdGetDatum(namespaceId));
2159  if (OidIsValid(conid))
2160  return conid;
2161  }
2162 
2163  /* Not found in path */
2164  return InvalidOid;
2165 }
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:670
@ CONNAMENSP
Definition: syscache.h:52
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:199

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

Referenced by ConversionIsVisible().

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2174 of file namespace.c.

2175 {
2176  HeapTuple contup;
2177  Form_pg_conversion conform;
2178  Oid connamespace;
2179  bool visible;
2180 
2181  contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
2182  if (!HeapTupleIsValid(contup))
2183  elog(ERROR, "cache lookup failed for conversion %u", conid);
2184  conform = (Form_pg_conversion) GETSTRUCT(contup);
2185 
2187 
2188  /*
2189  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2190  * the system namespace are surely in the path and so we needn't even do
2191  * list_member_oid() for them.
2192  */
2193  connamespace = conform->connamespace;
2194  if (connamespace != PG_CATALOG_NAMESPACE &&
2195  !list_member_oid(activeSearchPath, connamespace))
2196  visible = false;
2197  else
2198  {
2199  /*
2200  * If it is in the path, it might still not be visible; it could be
2201  * hidden by another conversion of the same name earlier in the path.
2202  * So we must do a slow check to see if this conversion would be found
2203  * by ConversionGetConid.
2204  */
2205  char *conname = NameStr(conform->conname);
2206 
2207  visible = (ConversionGetConid(conname) == conid);
2208  }
2209 
2210  ReleaseSysCache(contup);
2211 
2212  return visible;
2213 }
Oid ConversionGetConid(const char *conname)
Definition: namespace.c:2142
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:61
@ CONVOID
Definition: syscache.h:54

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

Referenced by getObjectDescription(), and pg_conversion_is_visible().

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3440 of file namespace.c.

3441 {
3442  OverrideSearchPath *result;
3443 
3444  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3445  result->schemas = list_copy(path->schemas);
3446  result->addCatalog = path->addCatalog;
3447  result->addTemp = path->addTemp;
3448  result->generation = path->generation;
3449 
3450  return result;
3451 }
List * list_copy(const List *oldlist)
Definition: list.c:1572
void * palloc(Size size)
Definition: mcxt.c:1199

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

Referenced by CopyCachedPlan().

◆ DeconstructQualifiedName()

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

Definition at line 2852 of file namespace.c.

2855 {
2856  char *catalogname;
2857  char *schemaname = NULL;
2858  char *objname = NULL;
2859 
2860  switch (list_length(names))
2861  {
2862  case 1:
2863  objname = strVal(linitial(names));
2864  break;
2865  case 2:
2866  schemaname = strVal(linitial(names));
2867  objname = strVal(lsecond(names));
2868  break;
2869  case 3:
2870  catalogname = strVal(linitial(names));
2871  schemaname = strVal(lsecond(names));
2872  objname = strVal(lthird(names));
2873 
2874  /*
2875  * We check the catalog name and then ignore it.
2876  */
2877  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2878  ereport(ERROR,
2879  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2880  errmsg("cross-database references are not implemented: %s",
2881  NameListToString(names))));
2882  break;
2883  default:
2884  ereport(ERROR,
2885  (errcode(ERRCODE_SYNTAX_ERROR),
2886  errmsg("improper qualified name (too many dotted names): %s",
2887  NameListToString(names))));
2888  break;
2889  }
2890 
2891  *nspname_p = schemaname;
2892  *objname_p = objname;
2893 }
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2981
char * NameListToString(List *names)
Definition: namespace.c:3145
static int list_length(const List *l)
Definition: pg_list.h:150
#define lthird(l)
Definition: pg_list.h:186
#define lsecond(l)
Definition: pg_list.h:181
#define strVal(v)
Definition: value.h:82

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

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4428 of file namespace.c.

4429 {
4430  List *result;
4431 
4433 
4434  /*
4435  * If the temp namespace should be first, force it to exist. This is so
4436  * that callers can trust the result to reflect the actual default
4437  * creation namespace. It's a bit bogus to do this here, since
4438  * current_schema() is supposedly a stable function without side-effects,
4439  * but the alternatives seem worse.
4440  */
4442  {
4445  }
4446 
4447  result = list_copy(activeSearchPath);
4448  if (!includeImplicit)
4449  {
4450  while (result && linitial_oid(result) != activeCreationNamespace)
4451  result = list_delete_first(result);
4452  }
4453 
4454  return result;
4455 }
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3958
#define linitial_oid(l)
Definition: pg_list.h:178

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

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

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4468 of file namespace.c.

4469 {
4470  int count = 0;
4471  ListCell *l;
4472 
4474 
4475  foreach(l, activeSearchPath)
4476  {
4477  Oid namespaceId = lfirst_oid(l);
4478 
4479  if (namespaceId == myTempNamespace)
4480  continue; /* do not include temp namespace */
4481 
4482  if (count < sarray_len)
4483  sarray[count] = namespaceId;
4484  count++;
4485  }
4486 
4487  return count;
4488 }

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

Referenced by make_oper_cache_key().

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3753 of file namespace.c.

3754 {
3755  Oid proc;
3756  ListCell *l;
3757 
3759 
3760  foreach(l, activeSearchPath)
3761  {
3762  Oid namespaceId = lfirst_oid(l);
3763 
3764  if (namespaceId == myTempNamespace)
3765  continue; /* do not look in temp namespace */
3766 
3767  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3768  if (OidIsValid(proc))
3769  return proc;
3770  }
3771 
3772  /* Not found in path */
3773  return InvalidOid;
3774 }
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)

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

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

◆ FuncnameGetCandidates()

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

Definition at line 952 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1456 of file namespace.c.

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

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

Referenced by format_procedure_extended(), and pg_function_is_visible().

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3644 of file namespace.c.

3645 {
3646  char *schemaname;
3647  char *collation_name;
3648  int32 dbencoding = GetDatabaseEncoding();
3649  Oid namespaceId;
3650  Oid colloid;
3651  ListCell *l;
3652 
3653  /* deconstruct the name list */
3654  DeconstructQualifiedName(collname, &schemaname, &collation_name);
3655 
3656  if (schemaname)
3657  {
3658  /* use exact schema given */
3659  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3660  if (missing_ok && !OidIsValid(namespaceId))
3661  return InvalidOid;
3662 
3663  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3664  if (OidIsValid(colloid))
3665  return colloid;
3666  }
3667  else
3668  {
3669  /* search for it in search path */
3671 
3672  foreach(l, activeSearchPath)
3673  {
3674  namespaceId = lfirst_oid(l);
3675 
3676  if (namespaceId == myTempNamespace)
3677  continue; /* do not look in temp namespace */
3678 
3679  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3680  if (OidIsValid(colloid))
3681  return colloid;
3682  }
3683  }
3684 
3685  /* Not found in path */
3686  if (!missing_ok)
3687  ereport(ERROR,
3688  (errcode(ERRCODE_UNDEFINED_OBJECT),
3689  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3690  NameListToString(collname), GetDatabaseEncodingName())));
3691  return InvalidOid;
3692 }
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1216

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

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

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 3698 of file namespace.c.

3699 {
3700  char *schemaname;
3701  char *conversion_name;
3702  Oid namespaceId;
3703  Oid conoid = InvalidOid;
3704  ListCell *l;
3705 
3706  /* deconstruct the name list */
3707  DeconstructQualifiedName(conname, &schemaname, &conversion_name);
3708 
3709  if (schemaname)
3710  {
3711  /* use exact schema given */
3712  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3713  if (missing_ok && !OidIsValid(namespaceId))
3714  conoid = InvalidOid;
3715  else
3716  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3717  PointerGetDatum(conversion_name),
3718  ObjectIdGetDatum(namespaceId));
3719  }
3720  else
3721  {
3722  /* search for it in search path */
3724 
3725  foreach(l, activeSearchPath)
3726  {
3727  namespaceId = lfirst_oid(l);
3728 
3729  if (namespaceId == myTempNamespace)
3730  continue; /* do not look in temp namespace */
3731 
3732  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3733  PointerGetDatum(conversion_name),
3734  ObjectIdGetDatum(namespaceId));
3735  if (OidIsValid(conoid))
3736  return conoid;
3737  }
3738  }
3739 
3740  /* Not found in path */
3741  if (!OidIsValid(conoid) && !missing_ok)
3742  ereport(ERROR,
3743  (errcode(ERRCODE_UNDEFINED_OBJECT),
3744  errmsg("conversion \"%s\" does not exist",
3745  NameListToString(conname))));
3746  return conoid;
3747 }

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

Referenced by get_object_address().

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2221 of file namespace.c.

2222 {
2223  char *schemaname;
2224  char *stats_name;
2225  Oid namespaceId;
2226  Oid stats_oid = InvalidOid;
2227  ListCell *l;
2228 
2229  /* deconstruct the name list */
2230  DeconstructQualifiedName(names, &schemaname, &stats_name);
2231 
2232  if (schemaname)
2233  {
2234  /* use exact schema given */
2235  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2236  if (missing_ok && !OidIsValid(namespaceId))
2237  stats_oid = InvalidOid;
2238  else
2239  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2240  PointerGetDatum(stats_name),
2241  ObjectIdGetDatum(namespaceId));
2242  }
2243  else
2244  {
2245  /* search for it in search path */
2247 
2248  foreach(l, activeSearchPath)
2249  {
2250  namespaceId = lfirst_oid(l);
2251 
2252  if (namespaceId == myTempNamespace)
2253  continue; /* do not look in temp namespace */
2254  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2255  PointerGetDatum(stats_name),
2256  ObjectIdGetDatum(namespaceId));
2257  if (OidIsValid(stats_oid))
2258  break;
2259  }
2260  }
2261 
2262  if (!OidIsValid(stats_oid) && !missing_ok)
2263  ereport(ERROR,
2264  (errcode(ERRCODE_UNDEFINED_OBJECT),
2265  errmsg("statistics object \"%s\" does not exist",
2266  NameListToString(names))));
2267 
2268  return stats_oid;
2269 }
@ STATEXTNAMENSP
Definition: syscache.h:95

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

Referenced by AlterStatistics(), and get_object_address().

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2722 of file namespace.c.

2723 {
2724  char *schemaname;
2725  char *config_name;
2726  Oid namespaceId;
2727  Oid cfgoid = InvalidOid;
2728  ListCell *l;
2729 
2730  /* deconstruct the name list */
2731  DeconstructQualifiedName(names, &schemaname, &config_name);
2732 
2733  if (schemaname)
2734  {
2735  /* use exact schema given */
2736  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2737  if (missing_ok && !OidIsValid(namespaceId))
2738  cfgoid = InvalidOid;
2739  else
2740  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2741  PointerGetDatum(config_name),
2742  ObjectIdGetDatum(namespaceId));
2743  }
2744  else
2745  {
2746  /* search for it in search path */
2748 
2749  foreach(l, activeSearchPath)
2750  {
2751  namespaceId = lfirst_oid(l);
2752 
2753  if (namespaceId == myTempNamespace)
2754  continue; /* do not look in temp namespace */
2755 
2756  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2757  PointerGetDatum(config_name),
2758  ObjectIdGetDatum(namespaceId));
2759  if (OidIsValid(cfgoid))
2760  break;
2761  }
2762  }
2763 
2764  if (!OidIsValid(cfgoid) && !missing_ok)
2765  ereport(ERROR,
2766  (errcode(ERRCODE_UNDEFINED_OBJECT),
2767  errmsg("text search configuration \"%s\" does not exist",
2768  NameListToString(names))));
2769 
2770  return cfgoid;
2771 }
@ TSCONFIGNAMENSP
Definition: syscache.h:105

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

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

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2469 of file namespace.c.

2470 {
2471  char *schemaname;
2472  char *dict_name;
2473  Oid namespaceId;
2474  Oid dictoid = InvalidOid;
2475  ListCell *l;
2476 
2477  /* deconstruct the name list */
2478  DeconstructQualifiedName(names, &schemaname, &dict_name);
2479 
2480  if (schemaname)
2481  {
2482  /* use exact schema given */
2483  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2484  if (missing_ok && !OidIsValid(namespaceId))
2485  dictoid = InvalidOid;
2486  else
2487  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2488  PointerGetDatum(dict_name),
2489  ObjectIdGetDatum(namespaceId));
2490  }
2491  else
2492  {
2493  /* search for it in search path */
2495 
2496  foreach(l, activeSearchPath)
2497  {
2498  namespaceId = lfirst_oid(l);
2499 
2500  if (namespaceId == myTempNamespace)
2501  continue; /* do not look in temp namespace */
2502 
2503  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2504  PointerGetDatum(dict_name),
2505  ObjectIdGetDatum(namespaceId));
2506  if (OidIsValid(dictoid))
2507  break;
2508  }
2509  }
2510 
2511  if (!OidIsValid(dictoid) && !missing_ok)
2512  ereport(ERROR,
2513  (errcode(ERRCODE_UNDEFINED_OBJECT),
2514  errmsg("text search dictionary \"%s\" does not exist",
2515  NameListToString(names))));
2516 
2517  return dictoid;
2518 }
@ TSDICTNAMENSP
Definition: syscache.h:107

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

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

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2343 of file namespace.c.

2344 {
2345  char *schemaname;
2346  char *parser_name;
2347  Oid namespaceId;
2348  Oid prsoid = InvalidOid;
2349  ListCell *l;
2350 
2351  /* deconstruct the name list */
2352  DeconstructQualifiedName(names, &schemaname, &parser_name);
2353 
2354  if (schemaname)
2355  {
2356  /* use exact schema given */
2357  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2358  if (missing_ok && !OidIsValid(namespaceId))
2359  prsoid = InvalidOid;
2360  else
2361  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2362  PointerGetDatum(parser_name),
2363  ObjectIdGetDatum(namespaceId));
2364  }
2365  else
2366  {
2367  /* search for it in search path */
2369 
2370  foreach(l, activeSearchPath)
2371  {
2372  namespaceId = lfirst_oid(l);
2373 
2374  if (namespaceId == myTempNamespace)
2375  continue; /* do not look in temp namespace */
2376 
2377  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2378  PointerGetDatum(parser_name),
2379  ObjectIdGetDatum(namespaceId));
2380  if (OidIsValid(prsoid))
2381  break;
2382  }
2383  }
2384 
2385  if (!OidIsValid(prsoid) && !missing_ok)
2386  ereport(ERROR,
2387  (errcode(ERRCODE_UNDEFINED_OBJECT),
2388  errmsg("text search parser \"%s\" does not exist",
2389  NameListToString(names))));
2390 
2391  return prsoid;
2392 }
@ TSPARSERNAMENSP
Definition: syscache.h:109

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

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

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2596 of file namespace.c.

2597 {
2598  char *schemaname;
2599  char *template_name;
2600  Oid namespaceId;
2601  Oid tmploid = InvalidOid;
2602  ListCell *l;
2603 
2604  /* deconstruct the name list */
2605  DeconstructQualifiedName(names, &schemaname, &template_name);
2606 
2607  if (schemaname)
2608  {
2609  /* use exact schema given */
2610  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2611  if (missing_ok && !OidIsValid(namespaceId))
2612  tmploid = InvalidOid;
2613  else
2614  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2615  PointerGetDatum(template_name),
2616  ObjectIdGetDatum(namespaceId));
2617  }
2618  else
2619  {
2620  /* search for it in search path */
2622 
2623  foreach(l, activeSearchPath)
2624  {
2625  namespaceId = lfirst_oid(l);
2626 
2627  if (namespaceId == myTempNamespace)
2628  continue; /* do not look in temp namespace */
2629 
2630  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2631  PointerGetDatum(template_name),
2632  ObjectIdGetDatum(namespaceId));
2633  if (OidIsValid(tmploid))
2634  break;
2635  }
2636  }
2637 
2638  if (!OidIsValid(tmploid) && !missing_ok)
2639  ereport(ERROR,
2640  (errcode(ERRCODE_UNDEFINED_OBJECT),
2641  errmsg("text search template \"%s\" does not exist",
2642  NameListToString(names))));
2643 
2644  return tmploid;
2645 }
@ TSTEMPLATENAMENSP
Definition: syscache.h:111

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

Referenced by DefineTSDictionary(), and get_object_address().

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3403 of file namespace.c.

3404 {
3405  OverrideSearchPath *result;
3406  List *schemas;
3407  MemoryContext oldcxt;
3408 
3410 
3411  oldcxt = MemoryContextSwitchTo(context);
3412 
3413  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3414  schemas = list_copy(activeSearchPath);
3415  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3416  {
3417  if (linitial_oid(schemas) == myTempNamespace)
3418  result->addTemp = true;
3419  else
3420  {
3421  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3422  result->addCatalog = true;
3423  }
3424  schemas = list_delete_first(schemas);
3425  }
3426  result->schemas = schemas;
3427  result->generation = activePathGeneration;
3428 
3429  MemoryContextSwitchTo(oldcxt);
3430 
3431  return result;
3432 }
void * palloc0(Size size)
Definition: mcxt.c:1230
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:135

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

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3317 of file namespace.c.

3318 {
3319  int result;
3320  char *nspname;
3321 
3322  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3323  nspname = get_namespace_name(namespaceId);
3324  if (!nspname)
3325  return InvalidBackendId; /* no such namespace? */
3326  if (strncmp(nspname, "pg_temp_", 8) == 0)
3327  result = atoi(nspname + 8);
3328  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3329  result = atoi(nspname + 14);
3330  else
3331  result = InvalidBackendId;
3332  pfree(nspname);
3333  return result;
3334 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3331

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

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

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3356 of file namespace.c.

3357 {
3358  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3359  *tempNamespaceId = myTempNamespace;
3360  *tempToastNamespaceId = myTempToastNamespace;
3361 }

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3342 of file namespace.c.

3343 {
3345  return myTempToastNamespace;
3346 }

References Assert(), myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4369 of file namespace.c.

4370 {
4372  {
4373  /*
4374  * In bootstrap mode, the search path must be 'pg_catalog' so that
4375  * tables are created in the proper namespace; ignore the GUC setting.
4376  */
4377  MemoryContext oldcxt;
4378 
4380  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4381  MemoryContextSwitchTo(oldcxt);
4382  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4383  baseTempCreationPending = false;
4384  baseSearchPathValid = true;
4389  activePathGeneration++; /* pro forma */
4390  }
4391  else
4392  {
4393  /*
4394  * In normal mode, arrange for a callback on any syscache invalidation
4395  * of pg_namespace rows.
4396  */
4399  (Datum) 0);
4400  /* Force search path to be recomputed on next use */
4401  baseSearchPathValid = false;
4402  }
4403 }
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1519
MemoryContext TopMemoryContext
Definition: mcxt.c:130
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:402
Oid GetUserId(void)
Definition: miscinit.c:497
static Oid namespaceUser
Definition: namespace.c:159
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4410
#define list_make1_oid(x1)
Definition: pg_list.h:240
@ NAMESPACEOID
Definition: syscache.h:70

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

Referenced by InitPostgres().

◆ InitTempTableNamespace()

static void InitTempTableNamespace ( void  )
static

Definition at line 3986 of file namespace.c.

3987 {
3988  char namespaceName[NAMEDATALEN];
3989  Oid namespaceId;
3990  Oid toastspaceId;
3991 
3993 
3994  /*
3995  * First, do permission check to see if we are authorized to make temp
3996  * tables. We use a nonstandard error message here since "databasename:
3997  * permission denied" might be a tad cryptic.
3998  *
3999  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
4000  * that's necessary since current user ID could change during the session.
4001  * But there's no need to make the namespace in the first place until a
4002  * temp table creation request is made by someone with appropriate rights.
4003  */
4004  if (object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(),
4006  ereport(ERROR,
4007  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4008  errmsg("permission denied to create temporary tables in database \"%s\"",
4010 
4011  /*
4012  * Do not allow a Hot Standby session to make temp tables. Aside from
4013  * problems with modifying the system catalogs, there is a naming
4014  * conflict: pg_temp_N belongs to the session with BackendId N on the
4015  * primary, not to a hot standby session with the same BackendId. We
4016  * should not be able to get here anyway due to XactReadOnly checks, but
4017  * let's just make real sure. Note that this also backstops various
4018  * operations that allow XactReadOnly transactions to modify temp tables;
4019  * they'd need RecoveryInProgress checks if not for this.
4020  */
4021  if (RecoveryInProgress())
4022  ereport(ERROR,
4023  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
4024  errmsg("cannot create temporary tables during recovery")));
4025 
4026  /* Parallel workers can't create temporary tables, either. */
4027  if (IsParallelWorker())
4028  ereport(ERROR,
4029  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
4030  errmsg("cannot create temporary tables during a parallel operation")));
4031 
4032  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
4033 
4034  namespaceId = get_namespace_oid(namespaceName, true);
4035  if (!OidIsValid(namespaceId))
4036  {
4037  /*
4038  * First use of this temp namespace in this database; create it. The
4039  * temp namespaces are always owned by the superuser. We leave their
4040  * permissions at default --- i.e., no access except to superuser ---
4041  * to ensure that unprivileged users can't peek at other backends'
4042  * temp tables. This works because the places that access the temp
4043  * namespace for my own backend skip permissions checks on it.
4044  */
4045  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
4046  true);
4047  /* Advance command counter to make namespace visible */
4049  }
4050  else
4051  {
4052  /*
4053  * If the namespace already exists, clean it out (in case the former
4054  * owner crashed without doing so).
4055  */
4056  RemoveTempRelations(namespaceId);
4057  }
4058 
4059  /*
4060  * If the corresponding toast-table namespace doesn't exist yet, create
4061  * it. (We assume there is no need to clean it out if it does exist, since
4062  * dropping a parent table should make its toast table go away.)
4063  */
4064  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
4065  MyBackendId);
4066 
4067  toastspaceId = get_namespace_oid(namespaceName, true);
4068  if (!OidIsValid(toastspaceId))
4069  {
4070  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
4071  true);
4072  /* Advance command counter to make namespace visible */
4074  }
4075 
4076  /*
4077  * Okay, we've prepared the temp namespace ... but it's not committed yet,
4078  * so all our work could be undone by transaction rollback. Set flag for
4079  * AtEOXact_Namespace to know what to do.
4080  */
4081  myTempNamespace = namespaceId;
4082  myTempToastNamespace = toastspaceId;
4083 
4084  /*
4085  * Mark MyProc as owning this namespace which other processes can use to
4086  * decide if a temporary namespace is in use or not. We assume that
4087  * assignment of namespaceId is an atomic operation. Even if it is not,
4088  * the temporary relation which resulted in the creation of this temporary
4089  * namespace is still locked until the current transaction commits, and
4090  * its pg_namespace row is not visible yet. However it does not matter:
4091  * this flag makes the namespace as being in use, so no objects created on
4092  * it would be removed concurrently.
4093  */
4094  MyProc->tempNamespaceId = namespaceId;
4095 
4096  /* It should not be done already. */
4099 
4100  baseSearchPathValid = false; /* need to rebuild list */
4101 }
@ ACLCHECK_OK
Definition: acl.h:182
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:4570
BackendId MyBackendId
Definition: globals.c:85
#define IsParallelWorker()
Definition: parallel.h:61
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3086
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4260
#define ACL_CREATE_TEMP
Definition: parsenodes.h:93
#define NAMEDATALEN
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
Definition: pg_namespace.c:43
#define snprintf
Definition: port.h:238
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:779
void CommandCounterIncrement(void)
Definition: xact.c:1077
bool RecoveryInProgress(void)
Definition: xlog.c:5912

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

Referenced by AccessTempTableNamespace().

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3238 of file namespace.c.

3239 {
3240  bool result;
3241  char *nspname;
3242 
3243  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3244  nspname = get_namespace_name(namespaceId);
3245  if (!nspname)
3246  return false; /* no such namespace? */
3247  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3248  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3249  pfree(nspname);
3250  return result;
3251 }

References get_namespace_name(), and pfree().

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

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3261 of file namespace.c.

3262 {
3263  /* If it's my own temp namespace, say "false" */
3264  if (isTempOrTempToastNamespace(namespaceId))
3265  return false;
3266  /* Else, if it's any temp namespace, say "true" */
3267  return isAnyTempNamespace(namespaceId);
3268 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3224

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3200 of file namespace.c.

3201 {
3202  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3203  return true;
3204  return false;
3205 }

References myTempNamespace, and OidIsValid.

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

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3224 of file namespace.c.

3225 {
3226  if (OidIsValid(myTempNamespace) &&
3227  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3228  return true;
3229  return false;
3230 }

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3212 of file namespace.c.

3213 {
3214  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3215  return true;
3216  return false;
3217 }

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

◆ lookup_collation()

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

Definition at line 2006 of file namespace.c.

2007 {
2008  Oid collid;
2009  HeapTuple colltup;
2010  Form_pg_collation collform;
2011 
2012  /* Check for encoding-specific entry (exact match) */
2013  collid = GetSysCacheOid3(COLLNAMEENCNSP, Anum_pg_collation_oid,
2014  PointerGetDatum(collname),
2016  ObjectIdGetDatum(collnamespace));
2017  if (OidIsValid(collid))
2018  return collid;
2019 
2020  /*
2021  * Check for any-encoding entry. This takes a bit more work: while libc
2022  * collations with collencoding = -1 do work with all encodings, ICU
2023  * collations only work with certain encodings, so we have to check that
2024  * aspect before deciding it's a match.
2025  */
2026  colltup = SearchSysCache3(COLLNAMEENCNSP,
2027  PointerGetDatum(collname),
2028  Int32GetDatum(-1),
2029  ObjectIdGetDatum(collnamespace));
2030  if (!HeapTupleIsValid(colltup))
2031  return InvalidOid;
2032  collform = (Form_pg_collation) GETSTRUCT(colltup);
2033  if (collform->collprovider == COLLPROVIDER_ICU)
2034  {
2036  collid = collform->oid;
2037  else
2038  collid = InvalidOid;
2039  }
2040  else
2041  {
2042  collid = collform->oid;
2043  }
2044  ReleaseSysCache(colltup);
2045  return collid;
2046 }
bool is_encoding_supported_by_icu(int encoding)
Definition: encnames.c:459
int32 encoding
Definition: pg_database.h:41
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:560
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:1195
@ COLLNAMEENCNSP
Definition: syscache.h:49
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:201

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

Referenced by CollationGetCollid(), and get_collation_oid().

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2979 of file namespace.c.

2980 {
2981  Oid namespaceId;
2982  AclResult aclresult;
2983 
2984  /* check for pg_temp alias */
2985  if (strcmp(nspname, "pg_temp") == 0)
2986  {
2987  /* Initialize temp namespace */
2988  AccessTempTableNamespace(false);
2989  return myTempNamespace;
2990  }
2991 
2992  namespaceId = get_namespace_oid(nspname, false);
2993 
2994  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
2995  if (aclresult != ACLCHECK_OK)
2996  aclcheck_error(aclresult, OBJECT_SCHEMA,
2997  nspname);
2998 
2999  return namespaceId;
3000 }
AclResult
Definition: acl.h:181
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3477
@ OBJECT_SCHEMA
Definition: parsenodes.h:1896
#define ACL_CREATE
Definition: parsenodes.h:92

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

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

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2936 of file namespace.c.

2937 {
2938  Oid namespaceId;
2939  AclResult aclresult;
2940 
2941  /* check for pg_temp alias */
2942  if (strcmp(nspname, "pg_temp") == 0)
2943  {
2945  return myTempNamespace;
2946 
2947  /*
2948  * Since this is used only for looking up existing objects, there is
2949  * no point in trying to initialize the temp namespace here; and doing
2950  * so might create problems for some callers --- just fall through.
2951  */
2952  }
2953 
2954  namespaceId = get_namespace_oid(nspname, missing_ok);
2955  if (missing_ok && !OidIsValid(namespaceId))
2956  return InvalidOid;
2957 
2958  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_USAGE);
2959  if (aclresult != ACLCHECK_OK)
2960  aclcheck_error(aclresult, OBJECT_SCHEMA,
2961  nspname);
2962  /* Schema search hook for this lookup */
2963  InvokeNamespaceSearchHook(namespaceId, true);
2964 
2965  return namespaceId;
2966 }
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:208
#define ACL_USAGE
Definition: parsenodes.h:91

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

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

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2906 of file namespace.c.

2907 {
2908  /* check for pg_temp alias */
2909  if (strcmp(nspname, "pg_temp") == 0)
2910  {
2912  {
2914  return myTempNamespace;
2915  }
2916 
2917  /*
2918  * Since this is used only for looking up existing objects, there is
2919  * no point in trying to initialize the temp namespace here; and doing
2920  * so might create problems for some callers. Just report "not found".
2921  */
2922  return InvalidOid;
2923  }
2924 
2925  return get_namespace_oid(nspname, true);
2926 }

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

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

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 3105 of file namespace.c.

3106 {
3107  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3108 
3109  switch (list_length(names))
3110  {
3111  case 1:
3112  rel->relname = strVal(linitial(names));
3113  break;
3114  case 2:
3115  rel->schemaname = strVal(linitial(names));
3116  rel->relname = strVal(lsecond(names));
3117  break;
3118  case 3:
3119  rel->catalogname = strVal(linitial(names));
3120  rel->schemaname = strVal(lsecond(names));
3121  rel->relname = strVal(lthird(names));
3122  break;
3123  default:
3124  ereport(ERROR,
3125  (errcode(ERRCODE_SYNTAX_ERROR),
3126  errmsg("improper relation name (too many dotted names): %s",
3127  NameListToString(names))));
3128  break;
3129  }
3130 
3131  return rel;
3132 }
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:422
char * relname
Definition: primnodes.h:77
char * schemaname
Definition: primnodes.h:74

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

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

◆ MatchNamedCall()

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

Definition at line 1345 of file namespace.c.

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

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

Referenced by FuncnameGetCandidates().

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3179 of file namespace.c.

3180 {
3182  ListCell *l;
3183 
3184  initStringInfo(&string);
3185 
3186  foreach(l, names)
3187  {
3188  if (l != list_head(names))
3189  appendStringInfoChar(&string, '.');
3191  }
3192 
3193  return string.data;
3194 }
static ListCell * list_head(const List *l)
Definition: pg_list.h:126
char string[11]
Definition: preproc-type.c:52
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11529
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

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

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3145 of file namespace.c.

3146 {
3148  ListCell *l;
3149 
3150  initStringInfo(&string);
3151 
3152  foreach(l, names)
3153  {
3154  Node *name = (Node *) lfirst(l);
3155 
3156  if (l != list_head(names))
3157  appendStringInfoChar(&string, '.');
3158 
3159  if (IsA(name, String))
3160  appendStringInfoString(&string, strVal(name));
3161  else if (IsA(name, A_Star))
3162  appendStringInfoChar(&string, '*');
3163  else
3164  elog(ERROR, "unexpected node type in name list: %d",
3165  (int) nodeTag(name));
3166  }
3167 
3168  return string.data;
3169 }
const char * name
Definition: encode.c:561
#define IsA(nodeptr, _type_)
Definition: nodes.h:162
#define nodeTag(nodeptr)
Definition: nodes.h:116
Definition: nodes.h:112
Definition: value.h:64

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

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

◆ NamespaceCallback()

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

Definition at line 4410 of file namespace.c.

4411 {
4412  /* Force search path to be recomputed on next use */
4413  baseSearchPathValid = false;
4414 }

References baseSearchPathValid.

Referenced by InitializeSearchPath().

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1876 of file namespace.c.

1877 {
1878  HeapTuple opctup;
1879  Form_pg_opclass opcform;
1880  Oid opcnamespace;
1881  bool visible;
1882 
1883  opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
1884  if (!HeapTupleIsValid(opctup))
1885  elog(ERROR, "cache lookup failed for opclass %u", opcid);
1886  opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1887 
1889 
1890  /*
1891  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1892  * the system namespace are surely in the path and so we needn't even do
1893  * list_member_oid() for them.
1894  */
1895  opcnamespace = opcform->opcnamespace;
1896  if (opcnamespace != PG_CATALOG_NAMESPACE &&
1897  !list_member_oid(activeSearchPath, opcnamespace))
1898  visible = false;
1899  else
1900  {
1901  /*
1902  * If it is in the path, it might still not be visible; it could be
1903  * hidden by another opclass of the same name earlier in the path. So
1904  * we must do a slow check to see if this opclass would be found by
1905  * OpclassnameGetOpcid.
1906  */
1907  char *opcname = NameStr(opcform->opcname);
1908 
1909  visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1910  }
1911 
1912  ReleaseSysCache(opctup);
1913 
1914  return visible;
1915 }
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
Definition: namespace.c:1843
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
@ CLAOID
Definition: syscache.h:48

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

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

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1843 of file namespace.c.

1844 {
1845  Oid opcid;
1846  ListCell *l;
1847 
1849 
1850  foreach(l, activeSearchPath)
1851  {
1852  Oid namespaceId = lfirst_oid(l);
1853 
1854  if (namespaceId == myTempNamespace)
1855  continue; /* do not look in temp namespace */
1856 
1857  opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
1858  ObjectIdGetDatum(amid),
1859  PointerGetDatum(opcname),
1860  ObjectIdGetDatum(namespaceId));
1861  if (OidIsValid(opcid))
1862  return opcid;
1863  }
1864 
1865  /* Not found in path */
1866  return InvalidOid;
1867 }
@ CLAAMNAMENSP
Definition: syscache.h:47

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

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

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1790 of file namespace.c.

1791 {
1792  HeapTuple oprtup;
1793  Form_pg_operator oprform;
1794  Oid oprnamespace;
1795  bool visible;
1796 
1798  if (!HeapTupleIsValid(oprtup))
1799  elog(ERROR, "cache lookup failed for operator %u", oprid);
1800  oprform = (Form_pg_operator) GETSTRUCT(oprtup);
1801 
1803 
1804  /*
1805  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1806  * the system namespace are surely in the path and so we needn't even do
1807  * list_member_oid() for them.
1808  */
1809  oprnamespace = oprform->oprnamespace;
1810  if (oprnamespace != PG_CATALOG_NAMESPACE &&
1811  !list_member_oid(activeSearchPath, oprnamespace))
1812  visible = false;
1813  else
1814  {
1815  /*
1816  * If it is in the path, it might still not be visible; it could be
1817  * hidden by another operator of the same name and arguments earlier
1818  * in the path. So we must do a slow check to see if this is the same
1819  * operator that would be found by OpernameGetOprid.
1820  */
1821  char *oprname = NameStr(oprform->oprname);
1822 
1823  visible = (OpernameGetOprid(list_make1(makeString(oprname)),
1824  oprform->oprleft, oprform->oprright)
1825  == oprid);
1826  }
1827 
1828  ReleaseSysCache(oprtup);
1829 
1830  return visible;
1831 }
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1526
Oid oprid(Operator op)
Definition: parse_oper.c:250
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
@ OPEROID
Definition: syscache.h:72

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

Referenced by format_operator_extended(), and pg_operator_is_visible().

◆ OpernameGetCandidates()

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

Definition at line 1629 of file namespace.c.

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

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

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

◆ OpernameGetOprid()

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

Definition at line 1526 of file namespace.c.

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

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

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

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1959 of file namespace.c.

1960 {
1961  HeapTuple opftup;
1962  Form_pg_opfamily opfform;
1963  Oid opfnamespace;
1964  bool visible;
1965 
1966  opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
1967  if (!HeapTupleIsValid(opftup))
1968  elog(ERROR, "cache lookup failed for opfamily %u", opfid);
1969  opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
1970 
1972 
1973  /*
1974  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1975  * the system namespace are surely in the path and so we needn't even do
1976  * list_member_oid() for them.
1977  */
1978  opfnamespace = opfform->opfnamespace;
1979  if (opfnamespace != PG_CATALOG_NAMESPACE &&
1980  !list_member_oid(activeSearchPath, opfnamespace))
1981  visible = false;
1982  else
1983  {
1984  /*
1985  * If it is in the path, it might still not be visible; it could be
1986  * hidden by another opfamily of the same name earlier in the path. So
1987  * we must do a slow check to see if this opfamily would be found by
1988  * OpfamilynameGetOpfid.
1989  */
1990  char *opfname = NameStr(opfform->opfname);
1991 
1992  visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
1993  }
1994 
1995  ReleaseSysCache(opftup);
1996 
1997  return visible;
1998 }
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
Definition: namespace.c:1926
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
@ OPFAMILYOID
Definition: syscache.h:74

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1926 of file namespace.c.

1927 {
1928  Oid opfid;
1929  ListCell *l;
1930 
1932 
1933  foreach(l, activeSearchPath)
1934  {
1935  Oid namespaceId = lfirst_oid(l);
1936 
1937  if (namespaceId == myTempNamespace)
1938  continue; /* do not look in temp namespace */
1939 
1940  opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
1941  ObjectIdGetDatum(amid),
1942  PointerGetDatum(opfname),
1943  ObjectIdGetDatum(namespaceId));
1944  if (OidIsValid(opfid))
1945  return opfid;
1946  }
1947 
1948  /* Not found in path */
1949  return InvalidOid;
1950 }
@ OPFAMILYAMNAMENSP
Definition: syscache.h:73

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3462 of file namespace.c.

3463 {
3464  ListCell *lc,
3465  *lcp;
3466 
3468 
3469  /* Quick out if already known equal to active path. */
3470  if (path->generation == activePathGeneration)
3471  return true;
3472 
3473  /* We scan down the activeSearchPath to see if it matches the input. */
3475 
3476  /* If path->addTemp, first item should be my temp namespace. */
3477  if (path->addTemp)
3478  {
3479  if (lc && lfirst_oid(lc) == myTempNamespace)
3480  lc = lnext(activeSearchPath, lc);
3481  else
3482  return false;
3483  }
3484  /* If path->addCatalog, next item should be pg_catalog. */
3485  if (path->addCatalog)
3486  {
3487  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3488  lc = lnext(activeSearchPath, lc);
3489  else
3490  return false;
3491  }
3492  /* We should now be looking at the activeCreationNamespace. */
3493  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3494  return false;
3495  /* The remainder of activeSearchPath should match path->schemas. */
3496  foreach(lcp, path->schemas)
3497  {
3498  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3499  lc = lnext(activeSearchPath, lc);
3500  else
3501  return false;
3502  }
3503  if (lc)
3504  return false;
3505 
3506  /*
3507  * Update path->generation so that future tests will return quickly, so
3508  * long as the active search path doesn't change.
3509  */
3511 
3512  return true;
3513 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:341

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

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

◆ pg_collation_is_visible()

Datum pg_collation_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4571 of file namespace.c.

4572 {
4573  Oid oid = PG_GETARG_OID(0);
4574 
4576  PG_RETURN_NULL();
4577 
4579 }
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool CollationIsVisible(Oid collid)
Definition: namespace.c:2091
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:188

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

◆ pg_conversion_is_visible()

Datum pg_conversion_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4582 of file namespace.c.

4583 {
4584  Oid oid = PG_GETARG_OID(0);
4585 
4587  PG_RETURN_NULL();
4588 
4590 }
bool ConversionIsVisible(Oid conid)
Definition: namespace.c:2174

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

◆ pg_function_is_visible()

Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4527 of file namespace.c.

4528 {
4529  Oid oid = PG_GETARG_OID(0);
4530 
4532  PG_RETURN_NULL();
4533 
4535 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1456

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

◆ pg_is_other_temp_schema()

Datum pg_is_other_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4654 of file namespace.c.

4655 {
4656  Oid oid = PG_GETARG_OID(0);
4657 
4659 }
bool isOtherTempNamespace(Oid namespaceId)
Definition: namespace.c:3261

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

◆ pg_my_temp_schema()

Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4648 of file namespace.c.

4649 {
4651 }
#define PG_RETURN_OID(x)
Definition: fmgr.h:360

References myTempNamespace, and PG_RETURN_OID.

◆ pg_opclass_is_visible()

Datum pg_opclass_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4549 of file namespace.c.

4550 {
4551  Oid oid = PG_GETARG_OID(0);
4552 
4554  PG_RETURN_NULL();
4555 
4557 }
bool OpclassIsVisible(Oid opcid)
Definition: namespace.c:1876

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

◆ pg_operator_is_visible()

Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4538 of file namespace.c.

4539 {
4540  Oid oid = PG_GETARG_OID(0);
4541 
4543  PG_RETURN_NULL();
4544 
4546 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1790

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

◆ pg_opfamily_is_visible()

Datum pg_opfamily_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4560 of file namespace.c.

4561 {
4562  Oid oid = PG_GETARG_OID(0);
4563 
4565  PG_RETURN_NULL();
4566 
4568 }
bool OpfamilyIsVisible(Oid opfid)
Definition: namespace.c:1959

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

◆ pg_statistics_obj_is_visible()

Datum pg_statistics_obj_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4593 of file namespace.c.

4594 {
4595  Oid oid = PG_GETARG_OID(0);
4596 
4598  PG_RETURN_NULL();
4599 
4601 }
bool StatisticsObjIsVisible(Oid relid)
Definition: namespace.c:2278
@ STATEXTOID
Definition: syscache.h:96

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

◆ pg_table_is_visible()

Datum pg_table_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4505 of file namespace.c.

4506 {
4507  Oid oid = PG_GETARG_OID(0);
4508 
4510  PG_RETURN_NULL();
4511 
4513 }
bool RelationIsVisible(Oid relid)
Definition: namespace.c:711
@ RELOID
Definition: syscache.h:89

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

◆ pg_ts_config_is_visible()

Datum pg_ts_config_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4637 of file namespace.c.

4638 {
4639  Oid oid = PG_GETARG_OID(0);
4640 
4642  PG_RETURN_NULL();
4643 
4645 }
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2780
@ TSCONFIGOID
Definition: syscache.h:106

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

◆ pg_ts_dict_is_visible()

Datum pg_ts_dict_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4615 of file namespace.c.

4616 {
4617  Oid oid = PG_GETARG_OID(0);
4618 
4620  PG_RETURN_NULL();
4621 
4623 }
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2527
@ TSDICTOID
Definition: syscache.h:108

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

◆ pg_ts_parser_is_visible()

Datum pg_ts_parser_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4604 of file namespace.c.

4605 {
4606  Oid oid = PG_GETARG_OID(0);
4607 
4609  PG_RETURN_NULL();
4610 
4612 }
bool TSParserIsVisible(Oid prsId)
Definition: namespace.c:2401
@ TSPARSEROID
Definition: syscache.h:110

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

◆ pg_ts_template_is_visible()

Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4626 of file namespace.c.

4627 {
4628  Oid oid = PG_GETARG_OID(0);
4629 
4631  PG_RETURN_NULL();
4632 
4634 }
bool TSTemplateIsVisible(Oid tmplId)
Definition: namespace.c:2654
@ TSTEMPLATEOID
Definition: syscache.h:112

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

◆ pg_type_is_visible()

Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4516 of file namespace.c.

4517 {
4518  Oid oid = PG_GETARG_OID(0);
4519 
4521  PG_RETURN_NULL();
4522 
4524 }
bool TypeIsVisible(Oid typid)
Definition: namespace.c:819
@ TYPEOID
Definition: syscache.h:114

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

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3600 of file namespace.c.

3601 {
3602  OverrideStackEntry *entry;
3603 
3604  /* Sanity checks. */
3605  if (overrideStack == NIL)
3606  elog(ERROR, "bogus PopOverrideSearchPath call");
3608  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3609  elog(ERROR, "bogus PopOverrideSearchPath call");
3610 
3611  /* Pop the stack and free storage. */
3613  list_free(entry->searchPath);
3614  pfree(entry);
3615 
3616  /* Activate the next level down. */
3617  if (overrideStack)
3618  {
3620  activeSearchPath = entry->searchPath;
3622  activeTempCreationPending = false; /* XXX is this OK? */
3623  }
3624  else
3625  {
3626  /* If not baseSearchPathValid, this is useless but harmless */
3630  }
3631 
3632  /* As above, the generation always increments. */
3634 }

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

Referenced by CreateSchemaCommand().

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3533 of file namespace.c.

3534 {
3535  OverrideStackEntry *entry;
3536  List *oidlist;
3537  Oid firstNS;
3538  MemoryContext oldcxt;
3539 
3540  /*
3541  * Copy the list for safekeeping, and insert implicitly-searched
3542  * namespaces as needed. This code should track recomputeNamespacePath.
3543  */
3545 
3546  oidlist = list_copy(newpath->schemas);
3547 
3548  /*
3549  * Remember the first member of the explicit list.
3550  */
3551  if (oidlist == NIL)
3552  firstNS = InvalidOid;
3553  else
3554  firstNS = linitial_oid(oidlist);
3555 
3556  /*
3557  * Add any implicitly-searched namespaces to the list. Note these go on
3558  * the front, not the back; also notice that we do not check USAGE
3559  * permissions for these.
3560  */
3561  if (newpath->addCatalog)
3562  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3563 
3564  if (newpath->addTemp && OidIsValid(myTempNamespace))
3565  oidlist = lcons_oid(myTempNamespace, oidlist);
3566 
3567  /*
3568  * Build the new stack entry, then insert it at the head of the list.
3569  */
3570  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3571  entry->searchPath = oidlist;
3572  entry->creationNamespace = firstNS;
3574 
3575  overrideStack = lcons(entry, overrideStack);
3576 
3577  /* And make it active. */
3578  activeSearchPath = entry->searchPath;
3580  activeTempCreationPending = false; /* XXX is this OK? */
3581 
3582  /*
3583  * We always increment activePathGeneration when pushing/popping an
3584  * override path. In current usage, these actions always change the
3585  * effective path state, so there's no value in checking to see if it
3586  * didn't change.
3587  */
3589 
3590  MemoryContextSwitchTo(oldcxt);
3591 }
List * lcons(void *datum, List *list)
Definition: list.c:494
List * lcons_oid(Oid datum, List *list)
Definition: list.c:530

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

Referenced by CreateSchemaCommand().

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 3038 of file namespace.c.

3039 {
3040  char *schemaname;
3041  Oid namespaceId;
3042 
3043  /* deconstruct the name list */
3044  DeconstructQualifiedName(names, &schemaname, objname_p);
3045 
3046  if (schemaname)
3047  {
3048  /* check for pg_temp alias */
3049  if (strcmp(schemaname, "pg_temp") == 0)
3050  {
3051  /* Initialize temp namespace */
3052  AccessTempTableNamespace(false);
3053  return myTempNamespace;
3054  }
3055  /* use exact schema given */
3056  namespaceId = get_namespace_oid(schemaname, false);
3057  /* we do not check for USAGE rights here! */
3058  }
3059  else
3060  {
3061  /* use the default creation namespace */
3064  {
3065  /* Need to initialize temp namespace */
3067  return myTempNamespace;
3068  }
3069  namespaceId = activeCreationNamespace;
3070  if (!OidIsValid(namespaceId))
3071  ereport(ERROR,
3072  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3073  errmsg("no schema has been selected to create in")));
3074  }
3075 
3076  return namespaceId;
3077 }

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

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

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 644 of file namespace.c.

645 {
646  switch (newRelation->relpersistence)
647  {
648  case RELPERSISTENCE_TEMP:
649  if (!isTempOrTempToastNamespace(nspid))
650  {
651  if (isAnyTempNamespace(nspid))
652  ereport(ERROR,
653  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
654  errmsg("cannot create relations in temporary schemas of other sessions")));
655  else
656  ereport(ERROR,
657  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
658  errmsg("cannot create temporary relation in non-temporary schema")));
659  }
660  break;
661  case RELPERSISTENCE_PERMANENT:
662  if (isTempOrTempToastNamespace(nspid))
663  newRelation->relpersistence = RELPERSISTENCE_TEMP;
664  else if (isAnyTempNamespace(nspid))
665  ereport(ERROR,
666  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
667  errmsg("cannot create relations in temporary schemas of other sessions")));
668  break;
669  default:
670  if (isAnyTempNamespace(nspid))
671  ereport(ERROR,
672  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
673  errmsg("only temporary relations may be created in temporary schemas")));
674  }
675 }
char relpersistence
Definition: primnodes.h:83

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 537 of file namespace.c.

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

References AccessShareLock, ACL_CREATE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert(), 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_aclcheck(), object_ownercheck(), OBJECT_SCHEMA, OidIsValid, RangeVarAdjustRelationPersistence(), RangeVarGetCreationNamespace(), RangeVar::relname, RangeVar::schemaname, SharedInvalidMessageCounter, UnlockDatabaseObject(), and UnlockRelationOid().

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 452 of file namespace.c.

453 {
454  Oid namespaceId;
455 
456  /*
457  * We check the catalog name and then ignore it.
458  */
459  if (newRelation->catalogname)
460  {
461  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
462  ereport(ERROR,
463  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
464  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
465  newRelation->catalogname, newRelation->schemaname,
466  newRelation->relname)));
467  }
468 
469  if (newRelation->schemaname)
470  {
471  /* check for pg_temp alias */
472  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
473  {
474  /* Initialize temp namespace */
476  return myTempNamespace;
477  }
478  /* use exact schema given */
479  namespaceId = get_namespace_oid(newRelation->schemaname, false);
480  /* we do not check for USAGE rights here! */
481  }
482  else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
483  {
484  /* Initialize temp namespace */
486  return myTempNamespace;
487  }
488  else
489  {
490  /* use the default creation namespace */
493  {
494  /* Need to initialize temp namespace */
496  return myTempNamespace;
497  }
498  namespaceId = activeCreationNamespace;
499  if (!OidIsValid(namespaceId))
500  ereport(ERROR,
501  (errcode(ERRCODE_UNDEFINED_SCHEMA),
502  errmsg("no schema has been selected to create in")));
503  }
504 
505  /* Note: callers will check for CREATE rights when appropriate */
506 
507  return namespaceId;
508 }

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

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

◆ RangeVarGetRelidExtended()

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

Definition at line 239 of file namespace.c.

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

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

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

◆ recomputeNamespacePath()

static void recomputeNamespacePath ( void  )
static

Definition at line 3780 of file namespace.c.

3781 {
3782  Oid roleid = GetUserId();
3783  char *rawname;
3784  List *namelist;
3785  List *oidlist;
3786  List *newpath;
3787  ListCell *l;
3788  bool temp_missing;
3789  Oid firstNS;
3790  bool pathChanged;
3791  MemoryContext oldcxt;
3792 
3793  /* Do nothing if an override search spec is active. */
3794  if (overrideStack)
3795  return;
3796 
3797  /* Do nothing if path is already valid. */
3798  if (baseSearchPathValid && namespaceUser == roleid)
3799  return;
3800 
3801  /* Need a modifiable copy of namespace_search_path string */
3802  rawname = pstrdup(namespace_search_path);
3803 
3804  /* Parse string into list of identifiers */
3805  if (!SplitIdentifierString(rawname, ',', &namelist))
3806  {
3807  /* syntax error in name list */
3808  /* this should not happen if GUC checked check_search_path */
3809  elog(ERROR, "invalid list syntax");
3810  }
3811 
3812  /*
3813  * Convert the list of names to a list of OIDs. If any names are not
3814  * recognizable or we don't have read access, just leave them out of the
3815  * list. (We can't raise an error, since the search_path setting has
3816  * already been accepted.) Don't make duplicate entries, either.
3817  */
3818  oidlist = NIL;
3819  temp_missing = false;
3820  foreach(l, namelist)
3821  {
3822  char *curname = (char *) lfirst(l);
3823  Oid namespaceId;
3824 
3825  if (strcmp(curname, "$user") == 0)
3826  {
3827  /* $user --- substitute namespace matching user name, if any */
3828  HeapTuple tuple;
3829 
3830  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
3831  if (HeapTupleIsValid(tuple))
3832  {
3833  char *rname;
3834 
3835  rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
3836  namespaceId = get_namespace_oid(rname, true);
3837  ReleaseSysCache(tuple);
3838  if (OidIsValid(namespaceId) &&
3839  !list_member_oid(oidlist, namespaceId) &&
3840  object_aclcheck(NamespaceRelationId, namespaceId, roleid,
3841  ACL_USAGE) == ACLCHECK_OK &&
3842  InvokeNamespaceSearchHook(namespaceId, false))
3843  oidlist = lappend_oid(oidlist, namespaceId);
3844  }
3845  }
3846  else if (strcmp(curname, "pg_temp") == 0)
3847  {
3848  /* pg_temp --- substitute temp namespace, if any */
3850  {
3851  if (!list_member_oid(oidlist, myTempNamespace) &&
3853  oidlist = lappend_oid(oidlist, myTempNamespace);
3854  }
3855  else
3856  {
3857  /* If it ought to be the creation namespace, set flag */
3858  if (oidlist == NIL)
3859  temp_missing = true;
3860  }
3861  }
3862  else
3863  {
3864  /* normal namespace reference */
3865  namespaceId = get_namespace_oid(curname, true);
3866  if (OidIsValid(namespaceId) &&
3867  !list_member_oid(oidlist, namespaceId) &&
3868  object_aclcheck(NamespaceRelationId, namespaceId, roleid,
3869  ACL_USAGE) == ACLCHECK_OK &&
3870  InvokeNamespaceSearchHook(namespaceId, false))
3871  oidlist = lappend_oid(oidlist, namespaceId);
3872  }
3873  }
3874 
3875  /*
3876  * Remember the first member of the explicit list. (Note: this is
3877  * nominally wrong if temp_missing, but we need it anyway to distinguish
3878  * explicit from implicit mention of pg_catalog.)
3879  */
3880  if (oidlist == NIL)
3881  firstNS = InvalidOid;
3882  else
3883  firstNS = linitial_oid(oidlist);
3884 
3885  /*
3886  * Add any implicitly-searched namespaces to the list. Note these go on
3887  * the front, not the back; also notice that we do not check USAGE
3888  * permissions for these.
3889  */
3890  if (!list_member_oid(oidlist, PG_CATALOG_NAMESPACE))
3891  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3892 
3893  if (OidIsValid(myTempNamespace) &&
3894  !list_member_oid(oidlist, myTempNamespace))
3895  oidlist = lcons_oid(myTempNamespace, oidlist);
3896 
3897  /*
3898  * We want to detect the case where the effective value of the base search
3899  * path variables didn't change. As long as we're doing so, we can avoid
3900  * copying the OID list unnecessarily.
3901  */
3902  if (baseCreationNamespace == firstNS &&
3903  baseTempCreationPending == temp_missing &&
3904  equal(oidlist, baseSearchPath))
3905  {
3906  pathChanged = false;
3907  }
3908  else
3909  {
3910  pathChanged = true;
3911 
3912  /* Must save OID list in permanent storage. */
3914  newpath = list_copy(oidlist);
3915  MemoryContextSwitchTo(oldcxt);
3916 
3917  /* Now safe to assign to state variables. */
3919  baseSearchPath = newpath;
3920  baseCreationNamespace = firstNS;
3921  baseTempCreationPending = temp_missing;
3922  }
3923 
3924  /* Mark the path valid. */
3925  baseSearchPathValid = true;
3926  namespaceUser = roleid;
3927 
3928  /* And make it active. */
3932 
3933  /*
3934  * Bump the generation only if something actually changed. (Notice that
3935  * what we compared to was the old state of the base path variables; so
3936  * this does not deal with the situation where we have just popped an
3937  * override path and restored the prior state of the base path. Instead
3938  * we rely on the override-popping logic to have bumped the generation.)
3939  */
3940  if (pathChanged)
3942 
3943  /* Clean up. */
3944  pfree(rawname);
3945  list_free(namelist);
3946  list_free(oidlist);
3947 }
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:225
List * lappend_oid(List *list, Oid datum)
Definition: list.c:374
char * namespace_search_path
Definition: namespace.c:200
NameData rolname
Definition: pg_authid.h:34
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
@ AUTHOID
Definition: syscache.h:45

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

Referenced by CollationGetCollid(), CollationIsVisible(), ConversionGetConid(), ConversionIsVisible(), fetch_search_path(), fetch_search_path_array(), FindDefaultConversionProc(), FuncnameGetCandidates(), FunctionIsVisible(), get_collation_oid(), get_conversion_oid(), get_statistics_object_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), GetOverrideSearchPath(), OpclassIsVisible(), OpclassnameGetOpcid(), OperatorIsVisible(), OpernameGetCandidates(), OpernameGetOprid(), OpfamilyIsVisible(), OpfamilynameGetOpfid(), OverrideSearchPathMatchesCurrent(), QualifiedNameGetCreationNamespace(), RangeVarGetCreationNamespace(), RelationIsVisible(), RelnameGetRelid(), StatisticsObjIsVisible(), TSConfigIsVisible(), TSDictionaryIsVisible(), TSParserIsVisible(), TSTemplateIsVisible(), TypeIsVisible(), and TypenameGetTypidExtended().

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 711 of file namespace.c.

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

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

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

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 683 of file namespace.c.

684 {
685  Oid relid;
686  ListCell *l;
687 
689 
690  foreach(l, activeSearchPath)
691  {
692  Oid namespaceId = lfirst_oid(l);
693 
694  relid = get_relname_relid(relname, namespaceId);
695  if (OidIsValid(relid))
696  return relid;
697  }
698 
699  /* Not found in path */
700  return InvalidOid;
701 }

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

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

◆ RemoveTempRelations()

static void RemoveTempRelations ( Oid  tempNamespaceId)
static

Definition at line 4260 of file namespace.c.

4261 {
4262  ObjectAddress object;
4263 
4264  /*
4265  * We want to get rid of everything in the target namespace, but not the
4266  * namespace itself (deleting it only to recreate it later would be a
4267  * waste of cycles). Hence, specify SKIP_ORIGINAL. It's also an INTERNAL
4268  * deletion, and we want to not drop any extensions that might happen to
4269  * own temp objects.
4270  */
4271  object.classId = NamespaceRelationId;
4272  object.objectId = tempNamespaceId;
4273  object.objectSubId = 0;
4274 
4275  performDeletion(&object, DROP_CASCADE,
4280 }
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
Definition: dependency.c:322
#define PERFORM_DELETION_SKIP_EXTENSIONS
Definition: dependency.h:140
#define PERFORM_DELETION_QUIETLY
Definition: dependency.h:138
#define PERFORM_DELETION_SKIP_ORIGINAL
Definition: dependency.h:139
#define PERFORM_DELETION_INTERNAL
Definition: dependency.h:136
@ DROP_CASCADE
Definition: parsenodes.h:1934

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

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

◆ RemoveTempRelationsCallback()

static void RemoveTempRelationsCallback ( int  code,
Datum  arg 
)
static

Definition at line 4286 of file namespace.c.

4287 {
4288  if (OidIsValid(myTempNamespace)) /* should always be true */
4289  {
4290  /* Need to ensure we have a usable transaction. */
4294 
4296 
4299  }
4300 }
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:251
void PushActiveSnapshot(Snapshot snapshot)
Definition: snapmgr.c:683
void PopActiveSnapshot(void)
Definition: snapmgr.c:778
void StartTransactionCommand(void)
Definition: xact.c:2925
void CommitTransactionCommand(void)
Definition: xact.c:3022
void AbortOutOfAnyTransaction(void)
Definition: xact.c:4692

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

Referenced by AtEOXact_Namespace().

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4306 of file namespace.c.

4307 {
4310 }

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3372 of file namespace.c.

3373 {
3374  /* Worker should not have created its own namespaces ... */
3378 
3379  /* Assign same namespace OIDs that leader has */
3380  myTempNamespace = tempNamespaceId;
3381  myTempToastNamespace = tempToastNamespaceId;
3382 
3383  /*
3384  * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
3385  * Even if the namespace is new so far as the leader is concerned, it's
3386  * not new to the worker, and we certainly wouldn't want the worker trying
3387  * to destroy it.
3388  */
3389 
3390  baseSearchPathValid = false; /* may need to rebuild list */
3391 }

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

Referenced by ParallelWorkerMain().

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  relid)

Definition at line 2278 of file namespace.c.

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

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

Referenced by getObjectDescription(), and pg_statistics_obj_is_visible().

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 2780 of file namespace.c.

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

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

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

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2527 of file namespace.c.

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

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

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

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2401 of file namespace.c.

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

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

Referenced by getObjectDescription(), and pg_ts_parser_is_visible().

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 2654 of file namespace.c.

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

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

Referenced by getObjectDescription(), and pg_ts_template_is_visible().

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 819 of file namespace.c.

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

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

Referenced by format_type_extended(), and pg_type_is_visible().

◆ TypenameGetTypid()

Oid TypenameGetTypid ( const char *  typname)

Definition at line 774 of file namespace.c.

775 {
776  return TypenameGetTypidExtended(typname, true);
777 }
Oid TypenameGetTypidExtended(const char *typname, bool temp_ok)
Definition: namespace.c:787

References TypenameGetTypidExtended(), and typname.

◆ TypenameGetTypidExtended()

Oid TypenameGetTypidExtended ( const char *  typname,
bool  temp_ok 
)

Definition at line 787 of file namespace.c.

788 {
789  Oid typid;
790  ListCell *l;
791 
793 
794  foreach(l, activeSearchPath)
795  {
796  Oid namespaceId = lfirst_oid(l);
797 
798  if (!temp_ok && namespaceId == myTempNamespace)
799  continue; /* do not look in temp namespace */
800 
801  typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
803  ObjectIdGetDatum(namespaceId));
804  if (OidIsValid(typid))
805  return typid;
806  }
807 
808  /* Not found in path */
809  return InvalidOid;
810 }

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

Referenced by LookupTypeNameExtended(), and TypenameGetTypid().

Variable Documentation

◆ activeCreationNamespace

◆ activePathGeneration

◆ activeSearchPath

◆ activeTempCreationPending

◆ baseCreationNamespace

◆ baseSearchPath

◆ baseSearchPathValid

◆ baseTempCreationPending

bool baseTempCreationPending = false
static

◆ myTempNamespace

◆ myTempNamespaceSubID

◆ myTempToastNamespace

◆ namespace_search_path

char* namespace_search_path = NULL

Definition at line 200 of file namespace.c.

Referenced by recomputeNamespacePath().

◆ namespaceUser

Oid namespaceUser = InvalidOid
static

Definition at line 159 of file namespace.c.

Referenced by InitializeSearchPath(), and recomputeNamespacePath().

◆ overrideStack