PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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/namespace.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 "common/hashfn_unstable.h"
#include "funcapi.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/proc.h"
#include "storage/procarray.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 "lib/simplehash.h"
Include dependency graph for namespace.c:

Go to the source code of this file.

Data Structures

struct  SearchPathCacheKey
 
struct  SearchPathCacheEntry
 

Macros

#define SH_PREFIX   nsphash
 
#define SH_ELEMENT_TYPE   SearchPathCacheEntry
 
#define SH_KEY_TYPE   SearchPathCacheKey
 
#define SH_KEY   key
 
#define SH_HASH_KEY(tb, key)   spcachekey_hash(key)
 
#define SH_EQUAL(tb, a, b)   spcachekey_equal(a, b)
 
#define SH_SCOPE   static inline
 
#define SH_DECLARE
 
#define SH_DEFINE
 
#define SPCACHE_RESET_THRESHOLD   256
 
#define SPACE_PER_OP
 

Typedefs

typedef struct SearchPathCacheKey SearchPathCacheKey
 
typedef struct SearchPathCacheEntry SearchPathCacheEntry
 

Functions

static bool RelationIsVisibleExt (Oid relid, bool *is_missing)
 
static bool TypeIsVisibleExt (Oid typid, bool *is_missing)
 
static bool FunctionIsVisibleExt (Oid funcid, bool *is_missing)
 
static bool OperatorIsVisibleExt (Oid oprid, bool *is_missing)
 
static bool OpclassIsVisibleExt (Oid opcid, bool *is_missing)
 
static bool OpfamilyIsVisibleExt (Oid opfid, bool *is_missing)
 
static bool CollationIsVisibleExt (Oid collid, bool *is_missing)
 
static bool ConversionIsVisibleExt (Oid conid, bool *is_missing)
 
static bool StatisticsObjIsVisibleExt (Oid stxid, bool *is_missing)
 
static bool TSParserIsVisibleExt (Oid prsId, bool *is_missing)
 
static bool TSDictionaryIsVisibleExt (Oid dictId, bool *is_missing)
 
static bool TSTemplateIsVisibleExt (Oid tmplId, bool *is_missing)
 
static bool TSConfigIsVisibleExt (Oid cfgid, bool *is_missing)
 
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 InvalidationCallback (Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
 
static bool MatchNamedCall (HeapTuple proctup, int nargs, List *argnames, bool include_out_arguments, int pronargs, int **argnumbers, int *fgc_flags)
 
static uint32 spcachekey_hash (SearchPathCacheKey key)
 
static bool spcachekey_equal (SearchPathCacheKey a, SearchPathCacheKey b)
 
static void spcache_init (void)
 
static SearchPathCacheEntryspcache_lookup (const char *searchPath, Oid roleid)
 
static SearchPathCacheEntryspcache_insert (const char *searchPath, Oid roleid)
 
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, int *fgc_flags)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok, int *fgc_flags)
 
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 stxid)
 
Oid get_ts_parser_oid (List *names, bool missing_ok)
 
bool TSParserIsVisible (Oid prsId)
 
Oid get_ts_dict_oid (List *names, bool missing_ok)
 
bool TSDictionaryIsVisible (Oid dictId)
 
Oid get_ts_template_oid (List *names, bool missing_ok)
 
bool TSTemplateIsVisible (Oid tmplId)
 
Oid get_ts_config_oid (List *names, bool missing_ok)
 
bool TSConfigIsVisible (Oid cfgid)
 
void DeconstructQualifiedName (const List *names, char **nspname_p, char **objname_p)
 
Oid LookupNamespaceNoError (const char *nspname)
 
Oid LookupExplicitNamespace (const char *nspname, bool missing_ok)
 
Oid LookupCreationNamespace (const char *nspname)
 
void CheckSetNamespace (Oid oldNspOid, Oid nspOid)
 
Oid QualifiedNameGetCreationNamespace (const List *names, char **objname_p)
 
Oid get_namespace_oid (const char *nspname, bool missing_ok)
 
RangeVarmakeRangeVarFromNameList (const List *names)
 
charNameListToString (const List *names)
 
charNameListToQuotedString (const List *names)
 
bool isTempNamespace (Oid namespaceId)
 
bool isTempToastNamespace (Oid namespaceId)
 
bool isTempOrTempToastNamespace (Oid namespaceId)
 
bool isAnyTempNamespace (Oid namespaceId)
 
bool isOtherTempNamespace (Oid namespaceId)
 
TempNamespaceStatus checkTempNamespaceStatus (Oid namespaceId)
 
ProcNumber GetTempNamespaceProcNumber (Oid namespaceId)
 
Oid GetTempToastNamespace (void)
 
void GetTempNamespaceState (Oid *tempNamespaceId, Oid *tempToastNamespaceId)
 
void SetTempNamespaceState (Oid tempNamespaceId, Oid tempToastNamespaceId)
 
SearchPathMatcherGetSearchPathMatcher (MemoryContext context)
 
SearchPathMatcherCopySearchPathMatcher (SearchPathMatcher *path)
 
bool SearchPathMatchesCurrentEnvironment (SearchPathMatcher *path)
 
Oid get_collation_oid (List *collname, bool missing_ok)
 
Oid get_conversion_oid (List *conname, bool missing_ok)
 
Oid FindDefaultConversionProc (int32 for_encoding, int32 to_encoding)
 
static ListpreprocessNamespacePath (const char *searchPath, Oid roleid, bool *temp_missing)
 
static ListfinalNamespacePath (List *oidlist, Oid *firstNS)
 
static const SearchPathCacheEntrycachedNamespacePath (const char *searchPath, Oid roleid)
 
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 bool searchPathCacheValid = false
 
static MemoryContext SearchPathCacheContext = NULL
 
static Oid myTempNamespace = InvalidOid
 
static Oid myTempToastNamespace = InvalidOid
 
static SubTransactionId myTempNamespaceSubID = InvalidSubTransactionId
 
charnamespace_search_path = NULL
 
static nsphash_hashSearchPathCache = NULL
 
static SearchPathCacheEntryLastSearchPathCacheEntry = NULL
 

Macro Definition Documentation

◆ SH_DECLARE

#define SH_DECLARE

Definition at line 288 of file namespace.c.

◆ SH_DEFINE

#define SH_DEFINE

Definition at line 289 of file namespace.c.

◆ SH_ELEMENT_TYPE

#define SH_ELEMENT_TYPE   SearchPathCacheEntry

Definition at line 282 of file namespace.c.

◆ SH_EQUAL

#define SH_EQUAL (   tb,
  a,
  b 
)    spcachekey_equal(a, b)

Definition at line 286 of file namespace.c.

◆ SH_HASH_KEY

#define SH_HASH_KEY (   tb,
  key 
)    spcachekey_hash(key)

Definition at line 285 of file namespace.c.

◆ SH_KEY

#define SH_KEY   key

Definition at line 284 of file namespace.c.

◆ SH_KEY_TYPE

#define SH_KEY_TYPE   SearchPathCacheKey

Definition at line 283 of file namespace.c.

◆ SH_PREFIX

#define SH_PREFIX   nsphash

Definition at line 281 of file namespace.c.

◆ SH_SCOPE

#define SH_SCOPE   static inline

Definition at line 287 of file namespace.c.

◆ SPACE_PER_OP

#define SPACE_PER_OP
Value:
2 * sizeof(Oid))
#define MAXALIGN(LEN)
Definition c.h:838
unsigned int Oid
static int fb(int x)

◆ SPCACHE_RESET_THRESHOLD

#define SPCACHE_RESET_THRESHOLD   256

Definition at line 298 of file namespace.c.

Typedef Documentation

◆ SearchPathCacheEntry

◆ SearchPathCacheKey

Function Documentation

◆ AccessTempTableNamespace()

static void AccessTempTableNamespace ( bool  force)
static

Definition at line 4434 of file namespace.c.

4435{
4436 /*
4437 * Make note that this temporary namespace has been accessed in this
4438 * transaction.
4439 */
4441
4442 /*
4443 * If the caller attempting to access a temporary schema expects the
4444 * creation of the namespace to be pending and should be enforced, then go
4445 * through the creation.
4446 */
4447 if (!force && OidIsValid(myTempNamespace))
4448 return;
4449
4450 /*
4451 * The temporary tablespace does not exist yet and is wanted, so
4452 * initialize it.
4453 */
4455}
#define OidIsValid(objectId)
Definition c.h:800
static Oid myTempNamespace
Definition namespace.c:201
static void InitTempTableNamespace(void)
Definition namespace.c:4462
int MyXactFlags
Definition xact.c:137
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition xact.h:103

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 4785 of file namespace.c.

4786{
4787 /* don't access search_path during bootstrap */
4789
4790 /*
4791 * We mark the path as needing recomputation, but don't do anything until
4792 * it's needed. This avoids trying to do database access during GUC
4793 * initialization, or outside a transaction.
4794 *
4795 * This does not invalidate the search path cache, so if this value had
4796 * been previously set and no syscache invalidations happened,
4797 * recomputation may not be necessary.
4798 */
4799 baseSearchPathValid = false;
4800}
#define Assert(condition)
Definition c.h:885
#define IsBootstrapProcessingMode()
Definition miscadmin.h:477
static bool baseSearchPathValid
Definition namespace.c:158

References Assert, baseSearchPathValid, and IsBootstrapProcessingMode.

◆ AtEOSubXact_Namespace()

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

Definition at line 4630 of file namespace.c.

4632{
4633
4635 {
4636 if (isCommit)
4638 else
4639 {
4641 /* TEMP namespace creation failed, so reset state */
4644 baseSearchPathValid = false; /* need to rebuild list */
4645 searchPathCacheValid = false;
4646
4647 /*
4648 * Reset the temporary namespace flag in MyProc. We assume that
4649 * this operation is atomic.
4650 *
4651 * Because this subtransaction is aborting, the pg_namespace row
4652 * is not visible to anyone else anyway, but that doesn't matter:
4653 * it's not a problem if objects contained in this namespace are
4654 * removed concurrently.
4655 */
4657 }
4658 }
4659}
#define InvalidSubTransactionId
Definition c.h:684
static bool searchPathCacheValid
Definition namespace.c:164
static SubTransactionId myTempNamespaceSubID
Definition namespace.c:205
static Oid myTempToastNamespace
Definition namespace.c:203
#define InvalidOid
PGPROC * MyProc
Definition proc.c:67
Oid tempNamespaceId
Definition proc.h:196

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4584 of file namespace.c.

4585{
4586 /*
4587 * If we abort the transaction in which a temp namespace was selected,
4588 * we'll have to do any creation or cleanout work over again. So, just
4589 * forget the namespace entirely until next time. On the other hand, if
4590 * we commit then register an exit callback to clean out the temp tables
4591 * at backend shutdown. (We only want to register the callback once per
4592 * session, so this is a good place to do it.)
4593 */
4595 {
4596 if (isCommit)
4598 else
4599 {
4602 baseSearchPathValid = false; /* need to rebuild list */
4603 searchPathCacheValid = false;
4604
4605 /*
4606 * Reset the temporary namespace flag in MyProc. We assume that
4607 * this operation is atomic.
4608 *
4609 * Because this transaction is aborting, the pg_namespace row is
4610 * not visible to anyone else anyway, but that doesn't matter:
4611 * it's not a problem if objects contained in this namespace are
4612 * removed concurrently.
4613 */
4615 }
4617 }
4618
4619}
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition ipc.c:344
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition namespace.c:4696

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

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

◆ cachedNamespacePath()

static const SearchPathCacheEntry * cachedNamespacePath ( const char searchPath,
Oid  roleid 
)
static

Definition at line 4316 of file namespace.c.

4317{
4319 SearchPathCacheEntry *entry;
4320
4321 spcache_init();
4322
4323 entry = spcache_insert(searchPath, roleid);
4324
4325 /*
4326 * An OOM may have resulted in a cache entry with missing 'oidlist' or
4327 * 'finalPath', so just compute whatever is missing.
4328 */
4329
4330 if (entry->oidlist == NIL)
4331 {
4333 entry->oidlist = preprocessNamespacePath(searchPath, roleid,
4334 &entry->temp_missing);
4336 }
4337
4338 /*
4339 * If a hook is set, we must recompute finalPath from the oidlist each
4340 * time, because the hook may affect the result. This is still much faster
4341 * than recomputing from the string (and doing catalog lookups and ACL
4342 * checks).
4343 */
4344 if (entry->finalPath == NIL || object_access_hook ||
4345 entry->forceRecompute)
4346 {
4347 list_free(entry->finalPath);
4348 entry->finalPath = NIL;
4349
4351 entry->finalPath = finalNamespacePath(entry->oidlist,
4352 &entry->firstNS);
4354
4355 /*
4356 * If an object_access_hook is set when finalPath is calculated, the
4357 * result may be affected by the hook. Force recomputation of
4358 * finalPath the next time this cache entry is used, even if the
4359 * object_access_hook is not set at that time.
4360 */
4361 entry->forceRecompute = object_access_hook ? true : false;
4362 }
4363
4364 return entry;
4365}
return true
Definition isn.c:130
void list_free(List *list)
Definition list.c:1546
static MemoryContext SearchPathCacheContext
Definition namespace.c:165
static SearchPathCacheEntry * spcache_insert(const char *searchPath, Oid roleid)
Definition namespace.c:375
static List * preprocessNamespacePath(const char *searchPath, Oid roleid, bool *temp_missing)
Definition namespace.c:4179
static void spcache_init(void)
Definition namespace.c:307
static List * finalNamespacePath(List *oidlist, Oid *firstNS)
Definition namespace.c:4270
object_access_hook_type object_access_hook
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
#define NIL
Definition pg_list.h:68

References fb(), finalNamespacePath(), SearchPathCacheEntry::finalPath, SearchPathCacheEntry::firstNS, SearchPathCacheEntry::forceRecompute, list_free(), MemoryContextSwitchTo(), NIL, object_access_hook, SearchPathCacheEntry::oidlist, preprocessNamespacePath(), SearchPathCacheContext, spcache_init(), spcache_insert(), SearchPathCacheEntry::temp_missing, and true.

Referenced by recomputeNamespacePath().

◆ check_search_path()

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

Definition at line 4729 of file namespace.c.

4730{
4731 Oid roleid = InvalidOid;
4732 const char *searchPath = *newval;
4733 char *rawname;
4734 List *namelist;
4736
4737 /*
4738 * We used to try to check that the named schemas exist, but there are
4739 * many valid use-cases for having search_path settings that include
4740 * schemas that don't exist; and often, we are not inside a transaction
4741 * here and so can't consult the system catalogs anyway. So now, the only
4742 * requirement is syntactic validity of the identifier list.
4743 *
4744 * Checking only the syntactic validity also allows us to use the search
4745 * path cache (if available) to avoid calling SplitIdentifierString() on
4746 * the same string repeatedly.
4747 */
4748 if (use_cache)
4749 {
4750 spcache_init();
4751
4752 roleid = GetUserId();
4753
4754 if (spcache_lookup(searchPath, roleid) != NULL)
4755 return true;
4756 }
4757
4758 /*
4759 * Ensure validity check succeeds before creating cache entry.
4760 */
4761
4762 rawname = pstrdup(searchPath); /* need a modifiable copy */
4763
4764 /* Parse string into list of identifiers */
4766 {
4767 /* syntax error in name list */
4768 GUC_check_errdetail("List syntax is invalid.");
4769 pfree(rawname);
4771 return false;
4772 }
4773 pfree(rawname);
4775
4776 /* OK to create empty cache entry */
4777 if (use_cache)
4778 (void) spcache_insert(searchPath, roleid);
4779
4780 return true;
4781}
#define newval
#define GUC_check_errdetail
Definition guc.h:506
char * pstrdup(const char *in)
Definition mcxt.c:1781
void pfree(void *pointer)
Definition mcxt.c:1616
Oid GetUserId(void)
Definition miscinit.c:469
static SearchPathCacheEntry * spcache_lookup(const char *searchPath, Oid roleid)
Definition namespace.c:345
Definition pg_list.h:54
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition varlena.c:2775

References fb(), GetUserId(), GUC_check_errdetail, InvalidOid, list_free(), newval, pfree(), pstrdup(), SearchPathCacheContext, spcache_init(), spcache_insert(), spcache_lookup(), and SplitIdentifierString().

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 3531 of file namespace.c.

3532{
3533 /* disallow renaming into or out of temp schemas */
3535 ereport(ERROR,
3537 errmsg("cannot move objects into or out of temporary schemas")));
3538
3539 /* same for TOAST schema */
3541 ereport(ERROR,
3543 errmsg("cannot move objects into or out of TOAST schema")));
3544}
int errcode(int sqlerrcode)
Definition elog.c:874
int errmsg(const char *fmt,...)
Definition elog.c:1093
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
bool isAnyTempNamespace(Oid namespaceId)
Definition namespace.c:3759

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

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

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3801 of file namespace.c.

3802{
3803 PGPROC *proc;
3804 ProcNumber procNumber;
3805
3807
3809
3810 /* No such namespace, or its name shows it's not temp? */
3811 if (procNumber == INVALID_PROC_NUMBER)
3813
3814 /* Is the backend alive? */
3815 proc = ProcNumberGetProc(procNumber);
3816 if (proc == NULL)
3817 return TEMP_NAMESPACE_IDLE;
3818
3819 /* Is the backend connected to the same database we are looking at? */
3820 if (proc->databaseId != MyDatabaseId)
3821 return TEMP_NAMESPACE_IDLE;
3822
3823 /* Does the backend own the temporary namespace? */
3824 if (proc->tempNamespaceId != namespaceId)
3825 return TEMP_NAMESPACE_IDLE;
3826
3827 /* Yup, so namespace is busy */
3828 return TEMP_NAMESPACE_IN_USE;
3829}
Oid MyDatabaseId
Definition globals.c:94
ProcNumber GetTempNamespaceProcNumber(Oid namespaceId)
Definition namespace.c:3838
@ TEMP_NAMESPACE_IN_USE
Definition namespace.h:67
@ TEMP_NAMESPACE_NOT_TEMP
Definition namespace.h:65
@ TEMP_NAMESPACE_IDLE
Definition namespace.h:66
PGPROC * ProcNumberGetProc(ProcNumber procNumber)
Definition procarray.c:3102
#define INVALID_PROC_NUMBER
Definition procnumber.h:26
int ProcNumber
Definition procnumber.h:24
Definition proc.h:176
Oid databaseId
Definition proc.h:193

References Assert, PGPROC::databaseId, fb(), GetTempNamespaceProcNumber(), INVALID_PROC_NUMBER, MyDatabaseId, OidIsValid, ProcNumberGetProc(), 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 2442 of file namespace.c.

2443{
2445 ListCell *l;
2446
2448
2449 foreach(l, activeSearchPath)
2450 {
2452 Oid collid;
2453
2455 continue; /* do not look in temp namespace */
2456
2458 if (OidIsValid(collid))
2459 return collid;
2460 }
2461
2462 /* Not found in path */
2463 return InvalidOid;
2464}
int32_t int32
Definition c.h:554
Oid collid
int GetDatabaseEncoding(void)
Definition mbutils.c:1389
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition namespace.c:2391
static List * activeSearchPath
Definition namespace.c:136
static void recomputeNamespacePath(void)
Definition namespace.c:4371
#define lfirst_oid(lc)
Definition pg_list.h:174

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

Referenced by CollationIsVisibleExt().

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2476 of file namespace.c.

2477{
2479}
static bool CollationIsVisibleExt(Oid collid, bool *is_missing)
Definition namespace.c:2488

References CollationIsVisibleExt(), collid, and fb().

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

◆ CollationIsVisibleExt()

static bool CollationIsVisibleExt ( Oid  collid,
bool is_missing 
)
static

Definition at line 2488 of file namespace.c.

2489{
2493 bool visible;
2494
2497 {
2498 if (is_missing != NULL)
2499 {
2500 *is_missing = true;
2501 return false;
2502 }
2503 elog(ERROR, "cache lookup failed for collation %u", collid);
2504 }
2506
2508
2509 /*
2510 * Quick check: if it ain't in the path at all, it ain't visible. Items in
2511 * the system namespace are surely in the path and so we needn't even do
2512 * list_member_oid() for them.
2513 */
2514 collnamespace = collform->collnamespace;
2517 visible = false;
2518 else
2519 {
2520 /*
2521 * If it is in the path, it might still not be visible; it could be
2522 * hidden by another collation of the same name earlier in the path,
2523 * or it might not work with the current DB encoding. So we must do a
2524 * slow check to see if this collation would be found by
2525 * CollationGetCollid.
2526 */
2527 char *collname = NameStr(collform->collname);
2528
2529 visible = (CollationGetCollid(collname) == collid);
2530 }
2531
2533
2534 return visible;
2535}
#define NameStr(name)
Definition c.h:777
#define elog(elevel,...)
Definition elog.h:226
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
bool list_member_oid(const List *list, Oid datum)
Definition list.c:722
Oid CollationGetCollid(const char *collname)
Definition namespace.c:2442
END_CATALOG_STRUCT typedef FormData_pg_collation * Form_pg_collation
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220

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

Referenced by CollationIsVisible(), and pg_collation_is_visible().

◆ ConversionGetConid()

Oid ConversionGetConid ( const char conname)

Definition at line 2546 of file namespace.c.

2547{
2548 Oid conid;
2549 ListCell *l;
2550
2552
2553 foreach(l, activeSearchPath)
2554 {
2556
2558 continue; /* do not look in temp namespace */
2559
2561 PointerGetDatum(conname),
2563 if (OidIsValid(conid))
2564 return conid;
2565 }
2566
2567 /* Not found in path */
2568 return InvalidOid;
2569}
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition syscache.h:111

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

Referenced by ConversionIsVisibleExt().

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2578 of file namespace.c.

2579{
2580 return ConversionIsVisibleExt(conid, NULL);
2581}
static bool ConversionIsVisibleExt(Oid conid, bool *is_missing)
Definition namespace.c:2590

References ConversionIsVisibleExt(), and fb().

Referenced by getObjectDescription().

◆ ConversionIsVisibleExt()

static bool ConversionIsVisibleExt ( Oid  conid,
bool is_missing 
)
static

Definition at line 2590 of file namespace.c.

2591{
2595 bool visible;
2596
2599 {
2600 if (is_missing != NULL)
2601 {
2602 *is_missing = true;
2603 return false;
2604 }
2605 elog(ERROR, "cache lookup failed for conversion %u", conid);
2606 }
2608
2610
2611 /*
2612 * Quick check: if it ain't in the path at all, it ain't visible. Items in
2613 * the system namespace are surely in the path and so we needn't even do
2614 * list_member_oid() for them.
2615 */
2616 connamespace = conform->connamespace;
2619 visible = false;
2620 else
2621 {
2622 /*
2623 * If it is in the path, it might still not be visible; it could be
2624 * hidden by another conversion of the same name earlier in the path.
2625 * So we must do a slow check to see if this conversion would be found
2626 * by ConversionGetConid.
2627 */
2628 char *conname = NameStr(conform->conname);
2629
2630 visible = (ConversionGetConid(conname) == conid);
2631 }
2632
2634
2635 return visible;
2636}
Oid ConversionGetConid(const char *conname)
Definition namespace.c:2546
END_CATALOG_STRUCT typedef FormData_pg_conversion * Form_pg_conversion

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

Referenced by ConversionIsVisible(), and pg_conversion_is_visible().

◆ CopySearchPathMatcher()

SearchPathMatcher * CopySearchPathMatcher ( SearchPathMatcher path)

Definition at line 3961 of file namespace.c.

3962{
3963 SearchPathMatcher *result;
3964
3966 result->schemas = list_copy(path->schemas);
3967 result->addCatalog = path->addCatalog;
3968 result->addTemp = path->addTemp;
3969 result->generation = path->generation;
3970
3971 return result;
3972}
#define palloc_object(type)
Definition fe_memutils.h:74
List * list_copy(const List *oldlist)
Definition list.c:1573

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

Referenced by CopyCachedPlan().

◆ DeconstructQualifiedName()

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

Definition at line 3373 of file namespace.c.

3376{
3377 char *catalogname;
3378 char *schemaname = NULL;
3379 char *objname = NULL;
3380
3381 switch (list_length(names))
3382 {
3383 case 1:
3384 objname = strVal(linitial(names));
3385 break;
3386 case 2:
3387 schemaname = strVal(linitial(names));
3388 objname = strVal(lsecond(names));
3389 break;
3390 case 3:
3391 catalogname = strVal(linitial(names));
3392 schemaname = strVal(lsecond(names));
3393 objname = strVal(lthird(names));
3394
3395 /*
3396 * We check the catalog name and then ignore it.
3397 */
3398 if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
3399 ereport(ERROR,
3401 errmsg("cross-database references are not implemented: %s",
3402 NameListToString(names))));
3403 break;
3404 default:
3405 ereport(ERROR,
3407 errmsg("improper qualified name (too many dotted names): %s",
3408 NameListToString(names))));
3409 break;
3410 }
3411
3412 *nspname_p = schemaname;
3413 *objname_p = objname;
3414}
char * get_database_name(Oid dbid)
Definition lsyscache.c:1242
char * NameListToString(const List *names)
Definition namespace.c:3666
static int list_length(const List *l)
Definition pg_list.h:152
#define lthird(l)
Definition pg_list.h:188
#define linitial(l)
Definition pg_list.h:178
#define lsecond(l)
Definition pg_list.h:183
#define strVal(v)
Definition value.h:82

References ereport, errcode(), errmsg(), ERROR, fb(), 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 4891 of file namespace.c.

4892{
4893 List *result;
4894
4896
4897 /*
4898 * If the temp namespace should be first, force it to exist. This is so
4899 * that callers can trust the result to reflect the actual default
4900 * creation namespace. It's a bit bogus to do this here, since
4901 * current_schema() is supposedly a stable function without side-effects,
4902 * but the alternatives seem worse.
4903 */
4905 {
4908 }
4909
4910 result = list_copy(activeSearchPath);
4911 if (!includeImplicit)
4912 {
4913 while (result && linitial_oid(result) != activeCreationNamespace)
4914 result = list_delete_first(result);
4915 }
4916
4917 return result;
4918}
List * list_delete_first(List *list)
Definition list.c:943
static Oid activeCreationNamespace
Definition namespace.c:139
static bool activeTempCreationPending
Definition namespace.c:142
static void AccessTempTableNamespace(bool force)
Definition namespace.c:4434
#define linitial_oid(l)
Definition pg_list.h:180

References AccessTempTableNamespace(), activeCreationNamespace, activeSearchPath, activeTempCreationPending, fb(), 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 4931 of file namespace.c.

4932{
4933 int count = 0;
4934 ListCell *l;
4935
4937
4938 foreach(l, activeSearchPath)
4939 {
4941
4943 continue; /* do not include temp namespace */
4944
4945 if (count < sarray_len)
4946 sarray[count] = namespaceId;
4947 count++;
4948 }
4949
4950 return count;
4951}

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

Referenced by make_oper_cache_key().

◆ finalNamespacePath()

static List * finalNamespacePath ( List oidlist,
Oid firstNS 
)
static

Definition at line 4270 of file namespace.c.

4271{
4272 List *finalPath = NIL;
4273 ListCell *lc;
4274
4275 foreach(lc, oidlist)
4276 {
4278
4279 if (!list_member_oid(finalPath, namespaceId))
4280 {
4282 finalPath = lappend_oid(finalPath, namespaceId);
4283 }
4284 }
4285
4286 /*
4287 * Remember the first member of the explicit list. (Note: this is
4288 * nominally wrong if temp_missing, but we need it anyway to distinguish
4289 * explicit from implicit mention of pg_catalog.)
4290 */
4291 if (finalPath == NIL)
4292 *firstNS = InvalidOid;
4293 else
4294 *firstNS = linitial_oid(finalPath);
4295
4296 /*
4297 * Add any implicitly-searched namespaces to the list. Note these go on
4298 * the front, not the back; also notice that we do not check USAGE
4299 * permissions for these.
4300 */
4301 if (!list_member_oid(finalPath, PG_CATALOG_NAMESPACE))
4302 finalPath = lcons_oid(PG_CATALOG_NAMESPACE, finalPath);
4303
4305 !list_member_oid(finalPath, myTempNamespace))
4306 finalPath = lcons_oid(myTempNamespace, finalPath);
4307
4308 return finalPath;
4309}
List * lcons_oid(Oid datum, List *list)
Definition list.c:531
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)

References fb(), InvalidOid, InvokeNamespaceSearchHook, lappend_oid(), lcons_oid(), lfirst_oid, linitial_oid, list_member_oid(), myTempNamespace, NIL, and OidIsValid.

Referenced by cachedNamespacePath().

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 4152 of file namespace.c.

4153{
4154 Oid proc;
4155 ListCell *l;
4156
4158
4159 foreach(l, activeSearchPath)
4160 {
4162
4164 continue; /* do not look in temp namespace */
4165
4167 if (OidIsValid(proc))
4168 return proc;
4169 }
4170
4171 /* Not found in path */
4172 return InvalidOid;
4173}
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)

References activeSearchPath, fb(), 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,
int fgc_flags 
)

Definition at line 1199 of file namespace.c.

1203{
1205 bool any_special = false;
1206 char *schemaname;
1207 char *funcname;
1210 int i;
1211
1212 /* check for caller error */
1213 Assert(nargs >= 0 || !(expand_variadic | expand_defaults));
1214
1215 /* initialize output fgc_flags to empty */
1216 *fgc_flags = 0;
1217
1218 /* deconstruct the name list */
1219 DeconstructQualifiedName(names, &schemaname, &funcname);
1220
1221 if (schemaname)
1222 {
1223 /* use exact schema given */
1224 *fgc_flags |= FGC_SCHEMA_GIVEN; /* report that a schema is given */
1225 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
1226 if (!OidIsValid(namespaceId))
1227 return NULL;
1228 *fgc_flags |= FGC_SCHEMA_EXISTS; /* report that the schema exists */
1229 }
1230 else
1231 {
1232 /* flag to indicate we need namespace search */
1235 }
1236
1237 /* Search syscache by name only */
1239
1240 for (i = 0; i < catlist->n_members; i++)
1241 {
1242 HeapTuple proctup = &catlist->members[i]->tuple;
1244 Oid *proargtypes = procform->proargtypes.values;
1245 int pronargs = procform->pronargs;
1246 int effective_nargs;
1247 int pathpos = 0;
1248 bool variadic;
1249 bool use_defaults;
1251 int *argnumbers = NULL;
1253
1254 *fgc_flags |= FGC_NAME_EXISTS; /* the name is present in pg_proc */
1255
1257 {
1258 /* Consider only procs in specified namespace */
1259 if (procform->pronamespace != namespaceId)
1260 continue;
1261 }
1262 else
1263 {
1264 /*
1265 * Consider only procs that are in the search path and are not in
1266 * the temp namespace.
1267 */
1268 ListCell *nsp;
1269
1270 foreach(nsp, activeSearchPath)
1271 {
1272 if (procform->pronamespace == lfirst_oid(nsp) &&
1273 procform->pronamespace != myTempNamespace)
1274 break;
1275 pathpos++;
1276 }
1277 if (nsp == NULL)
1278 continue; /* proc is not in search path */
1279 }
1280
1281 *fgc_flags |= FGC_NAME_VISIBLE; /* routine is in the right schema */
1282
1283 /*
1284 * If we are asked to match to OUT arguments, then use the
1285 * proallargtypes array (which includes those); otherwise use
1286 * proargtypes (which doesn't). Of course, if proallargtypes is null,
1287 * we always use proargtypes.
1288 */
1290 {
1292 bool isNull;
1293
1296 &isNull);
1297 if (!isNull)
1298 {
1300
1301 pronargs = ARR_DIMS(arr)[0];
1302 if (ARR_NDIM(arr) != 1 ||
1303 pronargs < 0 ||
1304 ARR_HASNULL(arr) ||
1305 ARR_ELEMTYPE(arr) != OIDOID)
1306 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
1307 Assert(pronargs >= procform->pronargs);
1308 proargtypes = (Oid *) ARR_DATA_PTR(arr);
1309 }
1310 }
1311
1312 if (argnames != NIL)
1313 {
1314 /*
1315 * Call uses named or mixed notation
1316 *
1317 * Check argument count.
1318 */
1319 Assert(nargs >= 0); /* -1 not supported with argnames */
1320
1321 if (pronargs > nargs && expand_defaults)
1322 {
1323 /* Ignore if not enough default expressions */
1324 if (nargs + procform->pronargdefaults < pronargs)
1325 continue;
1326 use_defaults = true;
1327 }
1328 else
1329 use_defaults = false;
1330
1331 /* Ignore if it doesn't match requested argument count */
1332 if (pronargs != nargs && !use_defaults)
1333 continue;
1334
1335 /* We found a routine with a suitable number of arguments */
1337
1338 /* Check for argument name match, generate positional mapping */
1339 if (!MatchNamedCall(proctup, nargs, argnames,
1341 &argnumbers, fgc_flags))
1342 continue;
1343
1344 /*
1345 * Named or mixed notation can match a variadic function only if
1346 * expand_variadic is off; otherwise there is no way to match the
1347 * presumed-nameless parameters expanded from the variadic array.
1348 * However, we postpone the check until here because we want to
1349 * perform argument name matching anyway (using the variadic array
1350 * argument's name). This allows us to give an on-point error
1351 * message if the user forgets to say VARIADIC in what would have
1352 * been a valid call with it.
1353 */
1354 if (OidIsValid(procform->provariadic) && expand_variadic)
1355 continue;
1357 variadic = false;
1358
1359 /* We found a fully-valid call using argument names */
1361
1362 /* Named argument matching is always "special" */
1363 any_special = true;
1364 }
1365 else
1366 {
1367 /*
1368 * Call uses positional notation
1369 *
1370 * Check if function is variadic, and get variadic element type if
1371 * so. If expand_variadic is false, we should just ignore
1372 * variadic-ness.
1373 */
1374 if (pronargs <= nargs && expand_variadic)
1375 {
1376 va_elem_type = procform->provariadic;
1379 }
1380 else
1381 {
1383 variadic = false;
1384 }
1385
1386 /*
1387 * Check if function can match by using parameter defaults.
1388 */
1389 if (pronargs > nargs && expand_defaults)
1390 {
1391 /* Ignore if not enough default expressions */
1392 if (nargs + procform->pronargdefaults < pronargs)
1393 continue;
1394 use_defaults = true;
1395 any_special = true;
1396 }
1397 else
1398 use_defaults = false;
1399
1400 /* Ignore if it doesn't match requested argument count */
1401 if (nargs >= 0 && pronargs != nargs && !variadic && !use_defaults)
1402 continue;
1403
1404 /* We found a routine with a suitable number of arguments */
1406 }
1407
1408 /*
1409 * We must compute the effective argument list so that we can easily
1410 * compare it to earlier results. We waste a palloc cycle if it gets
1411 * masked by an earlier result, but really that's a pretty infrequent
1412 * case so it's not worth worrying about.
1413 */
1414 effective_nargs = Max(pronargs, nargs);
1416 palloc(offsetof(struct _FuncCandidateList, args) +
1417 effective_nargs * sizeof(Oid));
1418 newResult->pathpos = pathpos;
1419 newResult->oid = procform->oid;
1420 newResult->nominalnargs = pronargs;
1421 newResult->nargs = effective_nargs;
1422 newResult->argnumbers = argnumbers;
1423 if (argnumbers)
1424 {
1425 /* Re-order the argument types into call's logical order */
1426 for (int j = 0; j < pronargs; j++)
1427 newResult->args[j] = proargtypes[argnumbers[j]];
1428 }
1429 else
1430 {
1431 /* Simple positional case, just copy proargtypes as-is */
1432 memcpy(newResult->args, proargtypes, pronargs * sizeof(Oid));
1433 }
1434 if (variadic)
1435 {
1436 newResult->nvargs = effective_nargs - pronargs + 1;
1437 /* Expand variadic argument into N copies of element type */
1438 for (int j = pronargs - 1; j < effective_nargs; j++)
1439 newResult->args[j] = va_elem_type;
1440 }
1441 else
1442 newResult->nvargs = 0;
1443 newResult->ndargs = use_defaults ? pronargs - nargs : 0;
1444
1445 /*
1446 * Does it have the same arguments as something we already accepted?
1447 * If so, decide what to do to avoid returning duplicate argument
1448 * lists. We can skip this check for the single-namespace case if no
1449 * special (named, variadic or defaults) match has been made, since
1450 * then the unique index on pg_proc guarantees all the matches have
1451 * different argument lists.
1452 */
1453 if (resultList != NULL &&
1455 {
1456 /*
1457 * If we have an ordered list from SearchSysCacheList (the normal
1458 * case), then any conflicting proc must immediately adjoin this
1459 * one in the list, so we only need to look at the newest result
1460 * item. If we have an unordered list, we have to scan the whole
1461 * result list. Also, if either the current candidate or any
1462 * previous candidate is a special match, we can't assume that
1463 * conflicts are adjacent.
1464 *
1465 * We ignore defaulted arguments in deciding what is a match.
1466 */
1468
1469 if (catlist->ordered && !any_special)
1470 {
1471 /* ndargs must be 0 if !any_special */
1472 if (effective_nargs == resultList->nargs &&
1473 memcmp(newResult->args,
1474 resultList->args,
1475 effective_nargs * sizeof(Oid)) == 0)
1477 else
1478 prevResult = NULL;
1479 }
1480 else
1481 {
1482 int cmp_nargs = newResult->nargs - newResult->ndargs;
1483
1484 for (prevResult = resultList;
1485 prevResult;
1486 prevResult = prevResult->next)
1487 {
1488 if (cmp_nargs == prevResult->nargs - prevResult->ndargs &&
1489 memcmp(newResult->args,
1490 prevResult->args,
1491 cmp_nargs * sizeof(Oid)) == 0)
1492 break;
1493 }
1494 }
1495
1496 if (prevResult)
1497 {
1498 /*
1499 * We have a match with a previous result. Decide which one
1500 * to keep, or mark it ambiguous if we can't decide. The
1501 * logic here is preference > 0 means prefer the old result,
1502 * preference < 0 means prefer the new, preference = 0 means
1503 * ambiguous.
1504 */
1505 int preference;
1506
1507 if (pathpos != prevResult->pathpos)
1508 {
1509 /*
1510 * Prefer the one that's earlier in the search path.
1511 */
1512 preference = pathpos - prevResult->pathpos;
1513 }
1514 else if (variadic && prevResult->nvargs == 0)
1515 {
1516 /*
1517 * With variadic functions we could have, for example,
1518 * both foo(numeric) and foo(variadic numeric[]) in the
1519 * same namespace; if so we prefer the non-variadic match
1520 * on efficiency grounds.
1521 */
1522 preference = 1;
1523 }
1524 else if (!variadic && prevResult->nvargs > 0)
1525 {
1526 preference = -1;
1527 }
1528 else
1529 {
1530 /*----------
1531 * We can't decide. This can happen with, for example,
1532 * both foo(numeric, variadic numeric[]) and
1533 * foo(variadic numeric[]) in the same namespace, or
1534 * both foo(int) and foo (int, int default something)
1535 * in the same namespace, or both foo(a int, b text)
1536 * and foo(b text, a int) in the same namespace.
1537 *----------
1538 */
1539 preference = 0;
1540 }
1541
1542 if (preference > 0)
1543 {
1544 /* keep previous result */
1546 continue;
1547 }
1548 else if (preference < 0)
1549 {
1550 /* remove previous result from the list */
1551 if (prevResult == resultList)
1552 resultList = prevResult->next;
1553 else
1554 {
1556
1560 {
1561 if (prevResult == prevPrevResult->next)
1562 {
1564 break;
1565 }
1566 }
1567 Assert(prevPrevResult); /* assert we found it */
1568 }
1570 /* fall through to add newResult to list */
1571 }
1572 else
1573 {
1574 /* mark old result as ambiguous, discard new */
1575 prevResult->oid = InvalidOid;
1577 continue;
1578 }
1579 }
1580 }
1581
1582 /*
1583 * Okay to add it to result list
1584 */
1585 newResult->next = resultList;
1587 }
1588
1590
1591 return resultList;
1592}
#define ARR_NDIM(a)
Definition array.h:290
#define ARR_DATA_PTR(a)
Definition array.h:322
#define DatumGetArrayTypeP(X)
Definition array.h:261
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define ARR_DIMS(a)
Definition array.h:294
#define ARR_HASNULL(a)
Definition array.h:291
#define Max(x, y)
Definition c.h:1013
#define funcname
int j
Definition isn.c:78
int i
Definition isn.c:77
void * palloc(Size size)
Definition mcxt.c:1387
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition namespace.c:3457
void DeconstructQualifiedName(const List *names, char **nspname_p, char **objname_p)
Definition namespace.c:3373
static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, bool include_out_arguments, int pronargs, int **argnumbers, int *fgc_flags)
Definition namespace.c:1618
#define FGC_NAME_EXISTS
Definition namespace.h:49
#define FGC_ARGNAMES_VALID
Definition namespace.h:56
#define FGC_SCHEMA_GIVEN
Definition namespace.h:47
#define FGC_ARGCOUNT_MATCH
Definition namespace.h:51
struct _FuncCandidateList * FuncCandidateList
#define FGC_NAME_VISIBLE
Definition namespace.h:50
#define FGC_SCHEMA_EXISTS
Definition namespace.h:48
int16 pronargs
Definition pg_proc.h:83
END_CATALOG_STRUCT typedef FormData_pg_proc * Form_pg_proc
Definition pg_proc.h:140
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
struct _FuncCandidateList * next
Definition namespace.h:31
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
#define ReleaseSysCacheList(x)
Definition syscache.h:134
#define SearchSysCacheList1(cacheId, key1)
Definition syscache.h:127

References activeSearchPath, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, Assert, CStringGetDatum(), DatumGetArrayTypeP, DeconstructQualifiedName(), elog, ERROR, fb(), FGC_ARGCOUNT_MATCH, FGC_ARGNAMES_VALID, FGC_NAME_EXISTS, FGC_NAME_VISIBLE, FGC_SCHEMA_EXISTS, FGC_SCHEMA_GIVEN, Form_pg_proc, funcname, GETSTRUCT(), i, InvalidOid, j, lfirst_oid, LookupExplicitNamespace(), MatchNamedCall(), Max, myTempNamespace, _FuncCandidateList::nargs, _FuncCandidateList::next, NIL, OidIsValid, palloc(), pfree(), pronargs, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, and SysCacheGetAttr().

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1743 of file namespace.c.

1744{
1745 return FunctionIsVisibleExt(funcid, NULL);
1746}
static bool FunctionIsVisibleExt(Oid funcid, bool *is_missing)
Definition namespace.c:1755

References fb(), and FunctionIsVisibleExt().

Referenced by format_procedure_extended().

◆ FunctionIsVisibleExt()

static bool FunctionIsVisibleExt ( Oid  funcid,
bool is_missing 
)
static

Definition at line 1755 of file namespace.c.

1756{
1760 bool visible;
1761
1764 {
1765 if (is_missing != NULL)
1766 {
1767 *is_missing = true;
1768 return false;
1769 }
1770 elog(ERROR, "cache lookup failed for function %u", funcid);
1771 }
1773
1775
1776 /*
1777 * Quick check: if it ain't in the path at all, it ain't visible. Items in
1778 * the system namespace are surely in the path and so we needn't even do
1779 * list_member_oid() for them.
1780 */
1781 pronamespace = procform->pronamespace;
1784 visible = false;
1785 else
1786 {
1787 /*
1788 * If it is in the path, it might still not be visible; it could be
1789 * hidden by another proc of the same name and arguments earlier in
1790 * the path. So we must do a slow check to see if this is the same
1791 * proc that would be found by FuncnameGetCandidates.
1792 */
1793 char *proname = NameStr(procform->proname);
1794 int nargs = procform->pronargs;
1796 int fgc_flags;
1797
1798 visible = false;
1799
1801 nargs, NIL, false, false, false, false,
1802 &fgc_flags);
1803
1804 for (; clist; clist = clist->next)
1805 {
1806 if (memcmp(clist->args, procform->proargtypes.values,
1807 nargs * sizeof(Oid)) == 0)
1808 {
1809 /* Found the expected entry; is it the right proc? */
1810 visible = (clist->oid == funcid);
1811 break;
1812 }
1813 }
1814 }
1815
1817
1818 return visible;
1819}
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok, int *fgc_flags)
Definition namespace.c:1199
#define list_make1(x1)
Definition pg_list.h:212
NameData proname
Definition pg_proc.h:37
String * makeString(char *str)
Definition value.c:63

References activeSearchPath, elog, ERROR, fb(), Form_pg_proc, FuncnameGetCandidates(), GETSTRUCT(), HeapTupleIsValid, list_make1, list_member_oid(), makeString(), NameStr, NIL, ObjectIdGetDatum(), proname, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1().

Referenced by FunctionIsVisible(), and pg_function_is_visible().

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 4043 of file namespace.c.

4044{
4045 char *schemaname;
4046 char *collation_name;
4049 Oid colloid;
4050 ListCell *l;
4051
4052 /* deconstruct the name list */
4053 DeconstructQualifiedName(collname, &schemaname, &collation_name);
4054
4055 if (schemaname)
4056 {
4057 /* use exact schema given */
4058 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
4059 if (missing_ok && !OidIsValid(namespaceId))
4060 return InvalidOid;
4061
4063 if (OidIsValid(colloid))
4064 return colloid;
4065 }
4066 else
4067 {
4068 /* search for it in search path */
4070
4071 foreach(l, activeSearchPath)
4072 {
4074
4076 continue; /* do not look in temp namespace */
4077
4079 if (OidIsValid(colloid))
4080 return colloid;
4081 }
4082 }
4083
4084 /* Not found in path */
4085 if (!missing_ok)
4086 ereport(ERROR,
4088 errmsg("collation \"%s\" for encoding \"%s\" does not exist",
4090 return InvalidOid;
4091}
const char * GetDatabaseEncodingName(void)
Definition mbutils.c:1395

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

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

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 4097 of file namespace.c.

4098{
4099 char *schemaname;
4100 char *conversion_name;
4102 Oid conoid = InvalidOid;
4103 ListCell *l;
4104
4105 /* deconstruct the name list */
4106 DeconstructQualifiedName(conname, &schemaname, &conversion_name);
4107
4108 if (schemaname)
4109 {
4110 /* use exact schema given */
4111 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
4112 if (missing_ok && !OidIsValid(namespaceId))
4113 conoid = InvalidOid;
4114 else
4116 PointerGetDatum(conversion_name),
4118 }
4119 else
4120 {
4121 /* search for it in search path */
4123
4124 foreach(l, activeSearchPath)
4125 {
4127
4129 continue; /* do not look in temp namespace */
4130
4132 PointerGetDatum(conversion_name),
4134 if (OidIsValid(conoid))
4135 return conoid;
4136 }
4137 }
4138
4139 /* Not found in path */
4140 if (!OidIsValid(conoid) && !missing_ok)
4141 ereport(ERROR,
4143 errmsg("conversion \"%s\" does not exist",
4144 NameListToString(conname))));
4145 return conoid;
4146}

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

Referenced by get_object_address().

◆ get_namespace_oid()

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2644 of file namespace.c.

2645{
2646 char *schemaname;
2647 char *stats_name;
2650 ListCell *l;
2651
2652 /* deconstruct the name list */
2653 DeconstructQualifiedName(names, &schemaname, &stats_name);
2654
2655 if (schemaname)
2656 {
2657 /* use exact schema given */
2658 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2659 if (missing_ok && !OidIsValid(namespaceId))
2661 else
2665 }
2666 else
2667 {
2668 /* search for it in search path */
2670
2671 foreach(l, activeSearchPath)
2672 {
2674
2676 continue; /* do not look in temp namespace */
2680 if (OidIsValid(stats_oid))
2681 break;
2682 }
2683 }
2684
2685 if (!OidIsValid(stats_oid) && !missing_ok)
2686 ereport(ERROR,
2688 errmsg("statistics object \"%s\" does not exist",
2689 NameListToString(names))));
2690
2691 return stats_oid;
2692}

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

Referenced by AlterStatistics(), and get_object_address().

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 3224 of file namespace.c.

3225{
3226 char *schemaname;
3227 char *config_name;
3230 ListCell *l;
3231
3232 /* deconstruct the name list */
3233 DeconstructQualifiedName(names, &schemaname, &config_name);
3234
3235 if (schemaname)
3236 {
3237 /* use exact schema given */
3238 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3239 if (missing_ok && !OidIsValid(namespaceId))
3241 else
3245 }
3246 else
3247 {
3248 /* search for it in search path */
3250
3251 foreach(l, activeSearchPath)
3252 {
3254
3256 continue; /* do not look in temp namespace */
3257
3261 if (OidIsValid(cfgoid))
3262 break;
3263 }
3264 }
3265
3266 if (!OidIsValid(cfgoid) && !missing_ok)
3267 ereport(ERROR,
3269 errmsg("text search configuration \"%s\" does not exist",
3270 NameListToString(names))));
3271
3272 return cfgoid;
3273}

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

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 2933 of file namespace.c.

2934{
2935 char *schemaname;
2936 char *dict_name;
2939 ListCell *l;
2940
2941 /* deconstruct the name list */
2942 DeconstructQualifiedName(names, &schemaname, &dict_name);
2943
2944 if (schemaname)
2945 {
2946 /* use exact schema given */
2947 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2948 if (missing_ok && !OidIsValid(namespaceId))
2950 else
2954 }
2955 else
2956 {
2957 /* search for it in search path */
2959
2960 foreach(l, activeSearchPath)
2961 {
2963
2965 continue; /* do not look in temp namespace */
2966
2970 if (OidIsValid(dictoid))
2971 break;
2972 }
2973 }
2974
2975 if (!OidIsValid(dictoid) && !missing_ok)
2976 ereport(ERROR,
2978 errmsg("text search dictionary \"%s\" does not exist",
2979 NameListToString(names))));
2980
2981 return dictoid;
2982}

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

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 2788 of file namespace.c.

2789{
2790 char *schemaname;
2791 char *parser_name;
2794 ListCell *l;
2795
2796 /* deconstruct the name list */
2797 DeconstructQualifiedName(names, &schemaname, &parser_name);
2798
2799 if (schemaname)
2800 {
2801 /* use exact schema given */
2802 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2803 if (missing_ok && !OidIsValid(namespaceId))
2805 else
2809 }
2810 else
2811 {
2812 /* search for it in search path */
2814
2815 foreach(l, activeSearchPath)
2816 {
2818
2820 continue; /* do not look in temp namespace */
2821
2825 if (OidIsValid(prsoid))
2826 break;
2827 }
2828 }
2829
2830 if (!OidIsValid(prsoid) && !missing_ok)
2831 ereport(ERROR,
2833 errmsg("text search parser \"%s\" does not exist",
2834 NameListToString(names))));
2835
2836 return prsoid;
2837}

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

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 3079 of file namespace.c.

3080{
3081 char *schemaname;
3082 char *template_name;
3085 ListCell *l;
3086
3087 /* deconstruct the name list */
3088 DeconstructQualifiedName(names, &schemaname, &template_name);
3089
3090 if (schemaname)
3091 {
3092 /* use exact schema given */
3093 namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3094 if (missing_ok && !OidIsValid(namespaceId))
3096 else
3100 }
3101 else
3102 {
3103 /* search for it in search path */
3105
3106 foreach(l, activeSearchPath)
3107 {
3109
3111 continue; /* do not look in temp namespace */
3112
3116 if (OidIsValid(tmploid))
3117 break;
3118 }
3119 }
3120
3121 if (!OidIsValid(tmploid) && !missing_ok)
3122 ereport(ERROR,
3124 errmsg("text search template \"%s\" does not exist",
3125 NameListToString(names))));
3126
3127 return tmploid;
3128}

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

Referenced by DefineTSDictionary(), and get_object_address().

◆ GetSearchPathMatcher()

SearchPathMatcher * GetSearchPathMatcher ( MemoryContext  context)

Definition at line 3924 of file namespace.c.

3925{
3926 SearchPathMatcher *result;
3927 List *schemas;
3929
3931
3932 oldcxt = MemoryContextSwitchTo(context);
3933
3935 schemas = list_copy(activeSearchPath);
3936 while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3937 {
3938 if (linitial_oid(schemas) == myTempNamespace)
3939 result->addTemp = true;
3940 else
3941 {
3943 result->addCatalog = true;
3944 }
3945 schemas = list_delete_first(schemas);
3946 }
3947 result->schemas = schemas;
3949
3951
3952 return result;
3953}
#define palloc0_object(type)
Definition fe_memutils.h:75
static uint64 activePathGeneration
Definition namespace.c:145

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

Referenced by CompleteCachedPlan(), and RevalidateCachedQuery().

◆ GetTempNamespaceProcNumber()

ProcNumber GetTempNamespaceProcNumber ( Oid  namespaceId)

Definition at line 3838 of file namespace.c.

3839{
3840 int result;
3841 char *nspname;
3842
3843 /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3845 if (!nspname)
3846 return INVALID_PROC_NUMBER; /* no such namespace? */
3847 if (strncmp(nspname, "pg_temp_", 8) == 0)
3848 result = atoi(nspname + 8);
3849 else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3850 result = atoi(nspname + 14);
3851 else
3852 result = INVALID_PROC_NUMBER;
3853 pfree(nspname);
3854 return result;
3855}
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3518

References fb(), get_namespace_name(), INVALID_PROC_NUMBER, and pfree().

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

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3877 of file namespace.c.

3878{
3879 /* Return namespace OIDs, or 0 if session has not created temp namespace */
3880 *tempNamespaceId = myTempNamespace;
3882}

References fb(), myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3863 of file namespace.c.

3864{
3866 return myTempToastNamespace;
3867}

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4808 of file namespace.c.

4809{
4811 {
4812 /*
4813 * In bootstrap mode, the search path must be 'pg_catalog' so that
4814 * tables are created in the proper namespace; ignore the GUC setting.
4815 */
4817
4823 baseSearchPathValid = true;
4828 activePathGeneration++; /* pro forma */
4829 }
4830 else
4831 {
4832 /*
4833 * In normal mode, arrange for a callback on any syscache invalidation
4834 * that will affect the search_path cache.
4835 */
4836
4837 /* namespace name or ACLs may have changed */
4840 (Datum) 0);
4841
4842 /* role name may affect the meaning of "$user" */
4845 (Datum) 0);
4846
4847 /* role membership may affect ACLs */
4850 (Datum) 0);
4851
4852 /* database owner may affect ACLs */
4855 (Datum) 0);
4856
4857 /* Force search path to be recomputed on next use */
4858 baseSearchPathValid = false;
4859 searchPathCacheValid = false;
4860 }
4861}
void CacheRegisterSyscacheCallback(SysCacheIdentifier cacheid, SyscacheCallbackFunction func, Datum arg)
Definition inval.c:1816
MemoryContext TopMemoryContext
Definition mcxt.c:166
static bool baseTempCreationPending
Definition namespace.c:153
static Oid baseCreationNamespace
Definition namespace.c:151
static Oid namespaceUser
Definition namespace.c:155
static List * baseSearchPath
Definition namespace.c:149
static void InvalidationCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
Definition namespace.c:4868
#define list_make1_oid(x1)
Definition pg_list.h:242

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

Referenced by InitPostgres().

◆ InitTempTableNamespace()

static void InitTempTableNamespace ( void  )
static

Definition at line 4462 of file namespace.c.

4463{
4467
4469
4470 /*
4471 * First, do permission check to see if we are authorized to make temp
4472 * tables. We use a nonstandard error message here since "databasename:
4473 * permission denied" might be a tad cryptic.
4474 *
4475 * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
4476 * that's necessary since current user ID could change during the session.
4477 * But there's no need to make the namespace in the first place until a
4478 * temp table creation request is made by someone with appropriate rights.
4479 */
4482 ereport(ERROR,
4484 errmsg("permission denied to create temporary tables in database \"%s\"",
4486
4487 /*
4488 * Do not allow a Hot Standby session to make temp tables. Aside from
4489 * problems with modifying the system catalogs, there is a naming
4490 * conflict: pg_temp_N belongs to the session with proc number N on the
4491 * primary, not to a hot standby session with the same proc number. We
4492 * should not be able to get here anyway due to XactReadOnly checks, but
4493 * let's just make real sure. Note that this also backstops various
4494 * operations that allow XactReadOnly transactions to modify temp tables;
4495 * they'd need RecoveryInProgress checks if not for this.
4496 */
4497 if (RecoveryInProgress())
4498 ereport(ERROR,
4500 errmsg("cannot create temporary tables during recovery")));
4501
4502 /* Parallel workers can't create temporary tables, either. */
4503 if (IsParallelWorker())
4504 ereport(ERROR,
4506 errmsg("cannot create temporary tables during a parallel operation")));
4507
4508 snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyProcNumber);
4509
4511 if (!OidIsValid(namespaceId))
4512 {
4513 /*
4514 * First use of this temp namespace in this database; create it. The
4515 * temp namespaces are always owned by the superuser. We leave their
4516 * permissions at default --- i.e., no access except to superuser ---
4517 * to ensure that unprivileged users can't peek at other backends'
4518 * temp tables. This works because the places that access the temp
4519 * namespace for my own backend skip permissions checks on it.
4520 */
4522 true);
4523 /* Advance command counter to make namespace visible */
4525 }
4526 else
4527 {
4528 /*
4529 * If the namespace already exists, clean it out (in case the former
4530 * owner crashed without doing so).
4531 */
4533 }
4534
4535 /*
4536 * If the corresponding toast-table namespace doesn't exist yet, create
4537 * it. (We assume there is no need to clean it out if it does exist, since
4538 * dropping a parent table should make its toast table go away.)
4539 */
4540 snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
4541 MyProcNumber);
4542
4545 {
4547 true);
4548 /* Advance command counter to make namespace visible */
4550 }
4551
4552 /*
4553 * Okay, we've prepared the temp namespace ... but it's not committed yet,
4554 * so all our work could be undone by transaction rollback. Set flag for
4555 * AtEOXact_Namespace to know what to do.
4556 */
4559
4560 /*
4561 * Mark MyProc as owning this namespace which other processes can use to
4562 * decide if a temporary namespace is in use or not. We assume that
4563 * assignment of namespaceId is an atomic operation. Even if it is not,
4564 * the temporary relation which resulted in the creation of this temporary
4565 * namespace is still locked until the current transaction commits, and
4566 * its pg_namespace row is not visible yet. However it does not matter:
4567 * this flag makes the namespace as being in use, so no objects created on
4568 * it would be removed concurrently.
4569 */
4571
4572 /* It should not be done already. */
4575
4576 baseSearchPathValid = false; /* need to rebuild list */
4577 searchPathCacheValid = false;
4578}
@ ACLCHECK_OK
Definition acl.h:183
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3854
ProcNumber MyProcNumber
Definition globals.c:90
#define IsParallelWorker()
Definition parallel.h:62
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition namespace.c:3607
static void RemoveTempRelations(Oid tempNamespaceId)
Definition namespace.c:4670
#define ACL_CREATE_TEMP
Definition parsenodes.h:86
#define NAMEDATALEN
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
#define snprintf
Definition port.h:260
SubTransactionId GetCurrentSubTransactionId(void)
Definition xact.c:792
void CommandCounterIncrement(void)
Definition xact.c:1101
bool RecoveryInProgress(void)
Definition xlog.c:6460

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

Referenced by AccessTempTableNamespace().

◆ InvalidationCallback()

static void InvalidationCallback ( Datum  arg,
SysCacheIdentifier  cacheid,
uint32  hashvalue 
)
static

Definition at line 4868 of file namespace.c.

4869{
4870 /*
4871 * Force search path to be recomputed on next use, also invalidating the
4872 * search path cache (because namespace names, ACLs, or role names may
4873 * have changed).
4874 */
4875 baseSearchPathValid = false;
4876 searchPathCacheValid = false;
4877}

References baseSearchPathValid, and searchPathCacheValid.

Referenced by InitializeSearchPath().

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3759 of file namespace.c.

3760{
3761 bool result;
3762 char *nspname;
3763
3764 /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3766 if (!nspname)
3767 return false; /* no such namespace? */
3768 result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3769 (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3770 pfree(nspname);
3771 return result;
3772}

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

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

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3782 of file namespace.c.

3783{
3784 /* If it's my own temp namespace, say "false" */
3786 return false;
3787 /* Else, if it's any temp namespace, say "true" */
3789}
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition namespace.c:3745

References fb(), isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

◆ isTempNamespace()

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3733 of file namespace.c.

3734{
3736 return true;
3737 return false;
3738}

References fb(), myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

◆ lookup_collation()

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

Definition at line 2391 of file namespace.c.

2392{
2393 Oid collid;
2396
2397 /* Check for encoding-specific entry (exact match) */
2399 PointerGetDatum(collname),
2402 if (OidIsValid(collid))
2403 return collid;
2404
2405 /*
2406 * Check for any-encoding entry. This takes a bit more work: while libc
2407 * collations with collencoding = -1 do work with all encodings, ICU
2408 * collations only work with certain encodings, so we have to check that
2409 * aspect before deciding it's a match.
2410 */
2412 PointerGetDatum(collname),
2413 Int32GetDatum(-1),
2416 return InvalidOid;
2418 if (collform->collprovider == COLLPROVIDER_ICU)
2419 {
2421 collid = collform->oid;
2422 else
2424 }
2425 else
2426 {
2427 collid = collform->oid;
2428 }
2430 return collid;
2431}
bool is_encoding_supported_by_icu(int encoding)
Definition encnames.c:461
static char * encoding
Definition initdb.c:139
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
HeapTuple SearchSysCache3(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3)
Definition syscache.c:240
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition syscache.h:113

References collid, encoding, fb(), Form_pg_collation, 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 3500 of file namespace.c.

3501{
3504
3505 /* check for pg_temp alias */
3506 if (strcmp(nspname, "pg_temp") == 0)
3507 {
3508 /* Initialize temp namespace */
3510 return myTempNamespace;
3511 }
3512
3513 namespaceId = get_namespace_oid(nspname, false);
3514
3516 if (aclresult != ACLCHECK_OK)
3518 nspname);
3519
3520 return namespaceId;
3521}
AclResult
Definition acl.h:182
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2654
@ OBJECT_SCHEMA
#define ACL_CREATE
Definition parsenodes.h:85

References AccessTempTableNamespace(), ACL_CREATE, aclcheck_error(), ACLCHECK_OK, fb(), 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 3457 of file namespace.c.

3458{
3461
3462 /* check for pg_temp alias */
3463 if (strcmp(nspname, "pg_temp") == 0)
3464 {
3466 return myTempNamespace;
3467
3468 /*
3469 * Since this is used only for looking up existing objects, there is
3470 * no point in trying to initialize the temp namespace here; and doing
3471 * so might create problems for some callers --- just fall through.
3472 */
3473 }
3474
3475 namespaceId = get_namespace_oid(nspname, missing_ok);
3476 if (missing_ok && !OidIsValid(namespaceId))
3477 return InvalidOid;
3478
3480 if (aclresult != ACLCHECK_OK)
3482 nspname);
3483 /* Schema search hook for this lookup */
3485
3486 return namespaceId;
3487}
#define ACL_USAGE
Definition parsenodes.h:84

References ACL_USAGE, aclcheck_error(), ACLCHECK_OK, fb(), 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 3427 of file namespace.c.

3428{
3429 /* check for pg_temp alias */
3430 if (strcmp(nspname, "pg_temp") == 0)
3431 {
3433 {
3435 return myTempNamespace;
3436 }
3437
3438 /*
3439 * Since this is used only for looking up existing objects, there is
3440 * no point in trying to initialize the temp namespace here; and doing
3441 * so might create problems for some callers. Just report "not found".
3442 */
3443 return InvalidOid;
3444 }
3445
3446 return get_namespace_oid(nspname, true);
3447}

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

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

◆ makeRangeVarFromNameList()

RangeVar * makeRangeVarFromNameList ( const List names)

Definition at line 3626 of file namespace.c.

3627{
3628 RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3629
3630 switch (list_length(names))
3631 {
3632 case 1:
3633 rel->relname = strVal(linitial(names));
3634 break;
3635 case 2:
3636 rel->schemaname = strVal(linitial(names));
3637 rel->relname = strVal(lsecond(names));
3638 break;
3639 case 3:
3640 rel->catalogname = strVal(linitial(names));
3641 rel->schemaname = strVal(lsecond(names));
3642 rel->relname = strVal(lthird(names));
3643 break;
3644 default:
3645 ereport(ERROR,
3647 errmsg("improper relation name (too many dotted names): %s",
3648 NameListToString(names))));
3649 break;
3650 }
3651
3652 return rel;
3653}
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition makefuncs.c:473
char * relname
Definition primnodes.h:84
char * catalogname
Definition primnodes.h:78
char * schemaname
Definition primnodes.h:81

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

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

◆ MatchNamedCall()

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

Definition at line 1618 of file namespace.c.

1621{
1623 int numposargs = nargs - list_length(argnames);
1624 int pronallargs;
1625 Oid *p_argtypes;
1626 char **p_argnames;
1627 char *p_argmodes;
1628 bool arggiven[FUNC_MAX_ARGS];
1629 bool arg_filled_twice = false;
1630 bool isnull;
1631 int ap; /* call args position */
1632 int pp; /* proargs position */
1633 ListCell *lc;
1634
1635 Assert(argnames != NIL);
1636 Assert(numposargs >= 0);
1637 Assert(nargs <= pronargs);
1638
1639 /* Ignore this function if its proargnames is null */
1641 &isnull);
1642 if (isnull)
1643 return false;
1644
1645 /* OK, let's extract the argument names and types */
1649
1651
1652 /* initialize state for matching */
1653 *argnumbers = (int *) palloc(pronargs * sizeof(int));
1654 memset(arggiven, false, pronargs * sizeof(bool));
1655
1656 /* there are numposargs positional args before the named args */
1657 for (ap = 0; ap < numposargs; ap++)
1658 {
1659 (*argnumbers)[ap] = ap;
1660 arggiven[ap] = true;
1661 }
1662
1663 /* now examine the named args */
1664 foreach(lc, argnames)
1665 {
1666 char *argname = (char *) lfirst(lc);
1667 bool found;
1668 int i;
1669
1670 pp = 0;
1671 found = false;
1672 for (i = 0; i < pronallargs; i++)
1673 {
1674 /* consider only input params, except with include_out_arguments */
1675 if (!include_out_arguments &&
1676 p_argmodes &&
1677 (p_argmodes[i] != FUNC_PARAM_IN &&
1680 continue;
1681 if (p_argnames[i] && strcmp(p_argnames[i], argname) == 0)
1682 {
1683 /* note if argname matches a positional argument */
1684 if (arggiven[pp])
1685 arg_filled_twice = true;
1686 arggiven[pp] = true;
1687 (*argnumbers)[ap] = pp;
1688 found = true;
1689 break;
1690 }
1691 /* increase pp only for considered parameters */
1692 pp++;
1693 }
1694 /* if name isn't in proargnames, fail */
1695 if (!found)
1696 return false;
1697 ap++;
1698 }
1699
1700 Assert(ap == nargs); /* processed all actual parameters */
1701
1702 /* If we get here, the function did match all the supplied argnames */
1704
1705 /* ... however, some of them might have been placed wrong */
1706 if (arg_filled_twice)
1707 return false; /* some argname matched a positional argument */
1708
1709 /* If we get here, the call doesn't have invalid mixed notation */
1711
1712 /* Check for default arguments */
1713 if (nargs < pronargs)
1714 {
1715 int first_arg_with_default = pronargs - procform->pronargdefaults;
1716
1717 for (pp = numposargs; pp < pronargs; pp++)
1718 {
1719 if (arggiven[pp])
1720 continue;
1721 /* fail if arg not given and no default available */
1723 return false;
1724 (*argnumbers)[ap++] = pp;
1725 }
1726 }
1727
1728 Assert(ap == pronargs); /* processed all function parameters */
1729
1730 /* If we get here, the call supplies all the required arguments */
1732
1733 return true;
1734}
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition funcapi.c:1379
#define FGC_ARGNAMES_ALL
Definition namespace.h:55
#define FGC_ARGNAMES_MATCH
Definition namespace.h:53
#define FGC_ARGNAMES_NONDUP
Definition namespace.h:54
@ FUNC_PARAM_IN
@ FUNC_PARAM_INOUT
@ FUNC_PARAM_VARIADIC
#define FUNC_MAX_ARGS
#define lfirst(lc)
Definition pg_list.h:172

References Assert, fb(), FGC_ARGNAMES_ALL, FGC_ARGNAMES_MATCH, FGC_ARGNAMES_NONDUP, Form_pg_proc, FUNC_MAX_ARGS, FUNC_PARAM_IN, FUNC_PARAM_INOUT, FUNC_PARAM_VARIADIC, get_func_arg_info(), GETSTRUCT(), i, lfirst, list_length(), NIL, palloc(), pronargs, and SysCacheGetAttr().

Referenced by FuncnameGetCandidates().

◆ NameListToQuotedString()

char * NameListToQuotedString ( const List names)

Definition at line 3700 of file namespace.c.

3701{
3703 ListCell *l;
3704
3705 initStringInfo(&string);
3706
3707 foreach(l, names)
3708 {
3709 if (l != list_head(names))
3710 appendStringInfoChar(&string, '.');
3712 }
3713
3714 return string.data;
3715}
static ListCell * list_head(const List *l)
Definition pg_list.h:128
char string[11]
const char * quote_identifier(const char *ident)
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242
void initStringInfo(StringInfo str)
Definition stringinfo.c:97

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

◆ NameListToString()

char * NameListToString ( const List names)

Definition at line 3666 of file namespace.c.

3667{
3669 ListCell *l;
3670
3671 initStringInfo(&string);
3672
3673 foreach(l, names)
3674 {
3675 Node *name = (Node *) lfirst(l);
3676
3677 if (l != list_head(names))
3678 appendStringInfoChar(&string, '.');
3679
3680 if (IsA(name, String))
3682 else if (IsA(name, A_Star))
3683 appendStringInfoChar(&string, '*');
3684 else
3685 elog(ERROR, "unexpected node type in name list: %d",
3686 (int) nodeTag(name));
3687 }
3688
3689 return string.data;
3690}
#define IsA(nodeptr, _type_)
Definition nodes.h:164
#define nodeTag(nodeptr)
Definition nodes.h:139
Definition nodes.h:135
Definition value.h:64
const char * name

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

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

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 2223 of file namespace.c.

2224{
2226}
static bool OpclassIsVisibleExt(Oid opcid, bool *is_missing)
Definition namespace.c:2235

References fb(), and OpclassIsVisibleExt().

Referenced by get_opclass_name(), and getObjectDescription().

◆ OpclassIsVisibleExt()

static bool OpclassIsVisibleExt ( Oid  opcid,
bool is_missing 
)
static

Definition at line 2235 of file namespace.c.

2236{
2240 bool visible;
2241
2244 {
2245 if (is_missing != NULL)
2246 {
2247 *is_missing = true;
2248 return false;
2249 }
2250 elog(ERROR, "cache lookup failed for opclass %u", opcid);
2251 }
2253
2255
2256 /*
2257 * Quick check: if it ain't in the path at all, it ain't visible. Items in
2258 * the system namespace are surely in the path and so we needn't even do
2259 * list_member_oid() for them.
2260 */
2261 opcnamespace = opcform->opcnamespace;
2264 visible = false;
2265 else
2266 {
2267 /*
2268 * If it is in the path, it might still not be visible; it could be
2269 * hidden by another opclass of the same name earlier in the path. So
2270 * we must do a slow check to see if this opclass would be found by
2271 * OpclassnameGetOpcid.
2272 */
2273 char *opcname = NameStr(opcform->opcname);
2274
2275 visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
2276 }
2277
2279
2280 return visible;
2281}
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
Definition namespace.c:2190
END_CATALOG_STRUCT typedef FormData_pg_opclass * Form_pg_opclass
Definition pg_opclass.h:87

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

Referenced by OpclassIsVisible(), and pg_opclass_is_visible().

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char opcname 
)

Definition at line 2190 of file namespace.c.

2191{
2192 Oid opcid;
2193 ListCell *l;
2194
2196
2197 foreach(l, activeSearchPath)
2198 {
2200
2202 continue; /* do not look in temp namespace */
2203
2208 if (OidIsValid(opcid))
2209 return opcid;
2210 }
2211
2212 /* Not found in path */
2213 return InvalidOid;
2214}

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

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

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 2118 of file namespace.c.

2119{
2121}
static bool OperatorIsVisibleExt(Oid oprid, bool *is_missing)
Definition namespace.c:2130
Oid oprid(Operator op)
Definition parse_oper.c:240

References fb(), OperatorIsVisibleExt(), and oprid().

Referenced by format_operator_extended().

◆ OperatorIsVisibleExt()

static bool OperatorIsVisibleExt ( Oid  oprid,
bool is_missing 
)
static

Definition at line 2130 of file namespace.c.

2131{
2135 bool visible;
2136
2139 {
2140 if (is_missing != NULL)
2141 {
2142 *is_missing = true;
2143 return false;
2144 }
2145 elog(ERROR, "cache lookup failed for operator %u", oprid);
2146 }
2148
2150
2151 /*
2152 * Quick check: if it ain't in the path at all, it ain't visible. Items in
2153 * the system namespace are surely in the path and so we needn't even do
2154 * list_member_oid() for them.
2155 */
2156 oprnamespace = oprform->oprnamespace;
2159 visible = false;
2160 else
2161 {
2162 /*
2163 * If it is in the path, it might still not be visible; it could be
2164 * hidden by another operator of the same name and arguments earlier
2165 * in the path. So we must do a slow check to see if this is the same
2166 * operator that would be found by OpernameGetOprid.
2167 */
2168 char *oprname = NameStr(oprform->oprname);
2169
2170 visible = (OpernameGetOprid(list_make1(makeString(oprname)),
2171 oprform->oprleft, oprform->oprright)
2172 == oprid);
2173 }
2174
2176
2177 return visible;
2178}
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition namespace.c:1834
END_CATALOG_STRUCT typedef FormData_pg_operator * Form_pg_operator
Definition pg_operator.h:87

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

Referenced by OperatorIsVisible(), and pg_operator_is_visible().

◆ OpernameGetCandidates()

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

Definition at line 1947 of file namespace.c.

1949{
1951 char *resultSpace = NULL;
1952 int nextResult = 0;
1953 char *schemaname;
1954 char *opername;
1957 int i;
1958
1959 /* initialize output fgc_flags to empty */
1960 *fgc_flags = 0;
1961
1962 /* deconstruct the name list */
1963 DeconstructQualifiedName(names, &schemaname, &opername);
1964
1965 if (schemaname)
1966 {
1967 /* use exact schema given */
1968 *fgc_flags |= FGC_SCHEMA_GIVEN; /* report that a schema is given */
1970 if (!OidIsValid(namespaceId))
1971 return NULL;
1972 *fgc_flags |= FGC_SCHEMA_EXISTS; /* report that the schema exists */
1973 }
1974 else
1975 {
1976 /* flag to indicate we need namespace search */
1979 }
1980
1981 /* Search syscache by name only */
1983
1984 /*
1985 * In typical scenarios, most if not all of the operators found by the
1986 * catcache search will end up getting returned; and there can be quite a
1987 * few, for common operator names such as '=' or '+'. To reduce the time
1988 * spent in palloc, we allocate the result space as an array large enough
1989 * to hold all the operators. The original coding of this routine did a
1990 * separate palloc for each operator, but profiling revealed that the
1991 * pallocs used an unreasonably large fraction of parsing time.
1992 */
1993#define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
1994 2 * sizeof(Oid))
1995
1996 if (catlist->n_members > 0)
1997 resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
1998
1999 for (i = 0; i < catlist->n_members; i++)
2000 {
2001 HeapTuple opertup = &catlist->members[i]->tuple;
2003 int pathpos = 0;
2005
2006 /* Ignore operators of wrong kind, if specific kind requested */
2007 if (oprkind && operform->oprkind != oprkind)
2008 continue;
2009
2010 *fgc_flags |= FGC_NAME_EXISTS; /* the name is present in pg_operator */
2011
2013 {
2014 /* Consider only opers in specified namespace */
2015 if (operform->oprnamespace != namespaceId)
2016 continue;
2017 /* No need to check args, they must all be different */
2018 }
2019 else
2020 {
2021 /*
2022 * Consider only opers that are in the search path and are not in
2023 * the temp namespace.
2024 */
2025 ListCell *nsp;
2026
2027 foreach(nsp, activeSearchPath)
2028 {
2029 if (operform->oprnamespace == lfirst_oid(nsp) &&
2030 operform->oprnamespace != myTempNamespace)
2031 break;
2032 pathpos++;
2033 }
2034 if (nsp == NULL)
2035 continue; /* oper is not in search path */
2036
2037 /*
2038 * Okay, it's in the search path, but does it have the same
2039 * arguments as something we already accepted? If so, keep only
2040 * the one that appears earlier in the search path.
2041 *
2042 * If we have an ordered list from SearchSysCacheList (the normal
2043 * case), then any conflicting oper must immediately adjoin this
2044 * one in the list, so we only need to look at the newest result
2045 * item. If we have an unordered list, we have to scan the whole
2046 * result list.
2047 */
2048 if (resultList)
2049 {
2051
2052 if (catlist->ordered)
2053 {
2054 if (operform->oprleft == resultList->args[0] &&
2055 operform->oprright == resultList->args[1])
2057 else
2058 prevResult = NULL;
2059 }
2060 else
2061 {
2062 for (prevResult = resultList;
2063 prevResult;
2064 prevResult = prevResult->next)
2065 {
2066 if (operform->oprleft == prevResult->args[0] &&
2067 operform->oprright == prevResult->args[1])
2068 break;
2069 }
2070 }
2071 if (prevResult)
2072 {
2073 /* We have a match with a previous result */
2074 Assert(pathpos != prevResult->pathpos);
2075 if (pathpos > prevResult->pathpos)
2076 continue; /* keep previous result */
2077 /* replace previous result */
2078 prevResult->pathpos = pathpos;
2079 prevResult->oid = operform->oid;
2080 continue; /* args are same, of course */
2081 }
2082 }
2083 }
2084
2085 *fgc_flags |= FGC_NAME_VISIBLE; /* operator is in the right schema */
2086
2087 /*
2088 * Okay to add it to result list
2089 */
2092
2093 newResult->pathpos = pathpos;
2094 newResult->oid = operform->oid;
2095 newResult->nominalnargs = 2;
2096 newResult->nargs = 2;
2097 newResult->nvargs = 0;
2098 newResult->ndargs = 0;
2099 newResult->argnumbers = NULL;
2100 newResult->args[0] = operform->oprleft;
2101 newResult->args[1] = operform->oprright;
2102 newResult->next = resultList;
2104 }
2105
2107
2108 return resultList;
2109}
#define SPACE_PER_OP

References activeSearchPath, Assert, CStringGetDatum(), DeconstructQualifiedName(), fb(), FGC_NAME_EXISTS, FGC_NAME_VISIBLE, FGC_SCHEMA_EXISTS, FGC_SCHEMA_GIVEN, Form_pg_operator, GETSTRUCT(), i, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, OidIsValid, palloc(), recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, and SPACE_PER_OP.

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

◆ OpernameGetOprid()

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

Definition at line 1834 of file namespace.c.

1835{
1836 char *schemaname;
1837 char *opername;
1839 ListCell *l;
1840
1841 /* deconstruct the name list */
1842 DeconstructQualifiedName(names, &schemaname, &opername);
1843
1844 if (schemaname)
1845 {
1846 /* search only in exact schema given */
1848
1849 namespaceId = LookupExplicitNamespace(schemaname, true);
1851 {
1853
1855 CStringGetDatum(opername),
1856 ObjectIdGetDatum(oprleft),
1857 ObjectIdGetDatum(oprright),
1860 {
1862 Oid result = operclass->oid;
1863
1865 return result;
1866 }
1867 }
1868
1869 return InvalidOid;
1870 }
1871
1872 /* Search syscache by name and argument types */
1874 CStringGetDatum(opername),
1875 ObjectIdGetDatum(oprleft),
1876 ObjectIdGetDatum(oprright));
1877
1878 if (catlist->n_members == 0)
1879 {
1880 /* no hope, fall out early */
1882 return InvalidOid;
1883 }
1884
1885 /*
1886 * We have to find the list member that is first in the search path, if
1887 * there's more than one. This doubly-nested loop looks ugly, but in
1888 * practice there should usually be few catlist members.
1889 */
1891
1892 foreach(l, activeSearchPath)
1893 {
1895 int i;
1896
1898 continue; /* do not look in temp namespace */
1899
1900 for (i = 0; i < catlist->n_members; i++)
1901 {
1902 HeapTuple opertup = &catlist->members[i]->tuple;
1904
1905 if (operform->oprnamespace == namespaceId)
1906 {
1907 Oid result = operform->oid;
1908
1910 return result;
1911 }
1912 }
1913 }
1914
1916 return InvalidOid;
1917}
HeapTuple SearchSysCache4(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition syscache.c:250
#define SearchSysCacheList3(cacheId, key1, key2, key3)
Definition syscache.h:131

References activeSearchPath, CStringGetDatum(), DeconstructQualifiedName(), fb(), Form_pg_operator, GETSTRUCT(), HeapTupleIsValid, i, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, ObjectIdGetDatum(), OidIsValid, recomputeNamespacePath(), ReleaseSysCache(), ReleaseSysCacheList, SearchSysCache4(), and SearchSysCacheList3.

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

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 2325 of file namespace.c.

2326{
2328}
static bool OpfamilyIsVisibleExt(Oid opfid, bool *is_missing)
Definition namespace.c:2337

References fb(), and OpfamilyIsVisibleExt().

Referenced by getOpFamilyDescription().

◆ OpfamilyIsVisibleExt()

static bool OpfamilyIsVisibleExt ( Oid  opfid,
bool is_missing 
)
static

Definition at line 2337 of file namespace.c.

2338{
2342 bool visible;
2343
2346 {
2347 if (is_missing != NULL)
2348 {
2349 *is_missing = true;
2350 return false;
2351 }
2352 elog(ERROR, "cache lookup failed for opfamily %u", opfid);
2353 }
2355
2357
2358 /*
2359 * Quick check: if it ain't in the path at all, it ain't visible. Items in
2360 * the system namespace are surely in the path and so we needn't even do
2361 * list_member_oid() for them.
2362 */
2363 opfnamespace = opfform->opfnamespace;
2366 visible = false;
2367 else
2368 {
2369 /*
2370 * If it is in the path, it might still not be visible; it could be
2371 * hidden by another opfamily of the same name earlier in the path. So
2372 * we must do a slow check to see if this opfamily would be found by
2373 * OpfamilynameGetOpfid.
2374 */
2375 char *opfname = NameStr(opfform->opfname);
2376
2377 visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
2378 }
2379
2381
2382 return visible;
2383}
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
Definition namespace.c:2292
END_CATALOG_STRUCT typedef FormData_pg_opfamily * Form_pg_opfamily
Definition pg_opfamily.h:55

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

Referenced by OpfamilyIsVisible(), and pg_opfamily_is_visible().

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char opfname 
)

Definition at line 2292 of file namespace.c.

2293{
2294 Oid opfid;
2295 ListCell *l;
2296
2298
2299 foreach(l, activeSearchPath)
2300 {
2302
2304 continue; /* do not look in temp namespace */
2305
2310 if (OidIsValid(opfid))
2311 return opfid;
2312 }
2313
2314 /* Not found in path */
2315 return InvalidOid;
2316}

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisibleExt().

◆ pg_collation_is_visible()

Datum pg_collation_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 5050 of file namespace.c.

5051{
5052 Oid oid = PG_GETARG_OID(0);
5053 bool result;
5054 bool is_missing = false;
5055
5056 result = CollationIsVisibleExt(oid, &is_missing);
5057
5058 if (is_missing)
5060 PG_RETURN_BOOL(result);
5061}
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360

References CollationIsVisibleExt(), fb(), PG_GETARG_OID, PG_RETURN_BOOL, and PG_RETURN_NULL.

◆ pg_conversion_is_visible()

Datum pg_conversion_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 5064 of file namespace.c.

5065{
5066 Oid oid = PG_GETARG_OID(0);
5067 bool result;
5068 bool is_missing = false;
5069
5070 result = ConversionIsVisibleExt(oid, &is_missing);
5071
5072 if (is_missing)
5074 PG_RETURN_BOOL(result);
5075}

References ConversionIsVisibleExt(), fb(), PG_GETARG_OID, PG_RETURN_BOOL, and PG_RETURN_NULL.

◆ pg_function_is_visible()

Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4994 of file namespace.c.

4995{
4996 Oid oid = PG_GETARG_OID(0);
4997 bool result;
4998 bool is_missing = false;
4999
5000 result = FunctionIsVisibleExt(oid, &is_missing);
5001
5002 if (is_missing)
5004 PG_RETURN_BOOL(result);
5005}

References fb(), FunctionIsVisibleExt(), PG_GETARG_OID, PG_RETURN_BOOL, and PG_RETURN_NULL.

◆ pg_is_other_temp_schema()

Datum pg_is_other_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 5154 of file namespace.c.

5155{
5156 Oid oid = PG_GETARG_OID(0);
5157
5159}
bool isOtherTempNamespace(Oid namespaceId)
Definition namespace.c:3782

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

◆ pg_my_temp_schema()

Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 5148 of file namespace.c.

5149{
5151}
#define PG_RETURN_OID(x)
Definition fmgr.h:361

References myTempNamespace, and PG_RETURN_OID.

◆ pg_opclass_is_visible()

Datum pg_opclass_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 5022 of file namespace.c.

5023{
5024 Oid oid = PG_GETARG_OID(0);
5025 bool result;
5026 bool is_missing = false;
5027
5028 result = OpclassIsVisibleExt(oid, &is_missing);
5029
5030 if (is_missing)
5032 PG_RETURN_BOOL(result);
5033}

References fb(), OpclassIsVisibleExt(), PG_GETARG_OID, PG_RETURN_BOOL, and PG_RETURN_NULL.

◆ pg_operator_is_visible()

Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 5008 of file namespace.c.

5009{
5010 Oid oid = PG_GETARG_OID(0);
5011 bool result;
5012 bool is_missing = false;
5013
5014 result = OperatorIsVisibleExt(oid, &is_missing);
5015
5016 if (is_missing)
5018 PG_RETURN_BOOL(result);
5019}

References fb(), OperatorIsVisibleExt(), PG_GETARG_OID, PG_RETURN_BOOL, and PG_RETURN_NULL.

◆ pg_opfamily_is_visible()

Datum pg_opfamily_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 5036 of file namespace.c.

5037{
5038 Oid oid = PG_GETARG_OID(0);
5039 bool result;
5040 bool is_missing = false;
5041
5042 result = OpfamilyIsVisibleExt(oid, &is_missing);
5043
5044 if (is_missing)
5046 PG_RETURN_BOOL(result);
5047}

References fb(), OpfamilyIsVisibleExt(), PG_GETARG_OID, PG_RETURN_BOOL, and PG_RETURN_NULL.

◆ pg_statistics_obj_is_visible()

Datum pg_statistics_obj_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 5078 of file namespace.c.

5079{
5080 Oid oid = PG_GETARG_OID(0);
5081 bool result;
5082 bool is_missing = false;
5083
5084 result = StatisticsObjIsVisibleExt(oid, &is_missing);
5085
5086 if (is_missing)
5088 PG_RETURN_BOOL(result);
5089}
static bool StatisticsObjIsVisibleExt(Oid stxid, bool *is_missing)
Definition namespace.c:2713

References fb(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and StatisticsObjIsVisibleExt().

◆ pg_table_is_visible()

Datum pg_table_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4966 of file namespace.c.

4967{
4968 Oid oid = PG_GETARG_OID(0);
4969 bool result;
4970 bool is_missing = false;
4971
4972 result = RelationIsVisibleExt(oid, &is_missing);
4973
4974 if (is_missing)
4976 PG_RETURN_BOOL(result);
4977}
static bool RelationIsVisibleExt(Oid relid, bool *is_missing)
Definition namespace.c:926

References fb(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and RelationIsVisibleExt().

◆ pg_ts_config_is_visible()

Datum pg_ts_config_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 5134 of file namespace.c.

5135{
5136 Oid oid = PG_GETARG_OID(0);
5137 bool result;
5138 bool is_missing = false;
5139
5140 result = TSConfigIsVisibleExt(oid, &is_missing);
5141
5142 if (is_missing)
5144 PG_RETURN_BOOL(result);
5145}
static bool TSConfigIsVisibleExt(Oid cfgid, bool *is_missing)
Definition namespace.c:3294

References fb(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and TSConfigIsVisibleExt().

◆ pg_ts_dict_is_visible()

Datum pg_ts_dict_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 5106 of file namespace.c.

5107{
5108 Oid oid = PG_GETARG_OID(0);
5109 bool result;
5110 bool is_missing = false;
5111
5112 result = TSDictionaryIsVisibleExt(oid, &is_missing);
5113
5114 if (is_missing)
5116 PG_RETURN_BOOL(result);
5117}
static bool TSDictionaryIsVisibleExt(Oid dictId, bool *is_missing)
Definition namespace.c:3003

References fb(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and TSDictionaryIsVisibleExt().

◆ pg_ts_parser_is_visible()

Datum pg_ts_parser_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 5092 of file namespace.c.

5093{
5094 Oid oid = PG_GETARG_OID(0);
5095 bool result;
5096 bool is_missing = false;
5097
5098 result = TSParserIsVisibleExt(oid, &is_missing);
5099
5100 if (is_missing)
5102 PG_RETURN_BOOL(result);
5103}
static bool TSParserIsVisibleExt(Oid prsId, bool *is_missing)
Definition namespace.c:2858

References fb(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and TSParserIsVisibleExt().

◆ pg_ts_template_is_visible()

Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 5120 of file namespace.c.

5121{
5122 Oid oid = PG_GETARG_OID(0);
5123 bool result;
5124 bool is_missing = false;
5125
5126 result = TSTemplateIsVisibleExt(oid, &is_missing);
5127
5128 if (is_missing)
5130 PG_RETURN_BOOL(result);
5131}
static bool TSTemplateIsVisibleExt(Oid tmplId, bool *is_missing)
Definition namespace.c:3149

References fb(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and TSTemplateIsVisibleExt().

◆ pg_type_is_visible()

Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4980 of file namespace.c.

4981{
4982 Oid oid = PG_GETARG_OID(0);
4983 bool result;
4984 bool is_missing = false;
4985
4986 result = TypeIsVisibleExt(oid, &is_missing);
4987
4988 if (is_missing)
4990 PG_RETURN_BOOL(result);
4991}
static bool TypeIsVisibleExt(Oid typid, bool *is_missing)
Definition namespace.c:1053

References fb(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and TypeIsVisibleExt().

◆ preprocessNamespacePath()

static List * preprocessNamespacePath ( const char searchPath,
Oid  roleid,
bool temp_missing 
)
static

Definition at line 4179 of file namespace.c.

4181{
4182 char *rawname;
4183 List *namelist;
4184 List *oidlist;
4185 ListCell *l;
4186
4187 /* Need a modifiable copy */
4188 rawname = pstrdup(searchPath);
4189
4190 /* Parse string into list of identifiers */
4192 {
4193 /* syntax error in name list */
4194 /* this should not happen if GUC checked check_search_path */
4195 elog(ERROR, "invalid list syntax");
4196 }
4197
4198 /*
4199 * Convert the list of names to a list of OIDs. If any names are not
4200 * recognizable or we don't have read access, just leave them out of the
4201 * list. (We can't raise an error, since the search_path setting has
4202 * already been accepted.) Don't make duplicate entries, either.
4203 */
4204 oidlist = NIL;
4205 *temp_missing = false;
4206 foreach(l, namelist)
4207 {
4208 char *curname = (char *) lfirst(l);
4210
4211 if (strcmp(curname, "$user") == 0)
4212 {
4213 /* $user --- substitute namespace matching user name, if any */
4214 HeapTuple tuple;
4215
4216 tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4217 if (HeapTupleIsValid(tuple))
4218 {
4219 char *rname;
4220
4223 ReleaseSysCache(tuple);
4224 if (OidIsValid(namespaceId) &&
4227 oidlist = lappend_oid(oidlist, namespaceId);
4228 }
4229 }
4230 else if (strcmp(curname, "pg_temp") == 0)
4231 {
4232 /* pg_temp --- substitute temp namespace, if any */
4234 oidlist = lappend_oid(oidlist, myTempNamespace);
4235 else
4236 {
4237 /* If it ought to be the creation namespace, set flag */
4238 if (oidlist == NIL)
4239 *temp_missing = true;
4240 }
4241 }
4242 else
4243 {
4244 /* normal namespace reference */
4246 if (OidIsValid(namespaceId) &&
4249 oidlist = lappend_oid(oidlist, namespaceId);
4250 }
4251 }
4252
4253 pfree(rawname);
4255
4256 return oidlist;
4257}
NameData rolname
Definition pg_authid.h:36
END_CATALOG_STRUCT typedef FormData_pg_authid * Form_pg_authid
Definition pg_authid.h:60

References ACL_USAGE, ACLCHECK_OK, elog, ERROR, fb(), Form_pg_authid, get_namespace_oid(), GETSTRUCT(), HeapTupleIsValid, lappend_oid(), lfirst, list_free(), myTempNamespace, NameStr, NIL, object_aclcheck(), ObjectIdGetDatum(), OidIsValid, pfree(), pstrdup(), ReleaseSysCache(), rolname, SearchSysCache1(), and SplitIdentifierString().

Referenced by cachedNamespacePath().

◆ QualifiedNameGetCreationNamespace()

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

Definition at line 3559 of file namespace.c.

3560{
3561 char *schemaname;
3563
3564 /* deconstruct the name list */
3565 DeconstructQualifiedName(names, &schemaname, objname_p);
3566
3567 if (schemaname)
3568 {
3569 /* check for pg_temp alias */
3570 if (strcmp(schemaname, "pg_temp") == 0)
3571 {
3572 /* Initialize temp namespace */
3574 return myTempNamespace;
3575 }
3576 /* use exact schema given */
3577 namespaceId = get_namespace_oid(schemaname, false);
3578 /* we do not check for USAGE rights here! */
3579 }
3580 else
3581 {
3582 /* use the default creation namespace */
3585 {
3586 /* Need to initialize temp namespace */
3588 return myTempNamespace;
3589 }
3591 if (!OidIsValid(namespaceId))
3592 ereport(ERROR,
3594 errmsg("no schema has been selected to create in")));
3595 }
3596
3597 return namespaceId;
3598}

References AccessTempTableNamespace(), activeCreationNamespace, activeTempCreationPending, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, fb(), 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 847 of file namespace.c.

848{
849 switch (newRelation->relpersistence)
850 {
853 {
857 errmsg("cannot create relations in temporary schemas of other sessions")));
858 else
861 errmsg("cannot create temporary relation in non-temporary schema")));
862 }
863 break;
866 newRelation->relpersistence = RELPERSISTENCE_TEMP;
867 else if (isAnyTempNamespace(nspid))
870 errmsg("cannot create relations in temporary schemas of other sessions")));
871 break;
872 default:
876 errmsg("only temporary relations may be created in temporary schemas")));
877 }
878}
int nspid

References ereport, errcode(), errmsg(), ERROR, fb(), isAnyTempNamespace(), isTempOrTempToastNamespace(), and nspid.

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 740 of file namespace.c.

743{
745 Oid relid;
747 Oid nspid;
749 bool retry = false;
750
751 /*
752 * We check the catalog name and then ignore it.
753 */
754 if (relation->catalogname)
755 {
756 if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
759 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
760 relation->catalogname, relation->schemaname,
761 relation->relname)));
762 }
763
764 /*
765 * As in RangeVarGetRelidExtended(), we guard against concurrent DDL
766 * operations by tracking whether any invalidation messages are processed
767 * while we're doing the name lookups and acquiring locks. See comments
768 * in that function for a more detailed explanation of this logic.
769 */
770 for (;;)
771 {
773
775
776 /* Look up creation namespace and check for existing relation. */
780 relid = get_relname_relid(relation->relname, nspid);
781 else
782 relid = InvalidOid;
783
784 /*
785 * In bootstrap processing mode, we don't bother with permissions or
786 * locking. Permissions might not be working yet, and locking is
787 * unnecessary.
788 */
790 break;
791
792 /* Check namespace permissions. */
794 if (aclresult != ACLCHECK_OK)
797
798 if (retry)
799 {
800 /* If nothing changed, we're done. */
801 if (relid == oldrelid && nspid == oldnspid)
802 break;
803 /* If creation namespace has changed, give up old lock. */
804 if (nspid != oldnspid)
807 /* If name points to something different, give up old lock. */
808 if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock)
809 UnlockRelationOid(oldrelid, lockmode);
810 }
811
812 /* Lock namespace. */
813 if (nspid != oldnspid)
815
816 /* Lock relation, if required if and we have permission. */
817 if (lockmode != NoLock && OidIsValid(relid))
818 {
821 relation->relname);
822 if (relid != oldrelid)
823 LockRelationOid(relid, lockmode);
824 }
825
826 /* If no invalidation message were processed, we're done! */
828 break;
829
830 /* Something may have changed, so recheck our work. */
831 retry = true;
832 oldrelid = relid;
833 oldnspid = nspid;
834 }
835
838 *existing_relation_id = relid;
839 return nspid;
840}
@ ACLCHECK_NOT_OWNER
Definition acl.h:185
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition aclchk.c:4108
uint64_t uint64
Definition c.h:559
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition lmgr.c:229
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition lmgr.c:1008
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition lmgr.c:107
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition lmgr.c:1068
#define NoLock
Definition lockdefs.h:34
#define AccessShareLock
Definition lockdefs.h:36
char get_rel_relkind(Oid relid)
Definition lsyscache.c:2153
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition lsyscache.c:2035
void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
Definition namespace.c:847
Oid RangeVarGetCreationNamespace(const RangeVar *newRelation)
Definition namespace.c:655
ObjectType get_relkind_objtype(char relkind)
uint64 SharedInvalidMessageCounter
Definition sinval.c:24

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 655 of file namespace.c.

656{
658
659 /*
660 * We check the catalog name and then ignore it.
661 */
662 if (newRelation->catalogname)
663 {
664 if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
667 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
668 newRelation->catalogname, newRelation->schemaname,
669 newRelation->relname)));
670 }
671
672 if (newRelation->schemaname)
673 {
674 /* check for pg_temp alias */
675 if (strcmp(newRelation->schemaname, "pg_temp") == 0)
676 {
677 /* Initialize temp namespace */
679 return myTempNamespace;
680 }
681 /* use exact schema given */
682 namespaceId = get_namespace_oid(newRelation->schemaname, false);
683 /* we do not check for USAGE rights here! */
684 }
685 else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
686 {
687 /* Initialize temp namespace */
689 return myTempNamespace;
690 }
691 else
692 {
693 /* use the default creation namespace */
696 {
697 /* Need to initialize temp namespace */
699 return myTempNamespace;
700 }
705 errmsg("no schema has been selected to create in")));
706 }
707
708 /* Note: callers will check for CREATE rights when appropriate */
709
710 return namespaceId;
711}

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

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

◆ RangeVarGetRelidExtended()

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

Definition at line 442 of file namespace.c.

445{
447 Oid relId;
449 bool retry = false;
450 bool missing_ok = (flags & RVR_MISSING_OK) != 0;
451
452 /* verify that flags do no conflict */
453 Assert(!((flags & RVR_NOWAIT) && (flags & RVR_SKIP_LOCKED)));
454
455 /*
456 * We check the catalog name and then ignore it.
457 */
458 if (relation->catalogname)
459 {
460 if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
463 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
464 relation->catalogname, relation->schemaname,
465 relation->relname)));
466 }
467
468 /*
469 * DDL operations can change the results of a name lookup. Since all such
470 * operations will generate invalidation messages, we keep track of
471 * whether any such messages show up while we're performing the operation,
472 * and retry until either (1) no more invalidation messages show up or (2)
473 * the answer doesn't change.
474 *
475 * But if lockmode = NoLock, then we assume that either the caller is OK
476 * with the answer changing under them, or that they already hold some
477 * appropriate lock, and therefore return the first answer we get without
478 * checking for invalidation messages. Also, if the requested lock is
479 * already held, LockRelationOid will not AcceptInvalidationMessages, so
480 * we may fail to notice a change. We could protect against that case by
481 * calling AcceptInvalidationMessages() before beginning this loop, but
482 * that would add a significant amount overhead, so for now we don't.
483 */
484 for (;;)
485 {
486 /*
487 * Remember this value, so that, after looking up the relation name
488 * and locking its OID, we can check whether any invalidation messages
489 * have been processed that might require a do-over.
490 */
492
493 /*
494 * Some non-default relpersistence value may have been specified. The
495 * parser never generates such a RangeVar in simple DML, but it can
496 * happen in contexts such as "CREATE TEMP TABLE foo (f1 int PRIMARY
497 * KEY)". Such a command will generate an added CREATE INDEX
498 * operation, which must be careful to find the temp table, even when
499 * pg_temp is not first in the search path.
500 */
501 if (relation->relpersistence == RELPERSISTENCE_TEMP)
502 {
504 relId = InvalidOid; /* this probably can't happen? */
505 else
506 {
507 if (relation->schemaname)
508 {
510
511 namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
512
513 /*
514 * For missing_ok, allow a non-existent schema name to
515 * return InvalidOid.
516 */
520 errmsg("temporary tables cannot specify a schema name")));
521 }
522
523 relId = get_relname_relid(relation->relname, myTempNamespace);
524 }
525 }
526 else if (relation->schemaname)
527 {
529
530 /* use exact schema given */
531 namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
532 if (missing_ok && !OidIsValid(namespaceId))
533 relId = InvalidOid;
534 else
535 relId = get_relname_relid(relation->relname, namespaceId);
536 }
537 else
538 {
539 /* search the namespace path */
540 relId = RelnameGetRelid(relation->relname);
541 }
542
543 /*
544 * Invoke caller-supplied callback, if any.
545 *
546 * This callback is a good place to check permissions: we haven't
547 * taken the table lock yet (and it's really best to check permissions
548 * before locking anything!), but we've gotten far enough to know what
549 * OID we think we should lock. Of course, concurrent DDL might
550 * change things while we're waiting for the lock, but in that case
551 * the callback will be invoked again for the new OID.
552 */
553 if (callback)
554 callback(relation, relId, oldRelId, callback_arg);
555
556 /*
557 * If no lock requested, we assume the caller knows what they're
558 * doing. They should have already acquired a heavyweight lock on
559 * this relation earlier in the processing of this same statement, so
560 * it wouldn't be appropriate to AcceptInvalidationMessages() here, as
561 * that might pull the rug out from under them.
562 */
563 if (lockmode == NoLock)
564 break;
565
566 /*
567 * If, upon retry, we get back the same OID we did last time, then the
568 * invalidation messages we processed did not change the final answer.
569 * So we're done.
570 *
571 * If we got a different OID, we've locked the relation that used to
572 * have this name rather than the one that does now. So release the
573 * lock.
574 */
575 if (retry)
576 {
577 if (relId == oldRelId)
578 break;
579 if (OidIsValid(oldRelId))
580 UnlockRelationOid(oldRelId, lockmode);
581 }
582
583 /*
584 * Lock relation. This will also accept any pending invalidation
585 * messages. If we got back InvalidOid, indicating not found, then
586 * there's nothing to lock, but we accept invalidation messages
587 * anyway, to flush any negative catcache entries that may be
588 * lingering.
589 */
590 if (!OidIsValid(relId))
592 else if (!(flags & (RVR_NOWAIT | RVR_SKIP_LOCKED)))
593 LockRelationOid(relId, lockmode);
594 else if (!ConditionalLockRelationOid(relId, lockmode))
595 {
596 int elevel = (flags & RVR_SKIP_LOCKED) ? DEBUG1 : ERROR;
597
598 if (relation->schemaname)
599 ereport(elevel,
601 errmsg("could not obtain lock on relation \"%s.%s\"",
602 relation->schemaname, relation->relname)));
603 else
604 ereport(elevel,
606 errmsg("could not obtain lock on relation \"%s\"",
607 relation->relname)));
608
609 return InvalidOid;
610 }
611
612 /*
613 * If no invalidation message were processed, we're done!
614 */
616 break;
617
618 /*
619 * Something may have changed. Let's repeat the name lookup, to make
620 * sure this name still references the same relation it did
621 * previously.
622 */
623 retry = true;
624 oldRelId = relId;
625 }
626
627 if (!OidIsValid(relId))
628 {
629 int elevel = missing_ok ? DEBUG1 : ERROR;
630
631 if (relation->schemaname)
632 ereport(elevel,
634 errmsg("relation \"%s.%s\" does not exist",
635 relation->schemaname, relation->relname)));
636 else
637 ereport(elevel,
639 errmsg("relation \"%s\" does not exist",
640 relation->relname)));
641 }
642 return relId;
643}
#define DEBUG1
Definition elog.h:30
void AcceptInvalidationMessages(void)
Definition inval.c:930
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
Definition lmgr.c:151
Oid RelnameGetRelid(const char *relname)
Definition namespace.c:886
@ RVR_SKIP_LOCKED
Definition namespace.h:92
@ RVR_NOWAIT
Definition namespace.h:91
@ RVR_MISSING_OK
Definition namespace.h:90
#define ERRCODE_UNDEFINED_TABLE
Definition pgbench.c:79
char relpersistence
Definition primnodes.h:90
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)

References AcceptInvalidationMessages(), Assert, callback(), RangeVar::catalogname, ConditionalLockRelationOid(), DEBUG1, ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, fb(), 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(), attribute_statistics_update(), cluster(), CreatePolicy(), ExecRefreshMatView(), ExecuteTruncate(), expand_vacuum_rel(), extended_statistics_update(), get_rel_from_relname(), LockTableCommand(), pg_clear_attribute_stats(), pg_clear_extended_stats(), ProcessUtilitySlow(), ReindexIndex(), ReindexTable(), relation_statistics_update(), RemoveRelations(), rename_policy(), renameatt(), RenameConstraint(), RenameRelation(), RenameRewriteRule(), renametrig(), transformPartitionCmdForMerge(), and transformPartitionCmdForSplit().

◆ recomputeNamespacePath()

static void recomputeNamespacePath ( void  )
static

Definition at line 4371 of file namespace.c.

4372{
4373 Oid roleid = GetUserId();
4374 bool pathChanged;
4375 const SearchPathCacheEntry *entry;
4376
4377 /* Do nothing if path is already valid. */
4378 if (baseSearchPathValid && namespaceUser == roleid)
4379 return;
4380
4382
4383 if (baseCreationNamespace == entry->firstNS &&
4386 {
4387 pathChanged = false;
4388 }
4389 else
4390 {
4392 List *newpath;
4393
4394 pathChanged = true;
4395
4396 /* Must save OID list in permanent storage. */
4398 newpath = list_copy(entry->finalPath);
4400
4401 /* Now safe to assign to state variables. */
4406 }
4407
4408 /* Mark the path valid. */
4409 baseSearchPathValid = true;
4410 namespaceUser = roleid;
4411
4412 /* And make it active. */
4416
4417 /*
4418 * Bump the generation only if something actually changed. (Notice that
4419 * what we compared to was the old state of the base path variables.)
4420 */
4421 if (pathChanged)
4423}
bool equal(const void *a, const void *b)
Definition equalfuncs.c:223
static const SearchPathCacheEntry * cachedNamespacePath(const char *searchPath, Oid roleid)
Definition namespace.c:4316
char * namespace_search_path
Definition namespace.c:211

References activeCreationNamespace, activePathGeneration, activeSearchPath, activeTempCreationPending, baseCreationNamespace, baseSearchPath, baseSearchPathValid, baseTempCreationPending, cachedNamespacePath(), equal(), fb(), SearchPathCacheEntry::finalPath, SearchPathCacheEntry::firstNS, GetUserId(), list_copy(), list_free(), MemoryContextSwitchTo(), namespace_search_path, namespaceUser, SearchPathCacheEntry::temp_missing, and TopMemoryContext.

Referenced by CollationGetCollid(), CollationIsVisibleExt(), ConversionGetConid(), ConversionIsVisibleExt(), fetch_search_path(), fetch_search_path_array(), FindDefaultConversionProc(), FuncnameGetCandidates(), FunctionIsVisibleExt(), get_collation_oid(), get_conversion_oid(), get_statistics_object_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), GetSearchPathMatcher(), OpclassIsVisibleExt(), OpclassnameGetOpcid(), OperatorIsVisibleExt(), OpernameGetCandidates(), OpernameGetOprid(), OpfamilyIsVisibleExt(), OpfamilynameGetOpfid(), QualifiedNameGetCreationNamespace(), RangeVarGetCreationNamespace(), RelationIsVisibleExt(), RelnameGetRelid(), SearchPathMatchesCurrentEnvironment(), StatisticsObjIsVisibleExt(), TSConfigIsVisibleExt(), TSDictionaryIsVisibleExt(), TSParserIsVisibleExt(), TSTemplateIsVisibleExt(), TypeIsVisibleExt(), and TypenameGetTypidExtended().

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 914 of file namespace.c.

915{
916 return RelationIsVisibleExt(relid, NULL);
917}

References fb(), and RelationIsVisibleExt().

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

◆ RelationIsVisibleExt()

static bool RelationIsVisibleExt ( Oid  relid,
bool is_missing 
)
static

Definition at line 926 of file namespace.c.

927{
930 Oid relnamespace;
931 bool visible;
932
935 {
936 if (is_missing != NULL)
937 {
938 *is_missing = true;
939 return false;
940 }
941 elog(ERROR, "cache lookup failed for relation %u", relid);
942 }
944
946
947 /*
948 * Quick check: if it ain't in the path at all, it ain't visible. Items in
949 * the system namespace are surely in the path and so we needn't even do
950 * list_member_oid() for them.
951 */
952 relnamespace = relform->relnamespace;
953 if (relnamespace != PG_CATALOG_NAMESPACE &&
954 !list_member_oid(activeSearchPath, relnamespace))
955 visible = false;
956 else
957 {
958 /*
959 * If it is in the path, it might still not be visible; it could be
960 * hidden by another relation of the same name earlier in the path. So
961 * we must do a slow check for conflicting relations.
962 */
963 char *relname = NameStr(relform->relname);
964 ListCell *l;
965
966 visible = false;
967 foreach(l, activeSearchPath)
968 {
970
971 if (namespaceId == relnamespace)
972 {
973 /* Found it first in path */
974 visible = true;
975 break;
976 }
978 {
979 /* Found something else first in path */
980 break;
981 }
982 }
983 }
984
986
987 return visible;
988}
NameData relname
Definition pg_class.h:40
FormData_pg_class * Form_pg_class
Definition pg_class.h:160

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

Referenced by pg_table_is_visible(), and RelationIsVisible().

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char relname)

Definition at line 886 of file namespace.c.

887{
888 Oid relid;
889 ListCell *l;
890
892
893 foreach(l, activeSearchPath)
894 {
896
898 if (OidIsValid(relid))
899 return relid;
900 }
901
902 /* Not found in path */
903 return InvalidOid;
904}

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

Referenced by plpgsql_parse_wordrowtype(), and RangeVarGetRelidExtended().

◆ RemoveTempRelations()

static void RemoveTempRelations ( Oid  tempNamespaceId)
static

Definition at line 4670 of file namespace.c.

4671{
4672 ObjectAddress object;
4673
4674 /*
4675 * We want to get rid of everything in the target namespace, but not the
4676 * namespace itself (deleting it only to recreate it later would be a
4677 * waste of cycles). Hence, specify SKIP_ORIGINAL. It's also an INTERNAL
4678 * deletion, and we want to not drop any extensions that might happen to
4679 * own temp objects.
4680 */
4682 object.objectId = tempNamespaceId;
4683 object.objectSubId = 0;
4684
4690}
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
Definition dependency.c:274
#define PERFORM_DELETION_SKIP_EXTENSIONS
Definition dependency.h:96
#define PERFORM_DELETION_QUIETLY
Definition dependency.h:94
#define PERFORM_DELETION_SKIP_ORIGINAL
Definition dependency.h:95
#define PERFORM_DELETION_INTERNAL
Definition dependency.h:92
@ DROP_CASCADE

References ObjectAddress::classId, DROP_CASCADE, fb(), 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 4696 of file namespace.c.

4697{
4698 if (OidIsValid(myTempNamespace)) /* should always be true */
4699 {
4700 /* Need to ensure we have a usable transaction. */
4704
4706
4709 }
4710}
Snapshot GetTransactionSnapshot(void)
Definition snapmgr.c:272
void PushActiveSnapshot(Snapshot snapshot)
Definition snapmgr.c:682
void PopActiveSnapshot(void)
Definition snapmgr.c:775
void StartTransactionCommand(void)
Definition xact.c:3080
void CommitTransactionCommand(void)
Definition xact.c:3178
void AbortOutOfAnyTransaction(void)
Definition xact.c:4884

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

Referenced by AtEOXact_Namespace().

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4716 of file namespace.c.

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

◆ SearchPathMatchesCurrentEnvironment()

bool SearchPathMatchesCurrentEnvironment ( SearchPathMatcher path)

Definition at line 3983 of file namespace.c.

3984{
3985 ListCell *lc,
3986 *lcp;
3987
3989
3990 /* Quick out if already known equal to active path. */
3991 if (path->generation == activePathGeneration)
3992 return true;
3993
3994 /* We scan down the activeSearchPath to see if it matches the input. */
3996
3997 /* If path->addTemp, first item should be my temp namespace. */
3998 if (path->addTemp)
3999 {
4000 if (lc && lfirst_oid(lc) == myTempNamespace)
4002 else
4003 return false;
4004 }
4005 /* If path->addCatalog, next item should be pg_catalog. */
4006 if (path->addCatalog)
4007 {
4010 else
4011 return false;
4012 }
4013 /* We should now be looking at the activeCreationNamespace. */
4015 return false;
4016 /* The remainder of activeSearchPath should match path->schemas. */
4017 foreach(lcp, path->schemas)
4018 {
4019 if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
4021 else
4022 return false;
4023 }
4024 if (lc)
4025 return false;
4026
4027 /*
4028 * Update path->generation so that future tests will return quickly, so
4029 * long as the active search path doesn't change.
4030 */
4032
4033 return true;
4034}
#define false
static ListCell * lnext(const List *l, const ListCell *c)
Definition pg_list.h:343

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

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

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3893 of file namespace.c.

3894{
3895 /* Worker should not have created its own namespaces ... */
3899
3900 /* Assign same namespace OIDs that leader has */
3901 myTempNamespace = tempNamespaceId;
3903
3904 /*
3905 * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
3906 * Even if the namespace is new so far as the leader is concerned, it's
3907 * not new to the worker, and we certainly wouldn't want the worker trying
3908 * to destroy it.
3909 */
3910
3911 baseSearchPathValid = false; /* may need to rebuild list */
3912 searchPathCacheValid = false;
3913}

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

Referenced by ParallelWorkerMain().

◆ spcache_init()

static void spcache_init ( void  )
static

Definition at line 307 of file namespace.c.

308{
311 return;
312
313 searchPathCacheValid = false;
314 baseSearchPathValid = false;
315
316 /*
317 * Make sure we don't leave dangling pointers if a failure happens during
318 * initialization.
319 */
322
324 {
325 /* Make the context we'll keep search path cache hashtable in */
327 "search_path processing cache",
329 }
330 else
331 {
333 }
334
335 /* arbitrary initial starting size of 16 elements */
338}
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
static SearchPathCacheEntry * LastSearchPathCacheEntry
Definition namespace.c:301
#define SPCACHE_RESET_THRESHOLD
Definition namespace.c:298
static nsphash_hash * SearchPathCache
Definition namespace.c:300

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, baseSearchPathValid, fb(), LastSearchPathCacheEntry, MemoryContextReset(), SearchPathCache, SearchPathCacheContext, searchPathCacheValid, SPCACHE_RESET_THRESHOLD, and TopMemoryContext.

Referenced by cachedNamespacePath(), and check_search_path().

◆ spcache_insert()

static SearchPathCacheEntry * spcache_insert ( const char searchPath,
Oid  roleid 
)
static

Definition at line 375 of file namespace.c.

376{
380 {
382 }
383 else
384 {
387 .searchPath = searchPath,
388 .roleid = roleid
389 };
390
391 /*
392 * searchPath is not saved in SearchPathCacheContext. First perform a
393 * lookup, and copy searchPath only if we need to create a new entry.
394 */
396
397 if (!entry)
398 {
399 bool found;
400
401 cachekey.searchPath = MemoryContextStrdup(SearchPathCacheContext, searchPath);
402 entry = nsphash_insert(SearchPathCache, cachekey, &found);
403 Assert(!found);
404
405 entry->oidlist = NIL;
406 entry->finalPath = NIL;
407 entry->firstNS = InvalidOid;
408 entry->temp_missing = false;
409 entry->forceRecompute = false;
410 /* do not touch entry->status, used by simplehash */
411 }
412
414 return entry;
415 }
416}
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition mcxt.c:1768
SearchPathCacheKey key
Definition namespace.c:175
const char * searchPath
Definition namespace.c:169

References Assert, fb(), SearchPathCacheEntry::finalPath, SearchPathCacheEntry::firstNS, SearchPathCacheEntry::forceRecompute, InvalidOid, SearchPathCacheEntry::key, LastSearchPathCacheEntry, MemoryContextStrdup(), NIL, SearchPathCacheEntry::oidlist, SearchPathCacheKey::roleid, SearchPathCacheKey::searchPath, SearchPathCache, SearchPathCacheContext, and SearchPathCacheEntry::temp_missing.

Referenced by cachedNamespacePath(), and check_search_path().

◆ spcache_lookup()

static SearchPathCacheEntry * spcache_lookup ( const char searchPath,
Oid  roleid 
)
static

Definition at line 345 of file namespace.c.

346{
350 {
352 }
353 else
354 {
357 .searchPath = searchPath,
358 .roleid = roleid
359 };
360
362 if (entry)
364 return entry;
365 }
366}

References fb(), SearchPathCacheEntry::key, LastSearchPathCacheEntry, SearchPathCacheKey::roleid, SearchPathCacheKey::searchPath, and SearchPathCache.

Referenced by check_search_path().

◆ spcachekey_equal()

static bool spcachekey_equal ( SearchPathCacheKey  a,
SearchPathCacheKey  b 
)
inlinestatic

Definition at line 275 of file namespace.c.

276{
277 return a.roleid == b.roleid &&
278 strcmp(a.searchPath, b.searchPath) == 0;
279}
int b
Definition isn.c:74
int a
Definition isn.c:73

References a, b, and fb().

◆ spcachekey_hash()

static uint32 spcachekey_hash ( SearchPathCacheKey  key)
inlinestatic

Definition at line 255 of file namespace.c.

256{
258 int sp_len;
259
260 fasthash_init(&hs, 0);
261
262 hs.accum = key.roleid;
264
265 /*
266 * Combine search path into the hash and save the length for tweaking the
267 * final mix.
268 */
269 sp_len = fasthash_accum_cstring(&hs, key.searchPath);
270
271 return fasthash_final32(&hs, sp_len);
272}
static size_t fasthash_accum_cstring(fasthash_state *hs, const char *str)
static uint32 fasthash_final32(fasthash_state *hs, uint64 tweak)
static void fasthash_combine(fasthash_state *hs)
static void fasthash_init(fasthash_state *hs, uint64 seed)

References fasthash_accum_cstring(), fasthash_combine(), fasthash_final32(), fasthash_init(), and fb().

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  stxid)

Definition at line 2701 of file namespace.c.

2702{
2704}

References fb(), and StatisticsObjIsVisibleExt().

Referenced by getObjectDescription().

◆ StatisticsObjIsVisibleExt()

static bool StatisticsObjIsVisibleExt ( Oid  stxid,
bool is_missing 
)
static

Definition at line 2713 of file namespace.c.

2714{
2718 bool visible;
2719
2722 {
2723 if (is_missing != NULL)
2724 {
2725 *is_missing = true;
2726 return false;
2727 }
2728 elog(ERROR, "cache lookup failed for statistics object %u", stxid);
2729 }
2731
2733
2734 /*
2735 * Quick check: if it ain't in the path at all, it ain't visible. Items in
2736 * the system namespace are surely in the path and so we needn't even do
2737 * list_member_oid() for them.
2738 */
2739 stxnamespace = stxform->stxnamespace;
2742 visible = false;
2743 else
2744 {
2745 /*
2746 * If it is in the path, it might still not be visible; it could be
2747 * hidden by another statistics object of the same name earlier in the
2748 * path. So we must do a slow check for conflicting objects.
2749 */
2750 char *stxname = NameStr(stxform->stxname);
2751 ListCell *l;
2752
2753 visible = false;
2754 foreach(l, activeSearchPath)
2755 {
2757
2759 continue; /* do not look in temp namespace */
2760
2762 {
2763 /* Found it first in path */
2764 visible = true;
2765 break;
2766 }
2770 {
2771 /* Found something else first in path */
2772 break;
2773 }
2774 }
2775 }
2776
2778
2779 return visible;
2780}
END_CATALOG_STRUCT typedef FormData_pg_statistic_ext * Form_pg_statistic_ext
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition syscache.h:102

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

Referenced by pg_statistics_obj_is_visible(), and StatisticsObjIsVisible().

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 3282 of file namespace.c.

3283{
3285}

References fb(), and TSConfigIsVisibleExt().

Referenced by getObjectDescription(), and regconfigout().

◆ TSConfigIsVisibleExt()

static bool TSConfigIsVisibleExt ( Oid  cfgid,
bool is_missing 
)
static

Definition at line 3294 of file namespace.c.

3295{
3296 HeapTuple tup;
3298 Oid namespace;
3299 bool visible;
3300
3302 if (!HeapTupleIsValid(tup))
3303 {
3304 if (is_missing != NULL)
3305 {
3306 *is_missing = true;
3307 return false;
3308 }
3309 elog(ERROR, "cache lookup failed for text search configuration %u",
3310 cfgid);
3311 }
3313
3315
3316 /*
3317 * Quick check: if it ain't in the path at all, it ain't visible. Items in
3318 * the system namespace are surely in the path and so we needn't even do
3319 * list_member_oid() for them.
3320 */
3321 namespace = form->cfgnamespace;
3322 if (namespace != PG_CATALOG_NAMESPACE &&
3323 !list_member_oid(activeSearchPath, namespace))
3324 visible = false;
3325 else
3326 {
3327 /*
3328 * If it is in the path, it might still not be visible; it could be
3329 * hidden by another configuration of the same name earlier in the
3330 * path. So we must do a slow check for conflicting configurations.
3331 */
3332 char *name = NameStr(form->cfgname);
3333 ListCell *l;
3334
3335 visible = false;
3336 foreach(l, activeSearchPath)
3337 {
3339
3341 continue; /* do not look in temp namespace */
3342
3343 if (namespaceId == namespace)
3344 {
3345 /* Found it first in path */
3346 visible = true;
3347 break;
3348 }
3352 {
3353 /* Found something else first in path */
3354 break;
3355 }
3356 }
3357 }
3358
3360
3361 return visible;
3362}
END_CATALOG_STRUCT typedef FormData_pg_ts_config * Form_pg_ts_config

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

Referenced by pg_ts_config_is_visible(), and TSConfigIsVisible().

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2991 of file namespace.c.

2992{
2993 return TSDictionaryIsVisibleExt(dictId, NULL);
2994}

References fb(), and TSDictionaryIsVisibleExt().

Referenced by getObjectDescription(), and regdictionaryout().

◆ TSDictionaryIsVisibleExt()

static bool TSDictionaryIsVisibleExt ( Oid  dictId,
bool is_missing 
)
static

Definition at line 3003 of file namespace.c.

3004{
3005 HeapTuple tup;
3007 Oid namespace;
3008 bool visible;
3009
3011 if (!HeapTupleIsValid(tup))
3012 {
3013 if (is_missing != NULL)
3014 {
3015 *is_missing = true;
3016 return false;
3017 }
3018 elog(ERROR, "cache lookup failed for text search dictionary %u",
3019 dictId);
3020 }
3022
3024
3025 /*
3026 * Quick check: if it ain't in the path at all, it ain't visible. Items in
3027 * the system namespace are surely in the path and so we needn't even do
3028 * list_member_oid() for them.
3029 */
3030 namespace = form->dictnamespace;
3031 if (namespace != PG_CATALOG_NAMESPACE &&
3032 !list_member_oid(activeSearchPath, namespace))
3033 visible = false;
3034 else
3035 {
3036 /*
3037 * If it is in the path, it might still not be visible; it could be
3038 * hidden by another dictionary of the same name earlier in the path.
3039 * So we must do a slow check for conflicting dictionaries.
3040 */
3041 char *name = NameStr(form->dictname);
3042 ListCell *l;
3043
3044 visible = false;
3045 foreach(l, activeSearchPath)
3046 {
3048
3050 continue; /* do not look in temp namespace */
3051
3052 if (namespaceId == namespace)
3053 {
3054 /* Found it first in path */
3055 visible = true;
3056 break;
3057 }
3061 {
3062 /* Found something else first in path */
3063 break;
3064 }
3065 }
3066 }
3067
3069
3070 return visible;
3071}
END_CATALOG_STRUCT typedef FormData_pg_ts_dict * Form_pg_ts_dict
Definition pg_ts_dict.h:56

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

Referenced by pg_ts_dict_is_visible(), and TSDictionaryIsVisible().

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2846 of file namespace.c.

2847{
2848 return TSParserIsVisibleExt(prsId, NULL);
2849}

References fb(), and TSParserIsVisibleExt().

Referenced by getObjectDescription().

◆ TSParserIsVisibleExt()

static bool TSParserIsVisibleExt ( Oid  prsId,
bool is_missing 
)
static

Definition at line 2858 of file namespace.c.

2859{
2860 HeapTuple tup;
2862 Oid namespace;
2863 bool visible;
2864
2866 if (!HeapTupleIsValid(tup))
2867 {
2868 if (is_missing != NULL)
2869 {
2870 *is_missing = true;
2871 return false;
2872 }
2873 elog(ERROR, "cache lookup failed for text search parser %u", prsId);
2874 }
2876
2878
2879 /*
2880 * Quick check: if it ain't in the path at all, it ain't visible. Items in
2881 * the system namespace are surely in the path and so we needn't even do
2882 * list_member_oid() for them.
2883 */
2884 namespace = form->prsnamespace;
2885 if (namespace != PG_CATALOG_NAMESPACE &&
2886 !list_member_oid(activeSearchPath, namespace))
2887 visible = false;
2888 else
2889 {
2890 /*
2891 * If it is in the path, it might still not be visible; it could be
2892 * hidden by another parser of the same name earlier in the path. So
2893 * we must do a slow check for conflicting parsers.
2894 */
2895 char *name = NameStr(form->prsname);
2896 ListCell *l;
2897
2898 visible = false;
2899 foreach(l, activeSearchPath)
2900 {
2902
2904 continue; /* do not look in temp namespace */
2905
2906 if (namespaceId == namespace)
2907 {
2908 /* Found it first in path */
2909 visible = true;
2910 break;
2911 }
2915 {
2916 /* Found something else first in path */
2917 break;
2918 }
2919 }
2920 }
2921
2923
2924 return visible;
2925}
END_CATALOG_STRUCT typedef FormData_pg_ts_parser * Form_pg_ts_parser

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

Referenced by pg_ts_parser_is_visible(), and TSParserIsVisible().

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 3137 of file namespace.c.

3138{
3140}

References fb(), and TSTemplateIsVisibleExt().

Referenced by getObjectDescription().

◆ TSTemplateIsVisibleExt()

static bool TSTemplateIsVisibleExt ( Oid  tmplId,
bool is_missing 
)
static

Definition at line 3149 of file namespace.c.

3150{
3151 HeapTuple tup;
3153 Oid namespace;
3154 bool visible;
3155
3157 if (!HeapTupleIsValid(tup))
3158 {
3159 if (is_missing != NULL)
3160 {
3161 *is_missing = true;
3162 return false;
3163 }
3164 elog(ERROR, "cache lookup failed for text search template %u", tmplId);
3165 }
3167
3169
3170 /*
3171 * Quick check: if it ain't in the path at all, it ain't visible. Items in
3172 * the system namespace are surely in the path and so we needn't even do
3173 * list_member_oid() for them.
3174 */
3175 namespace = form->tmplnamespace;
3176 if (namespace != PG_CATALOG_NAMESPACE &&
3177 !list_member_oid(activeSearchPath, namespace))
3178 visible = false;
3179 else
3180 {
3181 /*
3182 * If it is in the path, it might still not be visible; it could be
3183 * hidden by another template of the same name earlier in the path. So
3184 * we must do a slow check for conflicting templates.
3185 */
3186 char *name = NameStr(form->tmplname);
3187 ListCell *l;
3188
3189 visible = false;
3190 foreach(l, activeSearchPath)
3191 {
3193
3195 continue; /* do not look in temp namespace */
3196
3197 if (namespaceId == namespace)
3198 {
3199 /* Found it first in path */
3200 visible = true;
3201 break;
3202 }
3206 {
3207 /* Found something else first in path */
3208 break;
3209 }
3210 }
3211 }
3212
3214
3215 return visible;
3216}
END_CATALOG_STRUCT typedef FormData_pg_ts_template * Form_pg_ts_template

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

Referenced by pg_ts_template_is_visible(), and TSTemplateIsVisible().

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 1041 of file namespace.c.

1042{
1043 return TypeIsVisibleExt(typid, NULL);
1044}

References fb(), and TypeIsVisibleExt().

Referenced by format_type_extended().

◆ TypeIsVisibleExt()

static bool TypeIsVisibleExt ( Oid  typid,
bool is_missing 
)
static

Definition at line 1053 of file namespace.c.

1054{
1058 bool visible;
1059
1062 {
1063 if (is_missing != NULL)
1064 {
1065 *is_missing = true;
1066 return false;
1067 }
1068 elog(ERROR, "cache lookup failed for type %u", typid);
1069 }
1071
1073
1074 /*
1075 * Quick check: if it ain't in the path at all, it ain't visible. Items in
1076 * the system namespace are surely in the path and so we needn't even do
1077 * list_member_oid() for them.
1078 */
1079 typnamespace = typform->typnamespace;
1082 visible = false;
1083 else
1084 {
1085 /*
1086 * If it is in the path, it might still not be visible; it could be
1087 * hidden by another type of the same name earlier in the path. So we
1088 * must do a slow check for conflicting types.
1089 */
1090 char *typname = NameStr(typform->typname);
1091 ListCell *l;
1092
1093 visible = false;
1094 foreach(l, activeSearchPath)
1095 {
1097
1099 {
1100 /* Found it first in path */
1101 visible = true;
1102 break;
1103 }
1107 {
1108 /* Found something else first in path */
1109 break;
1110 }
1111 }
1112 }
1113
1115
1116 return visible;
1117}
END_CATALOG_STRUCT typedef FormData_pg_type * Form_pg_type
Definition pg_type.h:265
NameData typname
Definition pg_type.h:43

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

Referenced by pg_type_is_visible(), and TypeIsVisible().

◆ TypenameGetTypid()

Oid TypenameGetTypid ( const char typname)

Definition at line 996 of file namespace.c.

997{
998 return TypenameGetTypidExtended(typname, true);
999}
Oid TypenameGetTypidExtended(const char *typname, bool temp_ok)
Definition namespace.c:1009

References TypenameGetTypidExtended(), and typname.

◆ TypenameGetTypidExtended()

Oid TypenameGetTypidExtended ( const char typname,
bool  temp_ok 
)

Definition at line 1009 of file namespace.c.

1010{
1011 Oid typid;
1012 ListCell *l;
1013
1015
1016 foreach(l, activeSearchPath)
1017 {
1019
1021 continue; /* do not look in temp namespace */
1022
1026 if (OidIsValid(typid))
1027 return typid;
1028 }
1029
1030 /* Not found in path */
1031 return InvalidOid;
1032}

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

Referenced by LookupTypeNameExtended(), and TypenameGetTypid().

Variable Documentation

◆ activeCreationNamespace

◆ activePathGeneration

uint64 activePathGeneration = 1
static

◆ activeSearchPath

◆ activeTempCreationPending

◆ baseCreationNamespace

Oid baseCreationNamespace = InvalidOid
static

Definition at line 151 of file namespace.c.

Referenced by InitializeSearchPath(), and recomputeNamespacePath().

◆ baseSearchPath

List* baseSearchPath = NIL
static

Definition at line 149 of file namespace.c.

Referenced by InitializeSearchPath(), and recomputeNamespacePath().

◆ baseSearchPathValid

◆ baseTempCreationPending

bool baseTempCreationPending = false
static

Definition at line 153 of file namespace.c.

Referenced by InitializeSearchPath(), and recomputeNamespacePath().

◆ LastSearchPathCacheEntry

SearchPathCacheEntry* LastSearchPathCacheEntry = NULL
static

Definition at line 301 of file namespace.c.

Referenced by spcache_init(), spcache_insert(), and spcache_lookup().

◆ myTempNamespace

◆ myTempNamespaceSubID

◆ myTempToastNamespace

◆ namespace_search_path

char* namespace_search_path = NULL

Definition at line 211 of file namespace.c.

Referenced by CreateSchemaCommand(), and recomputeNamespacePath().

◆ namespaceUser

Oid namespaceUser = InvalidOid
static

Definition at line 155 of file namespace.c.

Referenced by InitializeSearchPath(), and recomputeNamespacePath().

◆ SearchPathCache

nsphash_hash* SearchPathCache = NULL
static

Definition at line 300 of file namespace.c.

Referenced by spcache_init(), spcache_insert(), and spcache_lookup().

◆ SearchPathCacheContext

MemoryContext SearchPathCacheContext = NULL
static

Definition at line 165 of file namespace.c.

Referenced by cachedNamespacePath(), check_search_path(), spcache_init(), and spcache_insert().

◆ searchPathCacheValid