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

Go to the source code of this file.

Data Structures

struct  OverrideStackEntry
 

Macros

#define SPACE_PER_OP
 

Functions

static void recomputeNamespacePath (void)
 
static void InitTempTableNamespace (void)
 
static void RemoveTempRelations (Oid tempNamespaceId)
 
static void RemoveTempRelationsCallback (int code, Datum arg)
 
static void NamespaceCallback (Datum arg, int cacheid, uint32 hashvalue)
 
static bool MatchNamedCall (HeapTuple proctup, int nargs, List *argnames, int **argnumbers)
 
Oid RangeVarGetRelidExtended (const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
 
Oid RangeVarGetCreationNamespace (const RangeVar *newRelation)
 
Oid RangeVarGetAndCheckCreationNamespace (RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
 
void RangeVarAdjustRelationPersistence (RangeVar *newRelation, Oid nspid)
 
Oid RelnameGetRelid (const char *relname)
 
bool RelationIsVisible (Oid relid)
 
Oid TypenameGetTypid (const char *typname)
 
bool TypeIsVisible (Oid typid)
 
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool missing_ok)
 
bool FunctionIsVisible (Oid funcid)
 
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
 
FuncCandidateList OpernameGetCandidates (List *names, char oprkind, bool missing_schema_ok)
 
bool OperatorIsVisible (Oid oprid)
 
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
 
bool OpclassIsVisible (Oid opcid)
 
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
 
bool OpfamilyIsVisible (Oid opfid)
 
static Oid lookup_collation (const char *collname, Oid collnamespace, int32 encoding)
 
Oid CollationGetCollid (const char *collname)
 
bool CollationIsVisible (Oid collid)
 
Oid ConversionGetConid (const char *conname)
 
bool ConversionIsVisible (Oid conid)
 
Oid get_statistics_object_oid (List *names, bool missing_ok)
 
bool StatisticsObjIsVisible (Oid relid)
 
Oid get_ts_parser_oid (List *names, bool missing_ok)
 
bool TSParserIsVisible (Oid prsId)
 
Oid get_ts_dict_oid (List *names, bool missing_ok)
 
bool TSDictionaryIsVisible (Oid dictId)
 
Oid get_ts_template_oid (List *names, bool missing_ok)
 
bool TSTemplateIsVisible (Oid tmplId)
 
Oid get_ts_config_oid (List *names, bool missing_ok)
 
bool TSConfigIsVisible (Oid cfgid)
 
void DeconstructQualifiedName (List *names, char **nspname_p, char **objname_p)
 
Oid LookupNamespaceNoError (const char *nspname)
 
Oid LookupExplicitNamespace (const char *nspname, bool missing_ok)
 
Oid LookupCreationNamespace (const char *nspname)
 
void CheckSetNamespace (Oid oldNspOid, Oid nspOid)
 
Oid QualifiedNameGetCreationNamespace (List *names, char **objname_p)
 
Oid get_namespace_oid (const char *nspname, bool missing_ok)
 
RangeVarmakeRangeVarFromNameList (List *names)
 
char * NameListToString (List *names)
 
char * NameListToQuotedString (List *names)
 
bool isTempNamespace (Oid namespaceId)
 
bool isTempToastNamespace (Oid namespaceId)
 
bool isTempOrTempToastNamespace (Oid namespaceId)
 
bool isAnyTempNamespace (Oid namespaceId)
 
bool isOtherTempNamespace (Oid namespaceId)
 
int GetTempNamespaceBackendId (Oid namespaceId)
 
Oid GetTempToastNamespace (void)
 
void GetTempNamespaceState (Oid *tempNamespaceId, Oid *tempToastNamespaceId)
 
void SetTempNamespaceState (Oid tempNamespaceId, Oid tempToastNamespaceId)
 
OverrideSearchPathGetOverrideSearchPath (MemoryContext context)
 
OverrideSearchPathCopyOverrideSearchPath (OverrideSearchPath *path)
 
bool OverrideSearchPathMatchesCurrent (OverrideSearchPath *path)
 
void PushOverrideSearchPath (OverrideSearchPath *newpath)
 
void PopOverrideSearchPath (void)
 
Oid get_collation_oid (List *name, bool missing_ok)
 
Oid get_conversion_oid (List *name, bool missing_ok)
 
Oid FindDefaultConversionProc (int32 for_encoding, int32 to_encoding)
 
void AtEOXact_Namespace (bool isCommit, bool parallel)
 
void AtEOSubXact_Namespace (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void ResetTempTableNamespace (void)
 
bool check_search_path (char **newval, void **extra, GucSource source)
 
void assign_search_path (const char *newval, void *extra)
 
void InitializeSearchPath (void)
 
Listfetch_search_path (bool includeImplicit)
 
int fetch_search_path_array (Oid *sarray, int sarray_len)
 
Datum pg_table_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_type_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_function_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_operator_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_opclass_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_opfamily_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_collation_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_conversion_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_statistics_obj_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_parser_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_dict_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_template_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_config_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_my_temp_schema (PG_FUNCTION_ARGS)
 
Datum pg_is_other_temp_schema (PG_FUNCTION_ARGS)
 

Variables

static ListactiveSearchPath = NIL
 
static Oid activeCreationNamespace = InvalidOid
 
static bool activeTempCreationPending = false
 
static ListbaseSearchPath = NIL
 
static Oid baseCreationNamespace = InvalidOid
 
static bool baseTempCreationPending = false
 
static Oid namespaceUser = InvalidOid
 
static bool baseSearchPathValid = true
 
static ListoverrideStack = NIL
 
static Oid myTempNamespace = InvalidOid
 
static Oid myTempToastNamespace = InvalidOid
 
static SubTransactionId myTempNamespaceSubID = InvalidSubTransactionId
 
char * namespace_search_path = NULL
 

Macro Definition Documentation

◆ SPACE_PER_OP

#define SPACE_PER_OP
Value:
2 * sizeof(Oid))
unsigned int Oid
Definition: postgres_ext.h:31
#define MAXALIGN(LEN)
Definition: c.h:652
#define offsetof(type, field)
Definition: c.h:622

Referenced by OpernameGetCandidates().

Function Documentation

◆ assign_search_path()

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

Definition at line 4113 of file namespace.c.

References baseSearchPathValid.

4114 {
4115  /*
4116  * We mark the path as needing recomputation, but don't do anything until
4117  * it's needed. This avoids trying to do database access during GUC
4118  * initialization, or outside a transaction.
4119  */
4120  baseSearchPathValid = false;
4121 }
static bool baseSearchPathValid
Definition: namespace.c:152

◆ AtEOSubXact_Namespace()

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

Definition at line 3962 of file namespace.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

3964 {
3965  OverrideStackEntry *entry;
3966 
3967  if (myTempNamespaceSubID == mySubid)
3968  {
3969  if (isCommit)
3970  myTempNamespaceSubID = parentSubid;
3971  else
3972  {
3974  /* TEMP namespace creation failed, so reset state */
3977  baseSearchPathValid = false; /* need to rebuild list */
3978  }
3979  }
3980 
3981  /*
3982  * Clean up if someone failed to do PopOverrideSearchPath
3983  */
3984  while (overrideStack)
3985  {
3988  break;
3989  if (isCommit)
3990  elog(WARNING, "leaked override search path");
3992  list_free(entry->searchPath);
3993  pfree(entry);
3994  }
3995 
3996  /* Activate the next level down. */
3997  if (overrideStack)
3998  {
4000  activeSearchPath = entry->searchPath;
4002  activeTempCreationPending = false; /* XXX is this OK? */
4003  }
4004  else
4005  {
4006  /* If not baseSearchPathValid, this is useless but harmless */
4010  }
4011 }
static bool baseSearchPathValid
Definition: namespace.c:152
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
static List * overrideStack
Definition: namespace.c:163
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:1031
#define linitial(l)
Definition: pg_list.h:111
static bool baseTempCreationPending
Definition: namespace.c:147
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:143
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:753
#define InvalidSubTransactionId
Definition: c.h:480
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1133
#define elog
Definition: elog.h:219
List * list_delete_first(List *list)
Definition: list.c:666

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 3907 of file namespace.c.

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

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

3908 {
3909  /*
3910  * If we abort the transaction in which a temp namespace was selected,
3911  * we'll have to do any creation or cleanout work over again. So, just
3912  * forget the namespace entirely until next time. On the other hand, if
3913  * we commit then register an exit callback to clean out the temp tables
3914  * at backend shutdown. (We only want to register the callback once per
3915  * session, so this is a good place to do it.)
3916  */
3917  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
3918  {
3919  if (isCommit)
3921  else
3922  {
3925  baseSearchPathValid = false; /* need to rebuild list */
3926  }
3928  }
3929 
3930  /*
3931  * Clean up if someone failed to do PopOverrideSearchPath
3932  */
3933  if (overrideStack)
3934  {
3935  if (isCommit)
3936  elog(WARNING, "leaked override search path");
3937  while (overrideStack)
3938  {
3939  OverrideStackEntry *entry;
3940 
3943  list_free(entry->searchPath);
3944  pfree(entry);
3945  }
3946  /* If not baseSearchPathValid, this is useless but harmless */
3950  }
3951 }
static bool baseSearchPathValid
Definition: namespace.c:152
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
static List * overrideStack
Definition: namespace.c:163
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:1031
#define linitial(l)
Definition: pg_list.h:111
static bool baseTempCreationPending
Definition: namespace.c:147
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:331
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:143
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidSubTransactionId
Definition: c.h:480
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1133
#define elog
Definition: elog.h:219
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4048
List * list_delete_first(List *list)
Definition: list.c:666

◆ check_search_path()

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

Definition at line 4079 of file namespace.c.

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

4080 {
4081  char *rawname;
4082  List *namelist;
4083 
4084  /* Need a modifiable copy of string */
4085  rawname = pstrdup(*newval);
4086 
4087  /* Parse string into list of identifiers */
4088  if (!SplitIdentifierString(rawname, ',', &namelist))
4089  {
4090  /* syntax error in name list */
4091  GUC_check_errdetail("List syntax is invalid.");
4092  pfree(rawname);
4093  list_free(namelist);
4094  return false;
4095  }
4096 
4097  /*
4098  * We used to try to check that the named schemas exist, but there are
4099  * many valid use-cases for having search_path settings that include
4100  * schemas that don't exist; and often, we are not inside a transaction
4101  * here and so can't consult the system catalogs anyway. So now, the only
4102  * requirement is syntactic validity of the identifier list.
4103  */
4104 
4105  pfree(rawname);
4106  list_free(namelist);
4107 
4108  return true;
4109 }
#define GUC_check_errdetail
Definition: guc.h:410
char * pstrdup(const char *in)
Definition: mcxt.c:1161
void pfree(void *pointer)
Definition: mcxt.c:1031
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3290
#define newval
void list_free(List *list)
Definition: list.c:1133
Definition: pg_list.h:45

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2947 of file namespace.c.

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

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

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

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 1993 of file namespace.c.

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

Referenced by CollationIsVisible().

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

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2027 of file namespace.c.

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

Referenced by generate_collation_name(), and pg_collation_is_visible().

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

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2078 of file namespace.c.

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

Referenced by ConversionIsVisible().

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

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2110 of file namespace.c.

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

Referenced by pg_conversion_is_visible().

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

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3336 of file namespace.c.

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

Referenced by CopyCachedPlan().

3337 {
3338  OverrideSearchPath *result;
3339 
3340  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3341  result->schemas = list_copy(path->schemas);
3342  result->addCatalog = path->addCatalog;
3343  result->addTemp = path->addTemp;
3344 
3345  return result;
3346 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
void * palloc(Size size)
Definition: mcxt.c:924

◆ DeconstructQualifiedName()

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

Definition at line 2788 of file namespace.c.

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

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

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

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4187 of file namespace.c.

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

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

4188 {
4189  List *result;
4190 
4192 
4193  /*
4194  * If the temp namespace should be first, force it to exist. This is so
4195  * that callers can trust the result to reflect the actual default
4196  * creation namespace. It's a bit bogus to do this here, since
4197  * current_schema() is supposedly a stable function without side-effects,
4198  * but the alternatives seem worse.
4199  */
4201  {
4204  }
4205 
4206  result = list_copy(activeSearchPath);
4207  if (!includeImplicit)
4208  {
4209  while (result && linitial_oid(result) != activeCreationNamespace)
4210  result = list_delete_first(result);
4211  }
4212 
4213  return result;
4214 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool activeTempCreationPending
Definition: namespace.c:139
static void InitTempTableNamespace(void)
Definition: namespace.c:3798
#define linitial_oid(l)
Definition: pg_list.h:113
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:45
List * list_delete_first(List *list)
Definition: list.c:666

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4227 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4228 {
4229  int count = 0;
4230  ListCell *l;
4231 
4233 
4234  foreach(l, activeSearchPath)
4235  {
4236  Oid namespaceId = lfirst_oid(l);
4237 
4238  if (namespaceId == myTempNamespace)
4239  continue; /* do not include temp namespace */
4240 
4241  if (count < sarray_len)
4242  sarray[count] = namespaceId;
4243  count++;
4244  }
4245 
4246  return count;
4247 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3621 of file namespace.c.

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

Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().

3622 {
3623  Oid proc;
3624  ListCell *l;
3625 
3627 
3628  foreach(l, activeSearchPath)
3629  {
3630  Oid namespaceId = lfirst_oid(l);
3631 
3632  if (namespaceId == myTempNamespace)
3633  continue; /* do not look in temp namespace */
3634 
3635  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3636  if (OidIsValid(proc))
3637  return proc;
3638  }
3639 
3640  /* Not found in path */
3641  return InvalidOid;
3642 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ FuncnameGetCandidates()

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

Definition at line 922 of file namespace.c.

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

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

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

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1393 of file namespace.c.

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

Referenced by format_procedure_internal(), and pg_function_is_visible().

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

◆ get_collation_oid()

Oid get_collation_oid ( List name,
bool  missing_ok 
)

Definition at line 3512 of file namespace.c.

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

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

3513 {
3514  char *schemaname;
3515  char *collation_name;
3516  int32 dbencoding = GetDatabaseEncoding();
3517  Oid namespaceId;
3518  Oid colloid;
3519  ListCell *l;
3520 
3521  /* deconstruct the name list */
3522  DeconstructQualifiedName(name, &schemaname, &collation_name);
3523 
3524  if (schemaname)
3525  {
3526  /* use exact schema given */
3527  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3528  if (missing_ok && !OidIsValid(namespaceId))
3529  return InvalidOid;
3530 
3531  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3532  if (OidIsValid(colloid))
3533  return colloid;
3534  }
3535  else
3536  {
3537  /* search for it in search path */
3539 
3540  foreach(l, activeSearchPath)
3541  {
3542  namespaceId = lfirst_oid(l);
3543 
3544  if (namespaceId == myTempNamespace)
3545  continue; /* do not look in temp namespace */
3546 
3547  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3548  if (OidIsValid(colloid))
3549  return colloid;
3550  }
3551  }
3552 
3553  /* Not found in path */
3554  if (!missing_ok)
3555  ereport(ERROR,
3556  (errcode(ERRCODE_UNDEFINED_OBJECT),
3557  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3559  return InvalidOid;
3560 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
signed int int32
Definition: c.h:313
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1942
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
int GetDatabaseEncoding(void)
Definition: mbutils.c:1004
#define InvalidOid
Definition: postgres_ext.h:36
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1010
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ get_conversion_oid()

Oid get_conversion_oid ( List name,
bool  missing_ok 
)

Definition at line 3566 of file namespace.c.

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

Referenced by get_object_address().

3567 {
3568  char *schemaname;
3569  char *conversion_name;
3570  Oid namespaceId;
3571  Oid conoid = InvalidOid;
3572  ListCell *l;
3573 
3574  /* deconstruct the name list */
3575  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3576 
3577  if (schemaname)
3578  {
3579  /* use exact schema given */
3580  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3581  if (missing_ok && !OidIsValid(namespaceId))
3582  conoid = InvalidOid;
3583  else
3584  conoid = GetSysCacheOid2(CONNAMENSP,
3585  PointerGetDatum(conversion_name),
3586  ObjectIdGetDatum(namespaceId));
3587  }
3588  else
3589  {
3590  /* search for it in search path */
3592 
3593  foreach(l, activeSearchPath)
3594  {
3595  namespaceId = lfirst_oid(l);
3596 
3597  if (namespaceId == myTempNamespace)
3598  continue; /* do not look in temp namespace */
3599 
3600  conoid = GetSysCacheOid2(CONNAMENSP,
3601  PointerGetDatum(conversion_name),
3602  ObjectIdGetDatum(namespaceId));
3603  if (OidIsValid(conoid))
3604  return conoid;
3605  }
3606  }
3607 
3608  /* Not found in path */
3609  if (!OidIsValid(conoid) && !missing_ok)
3610  ereport(ERROR,
3611  (errcode(ERRCODE_UNDEFINED_OBJECT),
3612  errmsg("conversion \"%s\" does not exist",
3613  NameListToString(name))));
3614  return conoid;
3615 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2872
#define PointerGetDatum(X)
Definition: postgres.h:539
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2788
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:193
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3082
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

Definition at line 3024 of file namespace.c.

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

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

3025 {
3026  Oid oid;
3027 
3029  if (!OidIsValid(oid) && !missing_ok)
3030  ereport(ERROR,
3031  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3032  errmsg("schema \"%s\" does not exist", nspname)));
3033 
3034  return oid;
3035 }
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define GetSysCacheOid1(cacheId, key1)
Definition: syscache.h:191
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:561
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2157 of file namespace.c.

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

Referenced by get_object_address().

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

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2658 of file namespace.c.

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

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

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

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2405 of file namespace.c.

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

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

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

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2279 of file namespace.c.

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

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

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

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2532 of file namespace.c.

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

Referenced by DefineTSDictionary(), and get_object_address().

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

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3300 of file namespace.c.

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

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

3301 {
3302  OverrideSearchPath *result;
3303  List *schemas;
3304  MemoryContext oldcxt;
3305 
3307 
3308  oldcxt = MemoryContextSwitchTo(context);
3309 
3310  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3311  schemas = list_copy(activeSearchPath);
3312  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3313  {
3314  if (linitial_oid(schemas) == myTempNamespace)
3315  result->addTemp = true;
3316  else
3317  {
3318  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3319  result->addCatalog = true;
3320  }
3321  schemas = list_delete_first(schemas);
3322  }
3323  result->schemas = schemas;
3324 
3325  MemoryContextSwitchTo(oldcxt);
3326 
3327  return result;
3328 }
static Oid myTempNamespace
Definition: namespace.c:180
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * list_copy(const List *oldlist)
Definition: list.c:1160
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static Oid activeCreationNamespace
Definition: namespace.c:136
void * palloc0(Size size)
Definition: mcxt.c:955
#define Assert(condition)
Definition: c.h:699
#define linitial_oid(l)
Definition: pg_list.h:113
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:45
List * list_delete_first(List *list)
Definition: list.c:666

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3214 of file namespace.c.

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

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

3215 {
3216  int result;
3217  char *nspname;
3218 
3219  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3220  nspname = get_namespace_name(namespaceId);
3221  if (!nspname)
3222  return InvalidBackendId; /* no such namespace? */
3223  if (strncmp(nspname, "pg_temp_", 8) == 0)
3224  result = atoi(nspname + 8);
3225  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3226  result = atoi(nspname + 14);
3227  else
3228  result = InvalidBackendId;
3229  pfree(nspname);
3230  return result;
3231 }
void pfree(void *pointer)
Definition: mcxt.c:1031
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3051
#define InvalidBackendId
Definition: backendid.h:23

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3253 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3254 {
3255  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3256  *tempNamespaceId = myTempNamespace;
3257  *tempToastNamespaceId = myTempToastNamespace;
3258 }
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3239 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3240 {
3242  return myTempToastNamespace;
3243 }
static Oid myTempToastNamespace
Definition: namespace.c:182
#define OidIsValid(objectId)
Definition: c.h:605
#define Assert(condition)
Definition: c.h:699

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4129 of file namespace.c.

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

Referenced by InitPostgres().

4130 {
4132  {
4133  /*
4134  * In bootstrap mode, the search path must be 'pg_catalog' so that
4135  * tables are created in the proper namespace; ignore the GUC setting.
4136  */
4137  MemoryContext oldcxt;
4138 
4140  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4141  MemoryContextSwitchTo(oldcxt);
4142  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4143  baseTempCreationPending = false;
4144  baseSearchPathValid = true;
4149  }
4150  else
4151  {
4152  /*
4153  * In normal mode, arrange for a callback on any syscache invalidation
4154  * of pg_namespace rows.
4155  */
4158  (Datum) 0);
4159  /* Force search path to be recomputed on next use */
4160  baseSearchPathValid = false;
4161  }
4162 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid GetUserId(void)
Definition: miscinit.c:379
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static Oid namespaceUser
Definition: namespace.c:149
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool baseTempCreationPending
Definition: namespace.c:147
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4169
static bool activeTempCreationPending
Definition: namespace.c:139
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static Oid baseCreationNamespace
Definition: namespace.c:145
static List * baseSearchPath
Definition: namespace.c:143
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1389
uintptr_t Datum
Definition: postgres.h:365
#define list_make1_oid(x1)
Definition: pg_list.h:151
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:372
static List * activeSearchPath
Definition: namespace.c:133

◆ InitTempTableNamespace()

static void InitTempTableNamespace ( void  )
static

Definition at line 3798 of file namespace.c.

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

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

3799 {
3800  char namespaceName[NAMEDATALEN];
3801  Oid namespaceId;
3802  Oid toastspaceId;
3803 
3805 
3806  /*
3807  * First, do permission check to see if we are authorized to make temp
3808  * tables. We use a nonstandard error message here since "databasename:
3809  * permission denied" might be a tad cryptic.
3810  *
3811  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
3812  * that's necessary since current user ID could change during the session.
3813  * But there's no need to make the namespace in the first place until a
3814  * temp table creation request is made by someone with appropriate rights.
3815  */
3818  ereport(ERROR,
3819  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3820  errmsg("permission denied to create temporary tables in database \"%s\"",
3822 
3823  /*
3824  * Do not allow a Hot Standby session to make temp tables. Aside from
3825  * problems with modifying the system catalogs, there is a naming
3826  * conflict: pg_temp_N belongs to the session with BackendId N on the
3827  * master, not to a hot standby session with the same BackendId. We
3828  * should not be able to get here anyway due to XactReadOnly checks, but
3829  * let's just make real sure. Note that this also backstops various
3830  * operations that allow XactReadOnly transactions to modify temp tables;
3831  * they'd need RecoveryInProgress checks if not for this.
3832  */
3833  if (RecoveryInProgress())
3834  ereport(ERROR,
3835  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3836  errmsg("cannot create temporary tables during recovery")));
3837 
3838  /* Parallel workers can't create temporary tables, either. */
3839  if (IsParallelWorker())
3840  ereport(ERROR,
3841  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3842  errmsg("cannot create temporary tables during a parallel operation")));
3843 
3844  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
3845 
3846  namespaceId = get_namespace_oid(namespaceName, true);
3847  if (!OidIsValid(namespaceId))
3848  {
3849  /*
3850  * First use of this temp namespace in this database; create it. The
3851  * temp namespaces are always owned by the superuser. We leave their
3852  * permissions at default --- i.e., no access except to superuser ---
3853  * to ensure that unprivileged users can't peek at other backends'
3854  * temp tables. This works because the places that access the temp
3855  * namespace for my own backend skip permissions checks on it.
3856  */
3857  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3858  true);
3859  /* Advance command counter to make namespace visible */
3861  }
3862  else
3863  {
3864  /*
3865  * If the namespace already exists, clean it out (in case the former
3866  * owner crashed without doing so).
3867  */
3868  RemoveTempRelations(namespaceId);
3869  }
3870 
3871  /*
3872  * If the corresponding toast-table namespace doesn't exist yet, create
3873  * it. (We assume there is no need to clean it out if it does exist, since
3874  * dropping a parent table should make its toast table go away.)
3875  */
3876  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
3877  MyBackendId);
3878 
3879  toastspaceId = get_namespace_oid(namespaceName, true);
3880  if (!OidIsValid(toastspaceId))
3881  {
3882  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3883  true);
3884  /* Advance command counter to make namespace visible */
3886  }
3887 
3888  /*
3889  * Okay, we've prepared the temp namespace ... but it's not committed yet,
3890  * so all our work could be undone by transaction rollback. Set flag for
3891  * AtEOXact_Namespace to know what to do.
3892  */
3893  myTempNamespace = namespaceId;
3894  myTempToastNamespace = toastspaceId;
3895 
3896  /* It should not be done already. */
3899 
3900  baseSearchPathValid = false; /* need to rebuild list */
3901 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3024
BackendId MyBackendId
Definition: globals.c:82
#define AssertState(condition)
Definition: c.h:702
Oid GetUserId(void)
Definition: miscinit.c:379
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:7939
#define OidIsValid(objectId)
Definition: c.h:605
#define NAMEDATALEN
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
#define ereport(elevel, rest)
Definition: elog.h:122
#define IsParallelWorker()
Definition: parallel.h:60
void CommandCounterIncrement(void)
Definition: xact.c:914
Oid MyDatabaseId
Definition: globals.c:86
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4639
#define Assert(condition)
Definition: c.h:699
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:641
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4022
#define InvalidSubTransactionId
Definition: c.h:480
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ACL_CREATE_TEMP
Definition: parsenodes.h:85
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
Definition: pg_namespace.c:42

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3175 of file namespace.c.

References get_namespace_name(), and pfree().

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

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

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3198 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

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

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3137 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

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

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3161 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

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

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3149 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

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

◆ lookup_collation()

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

Definition at line 1942 of file namespace.c.

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

Referenced by CollationGetCollid(), and get_collation_oid().

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

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2915 of file namespace.c.

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

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

2916 {
2917  Oid namespaceId;
2918  AclResult aclresult;
2919 
2920  /* check for pg_temp alias */
2921  if (strcmp(nspname, "pg_temp") == 0)
2922  {
2923  /* Initialize temp namespace if first time through */
2926  return myTempNamespace;
2927  }
2928 
2929  namespaceId = get_namespace_oid(nspname, false);
2930 
2931  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2932  if (aclresult != ACLCHECK_OK)
2933  aclcheck_error(aclresult, OBJECT_SCHEMA,
2934  nspname);
2935 
2936  return namespaceId;
2937 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3024
Oid GetUserId(void)
Definition: miscinit.c:379
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4689
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3349
#define ACL_CREATE
Definition: parsenodes.h:84
static void InitTempTableNamespace(void)
Definition: namespace.c:3798
AclResult
Definition: acl.h:178

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2872 of file namespace.c.

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

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

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

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2842 of file namespace.c.

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

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

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

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 3042 of file namespace.c.

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

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

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

◆ MatchNamedCall()

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

Definition at line 1285 of file namespace.c.

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

Referenced by FuncnameGetCandidates().

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

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3116 of file namespace.c.

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

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

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3082 of file namespace.c.

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

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

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

◆ NamespaceCallback()

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

Definition at line 4169 of file namespace.c.

References baseSearchPathValid.

Referenced by InitializeSearchPath().

4170 {
4171  /* Force search path to be recomputed on next use */
4172  baseSearchPathValid = false;
4173 }
static bool baseSearchPathValid
Definition: namespace.c:152

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1812 of file namespace.c.

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

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

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

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1779 of file namespace.c.

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

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

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

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1726 of file namespace.c.

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

Referenced by format_operator_internal(), and pg_operator_is_visible().

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

◆ OpernameGetCandidates()

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

Definition at line 1566 of file namespace.c.

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

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

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

◆ OpernameGetOprid()

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

Definition at line 1464 of file namespace.c.

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

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

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

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1895 of file namespace.c.

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

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

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1862 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

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

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3352 of file namespace.c.

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

Referenced by RevalidateCachedQuery().

3353 {
3354  ListCell *lc,
3355  *lcp;
3356 
3358 
3359  /* We scan down the activeSearchPath to see if it matches the input. */
3361 
3362  /* If path->addTemp, first item should be my temp namespace. */
3363  if (path->addTemp)
3364  {
3365  if (lc && lfirst_oid(lc) == myTempNamespace)
3366  lc = lnext(lc);
3367  else
3368  return false;
3369  }
3370  /* If path->addCatalog, next item should be pg_catalog. */
3371  if (path->addCatalog)
3372  {
3373  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3374  lc = lnext(lc);
3375  else
3376  return false;
3377  }
3378  /* We should now be looking at the activeCreationNamespace. */
3379  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3380  return false;
3381  /* The remainder of activeSearchPath should match path->schemas. */
3382  foreach(lcp, path->schemas)
3383  {
3384  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3385  lc = lnext(lc);
3386  else
3387  return false;
3388  }
3389  if (lc)
3390  return false;
3391  return true;
3392 }
static Oid myTempNamespace
Definition: namespace.c:180
static void recomputeNamespacePath(void)
Definition: namespace.c:3648
static Oid activeCreationNamespace
Definition: namespace.c:136
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
#define lnext(lc)
Definition: pg_list.h:105
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ pg_collation_is_visible()

Datum pg_collation_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4330 of file namespace.c.

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

4331 {
4332  Oid oid = PG_GETARG_OID(0);
4333 
4335  PG_RETURN_NULL();
4336 
4338 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
bool CollationIsVisible(Oid collid)
Definition: namespace.c:2027
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_conversion_is_visible()

Datum pg_conversion_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4341 of file namespace.c.

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

4342 {
4343  Oid oid = PG_GETARG_OID(0);
4344 
4346  PG_RETURN_NULL();
4347 
4349 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
bool ConversionIsVisible(Oid conid)
Definition: namespace.c:2110
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_function_is_visible()

Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4286 of file namespace.c.

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

4287 {
4288  Oid oid = PG_GETARG_OID(0);
4289 
4291  PG_RETURN_NULL();
4292 
4294 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1393
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_is_other_temp_schema()

Datum pg_is_other_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4413 of file namespace.c.

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

4414 {
4415  Oid oid = PG_GETARG_OID(0);
4416 
4418 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
bool isOtherTempNamespace(Oid namespaceId)
Definition: namespace.c:3198

◆ pg_my_temp_schema()

Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4407 of file namespace.c.

References myTempNamespace, and PG_RETURN_OID.

4408 {
4410 }
static Oid myTempNamespace
Definition: namespace.c:180
#define PG_RETURN_OID(x)
Definition: fmgr.h:325

◆ pg_opclass_is_visible()

Datum pg_opclass_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4308 of file namespace.c.

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

4309 {
4310  Oid oid = PG_GETARG_OID(0);
4311 
4313  PG_RETURN_NULL();
4314 
4316 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
bool OpclassIsVisible(Oid opcid)
Definition: namespace.c:1812
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_operator_is_visible()

Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4297 of file namespace.c.

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

4298 {
4299  Oid oid = PG_GETARG_OID(0);
4300 
4302  PG_RETURN_NULL();
4303 
4305 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1726
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_opfamily_is_visible()

Datum pg_opfamily_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4319 of file namespace.c.

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

4320 {
4321  Oid oid = PG_GETARG_OID(0);
4322 
4324  PG_RETURN_NULL();
4325 
4327 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
bool OpfamilyIsVisible(Oid opfid)
Definition: namespace.c:1895
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_statistics_obj_is_visible()

Datum pg_statistics_obj_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4352 of file namespace.c.

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

4353 {
4354  Oid oid = PG_GETARG_OID(0);
4355 
4357  PG_RETURN_NULL();
4358 
4360 }
bool StatisticsObjIsVisible(Oid relid)
Definition: namespace.c:2214
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_table_is_visible()

Datum pg_table_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4264 of file namespace.c.

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

4265 {
4266  Oid oid = PG_GETARG_OID(0);
4267 
4269  PG_RETURN_NULL();
4270 
4272 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
bool RelationIsVisible(Oid relid)
Definition: namespace.c:701
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_ts_config_is_visible()

Datum pg_ts_config_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4396 of file namespace.c.

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

4397 {
4398  Oid oid = PG_GETARG_OID(0);
4399 
4401  PG_RETURN_NULL();
4402 
4404 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2716
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_ts_dict_is_visible()

Datum pg_ts_dict_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4374 of file namespace.c.

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

4375 {
4376  Oid oid = PG_GETARG_OID(0);
4377 
4379  PG_RETURN_NULL();
4380 
4382 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2463
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_ts_parser_is_visible()

Datum pg_ts_parser_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4363 of file namespace.c.

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

4364 {
4365  Oid oid = PG_GETARG_OID(0);
4366 
4368  PG_RETURN_NULL();
4369 
4371 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
bool TSParserIsVisible(Oid prsId)
Definition: namespace.c:2337
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_ts_template_is_visible()

Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4385 of file namespace.c.

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

4386 {
4387  Oid oid = PG_GETARG_OID(0);
4388 
4390  PG_RETURN_NULL();
4391 
4393 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
bool TSTemplateIsVisible(Oid tmplId)
Definition: namespace.c:2590
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ pg_type_is_visible()

Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4275 of file namespace.c.

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

4276 {
4277  Oid oid = PG_GETARG_OID(0);
4278 
4280  PG_RETURN_NULL();
4281 
4283 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
bool TypeIsVisible(Oid typid)
Definition: namespace.c:796
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3471 of file namespace.c.

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

Referenced by CreateSchemaCommand().

3472 {
3473  OverrideStackEntry *entry;
3474 
3475  /* Sanity checks. */
3476  if (overrideStack == NIL)
3477  elog(ERROR, "bogus PopOverrideSearchPath call");
3479  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3480  elog(ERROR, "bogus PopOverrideSearchPath call");
3481 
3482  /* Pop the stack and free storage. */
3484  list_free(entry->searchPath);
3485  pfree(entry);
3486 
3487  /* Activate the next level down. */
3488  if (overrideStack)
3489  {
3491  activeSearchPath = entry->searchPath;
3493  activeTempCreationPending = false; /* XXX is this OK? */
3494  }
3495  else
3496  {
3497  /* If not baseSearchPathValid, this is useless but harmless */
3501  }
3502 }
#define NIL
Definition: pg_list.h:69
static List * overrideStack
Definition: namespace.c:163
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:1031
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
static bool baseTempCreationPending
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
static List * baseSearchPath
Definition: namespace.c:143
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:753
static List * activeSearchPath
Definition: namespace.c:133
void list_free(List *list)
Definition: list.c:1133
#define elog
Definition: elog.h:219
List * list_delete_first(List *list)
Definition: list.c:666

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3412 of file namespace.c.

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

Referenced by CreateSchemaCommand().

3413 {
3414  OverrideStackEntry *entry;
3415  List *oidlist;
3416  Oid firstNS;
3417  MemoryContext oldcxt;
3418 
3419  /*
3420  * Copy the list for safekeeping, and insert implicitly-searched
3421  * namespaces as needed. This code should track recomputeNamespacePath.
3422  */
3424 
3425  oidlist = list_copy(newpath->schemas);
3426 
3427  /*
3428  * Remember the first member of the explicit list.
3429  */
3430  if (oidlist == NIL)
3431  firstNS = InvalidOid;
3432  else
3433  firstNS = linitial_oid(oidlist);
3434 
3435  /*
3436  * Add any implicitly-searched namespaces to the list. Note these go on
3437  * the front, not the back; also notice that we do not check USAGE
3438  * permissions for these.
3439  */
3440  if (newpath->addCatalog)
3441  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3442 
3443  if (newpath->addTemp && OidIsValid(myTempNamespace))
3444  oidlist = lcons_oid(myTempNamespace, oidlist);
3445 
3446  /*
3447  * Build the new stack entry, then insert it at the head of the list.
3448  */
3449  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3450  entry->searchPath = oidlist;
3451  entry->creationNamespace = firstNS;
3453 
3454  overrideStack = lcons(entry, overrideStack);
3455 
3456  /* And make it active. */
3457  activeSearchPath = entry->searchPath;
3459  activeTempCreationPending = false; /* XXX is this OK? */
3460 
3461  MemoryContextSwitchTo(oldcxt);
3462 }
#define NIL
Definition: pg_list.h:69
static Oid myTempNamespace
Definition: namespace.c:180
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static List * overrideStack
Definition: namespace.c:163
List * list_copy(const List *oldlist)
Definition: list.c:1160
List * lcons_oid(Oid datum, List *list)
Definition: list.c:295
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool activeTempCreationPending
Definition: namespace.c:139
MemoryContext TopMemoryContext
Definition: mcxt.c:44
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:753
List * lcons(void *datum, List *list)
Definition: list.c:259
#define linitial_oid(l)
Definition: pg_list.h:113
static List * activeSearchPath
Definition: namespace.c:133
void * palloc(Size size)
Definition: mcxt.c:924
Definition: pg_list.h:45

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 2975 of file namespace.c.

References activeCreationNamespace, activeTempCreationPending, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, get_namespace_oid(), InitTempTableNamespace(), 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().

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

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 634 of file namespace.c.

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

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 527 of file namespace.c.

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

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 440 of file namespace.c.

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

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

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

◆ RangeVarGetRelidExtended()

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

Definition at line 227 of file namespace.c.

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

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

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

◆ recomputeNamespacePath()

static void recomputeNamespacePath ( void  )
static

Definition at line 3648 of file namespace.c.

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

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

3649 {
3650  Oid roleid = GetUserId();
3651  char *rawname;
3652  List *namelist;
3653  List *oidlist;
3654  List *newpath;
3655  ListCell *l;
3656  bool temp_missing;
3657  Oid firstNS;
3658  MemoryContext oldcxt;
3659 
3660  /* Do nothing if an override search spec is active. */
3661  if (overrideStack)
3662  return;
3663 
3664  /* Do nothing if path is already vali