PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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_conversion_fn.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_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, bool missing_ok, bool nowait, 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)
 
Oid CollationGetCollid (const char *collname)
 
bool CollationIsVisible (Oid collid)
 
Oid ConversionGetConid (const char *conname)
 
bool ConversionIsVisible (Oid conid)
 
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_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

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

Referenced by OpernameGetCandidates().

Function Documentation

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

Definition at line 3944 of file namespace.c.

References baseSearchPathValid.

3945 {
3946  /*
3947  * We mark the path as needing recomputation, but don't do anything until
3948  * it's needed. This avoids trying to do database access during GUC
3949  * initialization, or outside a transaction.
3950  */
3951  baseSearchPathValid = false;
3952 }
static bool baseSearchPathValid
Definition: namespace.c:152
void AtEOSubXact_Namespace ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

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

3795 {
3796  OverrideStackEntry *entry;
3797 
3798  if (myTempNamespaceSubID == mySubid)
3799  {
3800  if (isCommit)
3801  myTempNamespaceSubID = parentSubid;
3802  else
3803  {
3805  /* TEMP namespace creation failed, so reset state */
3808  baseSearchPathValid = false; /* need to rebuild list */
3809  }
3810  }
3811 
3812  /*
3813  * Clean up if someone failed to do PopOverrideSearchPath
3814  */
3815  while (overrideStack)
3816  {
3819  break;
3820  if (isCommit)
3821  elog(WARNING, "leaked override search path");
3823  list_free(entry->searchPath);
3824  pfree(entry);
3825  }
3826 
3827  /* Activate the next level down. */
3828  if (overrideStack)
3829  {
3831  activeSearchPath = entry->searchPath;
3833  activeTempCreationPending = false; /* XXX is this OK? */
3834  }
3835  else
3836  {
3837  /* If not baseSearchPathValid, this is useless but harmless */
3841  }
3842 }
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:950
#define linitial(l)
Definition: pg_list.h:110
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:761
#define InvalidSubTransactionId
Definition: c.h:403
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
void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

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

3739 {
3740  /*
3741  * If we abort the transaction in which a temp namespace was selected,
3742  * we'll have to do any creation or cleanout work over again. So, just
3743  * forget the namespace entirely until next time. On the other hand, if
3744  * we commit then register an exit callback to clean out the temp tables
3745  * at backend shutdown. (We only want to register the callback once per
3746  * session, so this is a good place to do it.)
3747  */
3748  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
3749  {
3750  if (isCommit)
3752  else
3753  {
3756  baseSearchPathValid = false; /* need to rebuild list */
3757  }
3759  }
3760 
3761  /*
3762  * Clean up if someone failed to do PopOverrideSearchPath
3763  */
3764  if (overrideStack)
3765  {
3766  if (isCommit)
3767  elog(WARNING, "leaked override search path");
3768  while (overrideStack)
3769  {
3770  OverrideStackEntry *entry;
3771 
3774  list_free(entry->searchPath);
3775  pfree(entry);
3776  }
3777  /* If not baseSearchPathValid, this is useless but harmless */
3781  }
3782 }
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:950
#define linitial(l)
Definition: pg_list.h:110
static bool baseTempCreationPending
Definition: namespace.c:147
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:320
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:403
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:3879
List * list_delete_first(List *list)
Definition: list.c:666
bool check_search_path ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 3910 of file namespace.c.

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

3911 {
3912  char *rawname;
3913  List *namelist;
3914 
3915  /* Need a modifiable copy of string */
3916  rawname = pstrdup(*newval);
3917 
3918  /* Parse string into list of identifiers */
3919  if (!SplitIdentifierString(rawname, ',', &namelist))
3920  {
3921  /* syntax error in name list */
3922  GUC_check_errdetail("List syntax is invalid.");
3923  pfree(rawname);
3924  list_free(namelist);
3925  return false;
3926  }
3927 
3928  /*
3929  * We used to try to check that the named schemas exist, but there are
3930  * many valid use-cases for having search_path settings that include
3931  * schemas that don't exist; and often, we are not inside a transaction
3932  * here and so can't consult the system catalogs anyway. So now, the only
3933  * requirement is syntactic validity of the identifier list.
3934  */
3935 
3936  pfree(rawname);
3937  list_free(namelist);
3938 
3939  return true;
3940 }
#define GUC_check_errdetail
Definition: guc.h:407
char * pstrdup(const char *in)
Definition: mcxt.c:1077
void pfree(void *pointer)
Definition: mcxt.c:950
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3115
#define newval
void list_free(List *list)
Definition: list.c:1133
Definition: pg_list.h:45
void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 2762 of file namespace.c.

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

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

2763 {
2764  /* disallow renaming into or out of temp schemas */
2765  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2766  ereport(ERROR,
2767  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2768  errmsg("cannot move objects into or out of temporary schemas")));
2769 
2770  /* same for TOAST schema */
2771  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
2772  ereport(ERROR,
2773  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2774  errmsg("cannot move objects into or out of TOAST schema")));
2775 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_TOAST_NAMESPACE
Definition: pg_namespace.h:74
#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:2990
Oid CollationGetCollid ( const char *  collname)

Definition at line 1922 of file namespace.c.

References COLLNAMEENCNSP, GetDatabaseEncoding(), GetSysCacheOid3, Int32GetDatum, InvalidOid, lfirst_oid, myTempNamespace, ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().

Referenced by CollationIsVisible().

1923 {
1924  int32 dbencoding = GetDatabaseEncoding();
1925  ListCell *l;
1926 
1928 
1929  foreach(l, activeSearchPath)
1930  {
1931  Oid namespaceId = lfirst_oid(l);
1932  Oid collid;
1933 
1934  if (namespaceId == myTempNamespace)
1935  continue; /* do not look in temp namespace */
1936 
1937  /* Check for database-encoding-specific entry */
1939  PointerGetDatum(collname),
1940  Int32GetDatum(dbencoding),
1941  ObjectIdGetDatum(namespaceId));
1942  if (OidIsValid(collid))
1943  return collid;
1944 
1945  /* Check for any-encoding entry */
1947  PointerGetDatum(collname),
1948  Int32GetDatum(-1),
1949  ObjectIdGetDatum(namespaceId));
1950  if (OidIsValid(collid))
1951  return collid;
1952  }
1953 
1954  /* Not found in path */
1955  return InvalidOid;
1956 }
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:180
signed int int32
Definition: c.h:256
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
int GetDatabaseEncoding(void)
Definition: mbutils.c:1015
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define Int32GetDatum(X)
Definition: postgres.h:485
#define lfirst_oid(lc)
Definition: pg_list.h:108
bool CollationIsVisible ( Oid  collid)

Definition at line 1965 of file namespace.c.

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

Referenced by generate_collation_name(), and pg_collation_is_visible().

1966 {
1967  HeapTuple colltup;
1968  Form_pg_collation collform;
1969  Oid collnamespace;
1970  bool visible;
1971 
1972  colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
1973  if (!HeapTupleIsValid(colltup))
1974  elog(ERROR, "cache lookup failed for collation %u", collid);
1975  collform = (Form_pg_collation) GETSTRUCT(colltup);
1976 
1978 
1979  /*
1980  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1981  * the system namespace are surely in the path and so we needn't even do
1982  * list_member_oid() for them.
1983  */
1984  collnamespace = collform->collnamespace;
1985  if (collnamespace != PG_CATALOG_NAMESPACE &&
1986  !list_member_oid(activeSearchPath, collnamespace))
1987  visible = false;
1988  else
1989  {
1990  /*
1991  * If it is in the path, it might still not be visible; it could be
1992  * hidden by another conversion of the same name earlier in the path.
1993  * So we must do a slow check to see if this conversion would be found
1994  * by CollationGetCollid.
1995  */
1996  char *collname = NameStr(collform->collname);
1997 
1998  visible = (CollationGetCollid(collname) == collid);
1999  }
2000 
2001  ReleaseSysCache(colltup);
2002 
2003  return visible;
2004 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid CollationGetCollid(const char *collname)
Definition: namespace.c:1922
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1081
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:47
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
Oid ConversionGetConid ( const char *  conname)

Definition at line 2015 of file namespace.c.

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

Referenced by ConversionIsVisible().

2016 {
2017  Oid conid;
2018  ListCell *l;
2019 
2021 
2022  foreach(l, activeSearchPath)
2023  {
2024  Oid namespaceId = lfirst_oid(l);
2025 
2026  if (namespaceId == myTempNamespace)
2027  continue; /* do not look in temp namespace */
2028 
2029  conid = GetSysCacheOid2(CONNAMENSP,
2030  PointerGetDatum(conname),
2031  ObjectIdGetDatum(namespaceId));
2032  if (OidIsValid(conid))
2033  return conid;
2034  }
2035 
2036  /* Not found in path */
2037  return InvalidOid;
2038 }
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:178
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108
bool ConversionIsVisible ( Oid  conid)

Definition at line 2047 of file namespace.c.

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

Referenced by pg_conversion_is_visible().

2048 {
2049  HeapTuple contup;
2050  Form_pg_conversion conform;
2051  Oid connamespace;
2052  bool visible;
2053 
2054  contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
2055  if (!HeapTupleIsValid(contup))
2056  elog(ERROR, "cache lookup failed for conversion %u", conid);
2057  conform = (Form_pg_conversion) GETSTRUCT(contup);
2058 
2060 
2061  /*
2062  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2063  * the system namespace are surely in the path and so we needn't even do
2064  * list_member_oid() for them.
2065  */
2066  connamespace = conform->connamespace;
2067  if (connamespace != PG_CATALOG_NAMESPACE &&
2068  !list_member_oid(activeSearchPath, connamespace))
2069  visible = false;
2070  else
2071  {
2072  /*
2073  * If it is in the path, it might still not be visible; it could be
2074  * hidden by another conversion of the same name earlier in the path.
2075  * So we must do a slow check to see if this conversion would be found
2076  * by ConversionGetConid.
2077  */
2078  char *conname = NameStr(conform->conname);
2079 
2080  visible = (ConversionGetConid(conname) == conid);
2081  }
2082 
2083  ReleaseSysCache(contup);
2084 
2085  return visible;
2086 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
Oid ConversionGetConid(const char *conname)
Definition: namespace.c:2015
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1081
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:77
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3151 of file namespace.c.

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

Referenced by CopyCachedPlan().

3152 {
3153  OverrideSearchPath *result;
3154 
3155  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3156  result->schemas = list_copy(path->schemas);
3157  result->addCatalog = path->addCatalog;
3158  result->addTemp = path->addTemp;
3159 
3160  return result;
3161 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
void * palloc(Size size)
Definition: mcxt.c:849
void DeconstructQualifiedName ( List names,
char **  nspname_p,
char **  objname_p 
)

Definition at line 2603 of file namespace.c.

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

Referenced by FuncnameGetCandidates(), get_collation_oid(), get_conversion_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().

2606 {
2607  char *catalogname;
2608  char *schemaname = NULL;
2609  char *objname = NULL;
2610 
2611  switch (list_length(names))
2612  {
2613  case 1:
2614  objname = strVal(linitial(names));
2615  break;
2616  case 2:
2617  schemaname = strVal(linitial(names));
2618  objname = strVal(lsecond(names));
2619  break;
2620  case 3:
2621  catalogname = strVal(linitial(names));
2622  schemaname = strVal(lsecond(names));
2623  objname = strVal(lthird(names));
2624 
2625  /*
2626  * We check the catalog name and then ignore it.
2627  */
2628  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2629  ereport(ERROR,
2630  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2631  errmsg("cross-database references are not implemented: %s",
2632  NameListToString(names))));
2633  break;
2634  default:
2635  ereport(ERROR,
2636  (errcode(ERRCODE_SYNTAX_ERROR),
2637  errmsg("improper qualified name (too many dotted names): %s",
2638  NameListToString(names))));
2639  break;
2640  }
2641 
2642  *nspname_p = schemaname;
2643  *objname_p = objname;
2644 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
#define lsecond(l)
Definition: pg_list.h:114
#define linitial(l)
Definition: pg_list.h:110
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2048
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2897
Oid MyDatabaseId
Definition: globals.c:76
#define NULL
Definition: c.h:229
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:118
List* fetch_search_path ( bool  includeImplicit)

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

4019 {
4020  List *result;
4021 
4023 
4024  /*
4025  * If the temp namespace should be first, force it to exist. This is so
4026  * that callers can trust the result to reflect the actual default
4027  * creation namespace. It's a bit bogus to do this here, since
4028  * current_schema() is supposedly a stable function without side-effects,
4029  * but the alternatives seem worse.
4030  */
4032  {
4035  }
4036 
4037  result = list_copy(activeSearchPath);
4038  if (!includeImplicit)
4039  {
4040  while (result && linitial_oid(result) != activeCreationNamespace)
4041  result = list_delete_first(result);
4042  }
4043 
4044  return result;
4045 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool activeTempCreationPending
Definition: namespace.c:139
static void InitTempTableNamespace(void)
Definition: namespace.c:3629
#define linitial_oid(l)
Definition: pg_list.h:112
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:45
List * list_delete_first(List *list)
Definition: list.c:666
int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4058 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4059 {
4060  int count = 0;
4061  ListCell *l;
4062 
4064 
4065  foreach(l, activeSearchPath)
4066  {
4067  Oid namespaceId = lfirst_oid(l);
4068 
4069  if (namespaceId == myTempNamespace)
4070  continue; /* do not include temp namespace */
4071 
4072  if (count < sarray_len)
4073  sarray[count] = namespaceId;
4074  count++;
4075  }
4076 
4077  return count;
4078 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108
Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3452 of file namespace.c.

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

Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().

3453 {
3454  Oid proc;
3455  ListCell *l;
3456 
3458 
3459  foreach(l, activeSearchPath)
3460  {
3461  Oid namespaceId = lfirst_oid(l);
3462 
3463  if (namespaceId == myTempNamespace)
3464  continue; /* do not look in temp namespace */
3465 
3466  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3467  if (OidIsValid(proc))
3468  return proc;
3469  }
3470 
3471  /* Not found in path */
3472  return InvalidOid;
3473 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#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
FuncCandidateList FuncnameGetCandidates ( List names,
int  nargs,
List argnames,
bool  expand_variadic,
bool  expand_defaults,
bool  missing_ok 
)

Definition at line 902 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, NULL, _FuncCandidateList::nvargs, offsetof, _FuncCandidateList::oid, OidIsValid, catclist::ordered, palloc(), _FuncCandidateList::pathpos, pfree(), PROCNAMEARGSNSP, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, and catctup::tuple.

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

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

Definition at line 1373 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, PG_CATALOG_NAMESPACE, PROCOID, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.

Referenced by format_procedure_internal(), and pg_function_is_visible().

1374 {
1375  HeapTuple proctup;
1376  Form_pg_proc procform;
1377  Oid pronamespace;
1378  bool visible;
1379 
1380  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1381  if (!HeapTupleIsValid(proctup))
1382  elog(ERROR, "cache lookup failed for function %u", funcid);
1383  procform = (Form_pg_proc) GETSTRUCT(proctup);
1384 
1386 
1387  /*
1388  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1389  * the system namespace are surely in the path and so we needn't even do
1390  * list_member_oid() for them.
1391  */
1392  pronamespace = procform->pronamespace;
1393  if (pronamespace != PG_CATALOG_NAMESPACE &&
1394  !list_member_oid(activeSearchPath, pronamespace))
1395  visible = false;
1396  else
1397  {
1398  /*
1399  * If it is in the path, it might still not be visible; it could be
1400  * hidden by another proc of the same name and arguments earlier in
1401  * the path. So we must do a slow check to see if this is the same
1402  * proc that would be found by FuncnameGetCandidates.
1403  */
1404  char *proname = NameStr(procform->proname);
1405  int nargs = procform->pronargs;
1406  FuncCandidateList clist;
1407 
1408  visible = false;
1409 
1410  clist = FuncnameGetCandidates(list_make1(makeString(proname)),
1411  nargs, NIL, false, false, false);
1412 
1413  for (; clist; clist = clist->next)
1414  {
1415  if (memcmp(clist->args, procform->proargtypes.values,
1416  nargs * sizeof(Oid)) == 0)
1417  {
1418  /* Found the expected entry; is it the right proc? */
1419  visible = (clist->oid == funcid);
1420  break;
1421  }
1422  }
1423  }
1424 
1425  ReleaseSysCache(proctup);
1426 
1427  return visible;
1428 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:69
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define list_make1(x1)
Definition: pg_list.h:133
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:37
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:902
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
struct _FuncCandidateList * next
Definition: namespace.h:30
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1081
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
Oid get_collation_oid ( List name,
bool  missing_ok 
)

Definition at line 3324 of file namespace.c.

References COLLNAMEENCNSP, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetDatabaseEncoding(), GetDatabaseEncodingName(), GetSysCacheOid3, Int32GetDatum, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().

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

3325 {
3326  char *schemaname;
3327  char *collation_name;
3328  int32 dbencoding = GetDatabaseEncoding();
3329  Oid namespaceId;
3330  Oid colloid;
3331  ListCell *l;
3332 
3333  /* deconstruct the name list */
3334  DeconstructQualifiedName(name, &schemaname, &collation_name);
3335 
3336  if (schemaname)
3337  {
3338  /* use exact schema given */
3339  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3340  if (missing_ok && !OidIsValid(namespaceId))
3341  return InvalidOid;
3342 
3343  /* first try for encoding-specific entry, then any-encoding */
3344  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3345  PointerGetDatum(collation_name),
3346  Int32GetDatum(dbencoding),
3347  ObjectIdGetDatum(namespaceId));
3348  if (OidIsValid(colloid))
3349  return colloid;
3350  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3351  PointerGetDatum(collation_name),
3352  Int32GetDatum(-1),
3353  ObjectIdGetDatum(namespaceId));
3354  if (OidIsValid(colloid))
3355  return colloid;
3356  }
3357  else
3358  {
3359  /* search for it in search path */
3361 
3362  foreach(l, activeSearchPath)
3363  {
3364  namespaceId = lfirst_oid(l);
3365 
3366  if (namespaceId == myTempNamespace)
3367  continue; /* do not look in temp namespace */
3368 
3369  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3370  PointerGetDatum(collation_name),
3371  Int32GetDatum(dbencoding),
3372  ObjectIdGetDatum(namespaceId));
3373  if (OidIsValid(colloid))
3374  return colloid;
3375  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3376  PointerGetDatum(collation_name),
3377  Int32GetDatum(-1),
3378  ObjectIdGetDatum(namespaceId));
3379  if (OidIsValid(colloid))
3380  return colloid;
3381  }
3382  }
3383 
3384  /* Not found in path */
3385  if (!missing_ok)
3386  ereport(ERROR,
3387  (errcode(ERRCODE_UNDEFINED_OBJECT),
3388  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3390  return InvalidOid;
3391 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2687
#define PointerGetDatum(X)
Definition: postgres.h:562
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:2603
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:180
signed int int32
Definition: c.h:256
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2897
int GetDatabaseEncoding(void)
Definition: mbutils.c:1015
#define InvalidOid
Definition: postgres_ext.h:36
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1021
static List * activeSearchPath
Definition: namespace.c:133
#define Int32GetDatum(X)
Definition: postgres.h:485
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lfirst_oid(lc)
Definition: pg_list.h:108
Oid get_conversion_oid ( List name,
bool  missing_ok 
)

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

3398 {
3399  char *schemaname;
3400  char *conversion_name;
3401  Oid namespaceId;
3402  Oid conoid = InvalidOid;
3403  ListCell *l;
3404 
3405  /* deconstruct the name list */
3406  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3407 
3408  if (schemaname)
3409  {
3410  /* use exact schema given */
3411  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3412  if (missing_ok && !OidIsValid(namespaceId))
3413  conoid = InvalidOid;
3414  else
3415  conoid = GetSysCacheOid2(CONNAMENSP,
3416  PointerGetDatum(conversion_name),
3417  ObjectIdGetDatum(namespaceId));
3418  }
3419  else
3420  {
3421  /* search for it in search path */
3423 
3424  foreach(l, activeSearchPath)
3425  {
3426  namespaceId = lfirst_oid(l);
3427 
3428  if (namespaceId == myTempNamespace)
3429  continue; /* do not look in temp namespace */
3430 
3431  conoid = GetSysCacheOid2(CONNAMENSP,
3432  PointerGetDatum(conversion_name),
3433  ObjectIdGetDatum(namespaceId));
3434  if (OidIsValid(conoid))
3435  return conoid;
3436  }
3437  }
3438 
3439  /* Not found in path */
3440  if (!OidIsValid(conoid) && !missing_ok)
3441  ereport(ERROR,
3442  (errcode(ERRCODE_UNDEFINED_OBJECT),
3443  errmsg("conversion \"%s\" does not exist",
3444  NameListToString(name))));
3445  return conoid;
3446 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2687
#define PointerGetDatum(X)
Definition: postgres.h:562
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:2603
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:178
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2897
#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
Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

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

2840 {
2841  Oid oid;
2842 
2844  if (!OidIsValid(oid) && !missing_ok)
2845  ereport(ERROR,
2846  (errcode(ERRCODE_UNDEFINED_SCHEMA),
2847  errmsg("schema \"%s\" does not exist", nspname)));
2848 
2849  return oid;
2850 }
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid1(cacheId, key1)
Definition: syscache.h:176
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

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

2474 {
2475  char *schemaname;
2476  char *config_name;
2477  Oid namespaceId;
2478  Oid cfgoid = InvalidOid;
2479  ListCell *l;
2480 
2481  /* deconstruct the name list */
2482  DeconstructQualifiedName(names, &schemaname, &config_name);
2483 
2484  if (schemaname)
2485  {
2486  /* use exact schema given */
2487  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2488  if (missing_ok && !OidIsValid(namespaceId))
2489  cfgoid = InvalidOid;
2490  else
2492  PointerGetDatum(config_name),
2493  ObjectIdGetDatum(namespaceId));
2494  }
2495  else
2496  {
2497  /* search for it in search path */
2499 
2500  foreach(l, activeSearchPath)
2501  {
2502  namespaceId = lfirst_oid(l);
2503 
2504  if (namespaceId == myTempNamespace)
2505  continue; /* do not look in temp namespace */
2506 
2508  PointerGetDatum(config_name),
2509  ObjectIdGetDatum(namespaceId));
2510  if (OidIsValid(cfgoid))
2511  break;
2512  }
2513  }
2514 
2515  if (!OidIsValid(cfgoid) && !missing_ok)
2516  ereport(ERROR,
2517  (errcode(ERRCODE_UNDEFINED_OBJECT),
2518  errmsg("text search configuration \"%s\" does not exist",
2519  NameListToString(names))));
2520 
2521  return cfgoid;
2522 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2687
#define PointerGetDatum(X)
Definition: postgres.h:562
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:2603
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:178
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2897
#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
Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

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

2221 {
2222  char *schemaname;
2223  char *dict_name;
2224  Oid namespaceId;
2225  Oid dictoid = InvalidOid;
2226  ListCell *l;
2227 
2228  /* deconstruct the name list */
2229  DeconstructQualifiedName(names, &schemaname, &dict_name);
2230 
2231  if (schemaname)
2232  {
2233  /* use exact schema given */
2234  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2235  if (missing_ok && !OidIsValid(namespaceId))
2236  dictoid = InvalidOid;
2237  else
2238  dictoid = GetSysCacheOid2(TSDICTNAMENSP,
2239  PointerGetDatum(dict_name),
2240  ObjectIdGetDatum(namespaceId));
2241  }
2242  else
2243  {
2244  /* search for it in search path */
2246 
2247  foreach(l, activeSearchPath)
2248  {
2249  namespaceId = lfirst_oid(l);
2250 
2251  if (namespaceId == myTempNamespace)
2252  continue; /* do not look in temp namespace */
2253 
2254  dictoid = GetSysCacheOid2(TSDICTNAMENSP,
2255  PointerGetDatum(dict_name),
2256  ObjectIdGetDatum(namespaceId));
2257  if (OidIsValid(dictoid))
2258  break;
2259  }
2260  }
2261 
2262  if (!OidIsValid(dictoid) && !missing_ok)
2263  ereport(ERROR,
2264  (errcode(ERRCODE_UNDEFINED_OBJECT),
2265  errmsg("text search dictionary \"%s\" does not exist",
2266  NameListToString(names))));
2267 
2268  return dictoid;
2269 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2687
#define PointerGetDatum(X)
Definition: postgres.h:562
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:2603
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:178
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2897
#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
Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

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

2095 {
2096  char *schemaname;
2097  char *parser_name;
2098  Oid namespaceId;
2099  Oid prsoid = InvalidOid;
2100  ListCell *l;
2101 
2102  /* deconstruct the name list */
2103  DeconstructQualifiedName(names, &schemaname, &parser_name);
2104 
2105  if (schemaname)
2106  {
2107  /* use exact schema given */
2108  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2109  if (missing_ok && !OidIsValid(namespaceId))
2110  prsoid = InvalidOid;
2111  else
2113  PointerGetDatum(parser_name),
2114  ObjectIdGetDatum(namespaceId));
2115  }
2116  else
2117  {
2118  /* search for it in search path */
2120 
2121  foreach(l, activeSearchPath)
2122  {
2123  namespaceId = lfirst_oid(l);
2124 
2125  if (namespaceId == myTempNamespace)
2126  continue; /* do not look in temp namespace */
2127 
2129  PointerGetDatum(parser_name),
2130  ObjectIdGetDatum(namespaceId));
2131  if (OidIsValid(prsoid))
2132  break;
2133  }
2134  }
2135 
2136  if (!OidIsValid(prsoid) && !missing_ok)
2137  ereport(ERROR,
2138  (errcode(ERRCODE_UNDEFINED_OBJECT),
2139  errmsg("text search parser \"%s\" does not exist",
2140  NameListToString(names))));
2141 
2142  return prsoid;
2143 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2687
#define PointerGetDatum(X)
Definition: postgres.h:562
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:2603
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:178
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2897
#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
Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

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

2348 {
2349  char *schemaname;
2350  char *template_name;
2351  Oid namespaceId;
2352  Oid tmploid = InvalidOid;
2353  ListCell *l;
2354 
2355  /* deconstruct the name list */
2356  DeconstructQualifiedName(names, &schemaname, &template_name);
2357 
2358  if (schemaname)
2359  {
2360  /* use exact schema given */
2361  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2362  if (missing_ok && !OidIsValid(namespaceId))
2363  tmploid = InvalidOid;
2364  else
2366  PointerGetDatum(template_name),
2367  ObjectIdGetDatum(namespaceId));
2368  }
2369  else
2370  {
2371  /* search for it in search path */
2373 
2374  foreach(l, activeSearchPath)
2375  {
2376  namespaceId = lfirst_oid(l);
2377 
2378  if (namespaceId == myTempNamespace)
2379  continue; /* do not look in temp namespace */
2380 
2382  PointerGetDatum(template_name),
2383  ObjectIdGetDatum(namespaceId));
2384  if (OidIsValid(tmploid))
2385  break;
2386  }
2387  }
2388 
2389  if (!OidIsValid(tmploid) && !missing_ok)
2390  ereport(ERROR,
2391  (errcode(ERRCODE_UNDEFINED_OBJECT),
2392  errmsg("text search template \"%s\" does not exist",
2393  NameListToString(names))));
2394 
2395  return tmploid;
2396 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2687
#define PointerGetDatum(X)
Definition: postgres.h:562
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:2603
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:178
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2897
#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
OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3115 of file namespace.c.

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

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

3116 {
3117  OverrideSearchPath *result;
3118  List *schemas;
3119  MemoryContext oldcxt;
3120 
3122 
3123  oldcxt = MemoryContextSwitchTo(context);
3124 
3125  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3126  schemas = list_copy(activeSearchPath);
3127  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3128  {
3129  if (linitial_oid(schemas) == myTempNamespace)
3130  result->addTemp = true;
3131  else
3132  {
3134  result->addCatalog = true;
3135  }
3136  schemas = list_delete_first(schemas);
3137  }
3138  result->schemas = schemas;
3139 
3140  MemoryContextSwitchTo(oldcxt);
3141 
3142  return result;
3143 }
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:3479
static Oid activeCreationNamespace
Definition: namespace.c:136
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
void * palloc0(Size size)
Definition: mcxt.c:878
#define Assert(condition)
Definition: c.h:675
#define linitial_oid(l)
Definition: pg_list.h:112
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:45
List * list_delete_first(List *list)
Definition: list.c:666
int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3029 of file namespace.c.

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

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

3030 {
3031  int result;
3032  char *nspname;
3033 
3034  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3035  nspname = get_namespace_name(namespaceId);
3036  if (!nspname)
3037  return InvalidBackendId; /* no such namespace? */
3038  if (strncmp(nspname, "pg_temp_", 8) == 0)
3039  result = atoi(nspname + 8);
3040  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3041  result = atoi(nspname + 14);
3042  else
3043  result = InvalidBackendId;
3044  pfree(nspname);
3045  return result;
3046 }
void pfree(void *pointer)
Definition: mcxt.c:950
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
#define InvalidBackendId
Definition: backendid.h:23
void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3068 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3069 {
3070  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3071  *tempNamespaceId = myTempNamespace;
3072  *tempToastNamespaceId = myTempToastNamespace;
3073 }
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
Oid GetTempToastNamespace ( void  )

Definition at line 3054 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3055 {
3057  return myTempToastNamespace;
3058 }
static Oid myTempToastNamespace
Definition: namespace.c:182
#define OidIsValid(objectId)
Definition: c.h:538
#define Assert(condition)
Definition: c.h:675
void InitializeSearchPath ( void  )

Definition at line 3960 of file namespace.c.

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

Referenced by InitPostgres().

3961 {
3963  {
3964  /*
3965  * In bootstrap mode, the search path must be 'pg_catalog' so that
3966  * tables are created in the proper namespace; ignore the GUC setting.
3967  */
3968  MemoryContext oldcxt;
3969 
3972  MemoryContextSwitchTo(oldcxt);
3974  baseTempCreationPending = false;
3975  baseSearchPathValid = true;
3980  }
3981  else
3982  {
3983  /*
3984  * In normal mode, arrange for a callback on any syscache invalidation
3985  * of pg_namespace rows.
3986  */
3989  (Datum) 0);
3990  /* Force search path to be recomputed on next use */
3991  baseSearchPathValid = false;
3992  }
3993 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid GetUserId(void)
Definition: miscinit.c:283
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
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4000
static bool activeTempCreationPending
Definition: namespace.c:139
MemoryContext TopMemoryContext
Definition: mcxt.c:43
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:1381
uintptr_t Datum
Definition: postgres.h:372
#define list_make1_oid(x1)
Definition: pg_list.h:145
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
static List * activeSearchPath
Definition: namespace.c:133
static void InitTempTableNamespace ( void  )
static

Definition at line 3629 of file namespace.c.

References ACL_CREATE_TEMP, ACLCHECK_OK, Assert, AssertState, baseSearchPathValid, BOOTSTRAP_SUPERUSERID, 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().

3630 {
3631  char namespaceName[NAMEDATALEN];
3632  Oid namespaceId;
3633  Oid toastspaceId;
3634 
3636 
3637  /*
3638  * First, do permission check to see if we are authorized to make temp
3639  * tables. We use a nonstandard error message here since "databasename:
3640  * permission denied" might be a tad cryptic.
3641  *
3642  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
3643  * that's necessary since current user ID could change during the session.
3644  * But there's no need to make the namespace in the first place until a
3645  * temp table creation request is made by someone with appropriate rights.
3646  */
3649  ereport(ERROR,
3650  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3651  errmsg("permission denied to create temporary tables in database \"%s\"",
3653 
3654  /*
3655  * Do not allow a Hot Standby slave session to make temp tables. Aside
3656  * from problems with modifying the system catalogs, there is a naming
3657  * conflict: pg_temp_N belongs to the session with BackendId N on the
3658  * master, not to a slave session with the same BackendId. We should not
3659  * be able to get here anyway due to XactReadOnly checks, but let's just
3660  * make real sure. Note that this also backstops various operations that
3661  * allow XactReadOnly transactions to modify temp tables; they'd need
3662  * RecoveryInProgress checks if not for this.
3663  */
3664  if (RecoveryInProgress())
3665  ereport(ERROR,
3666  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3667  errmsg("cannot create temporary tables during recovery")));
3668 
3669  /* Parallel workers can't create temporary tables, either. */
3670  if (IsParallelWorker())
3671  ereport(ERROR,
3672  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3673  errmsg("cannot create temporary tables in parallel mode")));
3674 
3675  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
3676 
3677  namespaceId = get_namespace_oid(namespaceName, true);
3678  if (!OidIsValid(namespaceId))
3679  {
3680  /*
3681  * First use of this temp namespace in this database; create it. The
3682  * temp namespaces are always owned by the superuser. We leave their
3683  * permissions at default --- i.e., no access except to superuser ---
3684  * to ensure that unprivileged users can't peek at other backends'
3685  * temp tables. This works because the places that access the temp
3686  * namespace for my own backend skip permissions checks on it.
3687  */
3688  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3689  true);
3690  /* Advance command counter to make namespace visible */
3692  }
3693  else
3694  {
3695  /*
3696  * If the namespace already exists, clean it out (in case the former
3697  * owner crashed without doing so).
3698  */
3699  RemoveTempRelations(namespaceId);
3700  }
3701 
3702  /*
3703  * If the corresponding toast-table namespace doesn't exist yet, create
3704  * it. (We assume there is no need to clean it out if it does exist, since
3705  * dropping a parent table should make its toast table go away.)
3706  */
3707  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
3708  MyBackendId);
3709 
3710  toastspaceId = get_namespace_oid(namespaceName, true);
3711  if (!OidIsValid(toastspaceId))
3712  {
3713  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3714  true);
3715  /* Advance command counter to make namespace visible */
3717  }
3718 
3719  /*
3720  * Okay, we've prepared the temp namespace ... but it's not committed yet,
3721  * so all our work could be undone by transaction rollback. Set flag for
3722  * AtEOXact_Namespace to know what to do.
3723  */
3724  myTempNamespace = namespaceId;
3725  myTempToastNamespace = toastspaceId;
3726 
3727  /* It should not be done already. */
3730 
3731  baseSearchPathValid = false; /* need to rebuild list */
3732 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2839
BackendId MyBackendId
Definition: globals.c:72
#define AssertState(condition)
Definition: c.h:678
Oid GetUserId(void)
Definition: miscinit.c:283
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:7855
#define OidIsValid(objectId)
Definition: c.h:538
#define NAMEDATALEN
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2048
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
#define ereport(elevel, rest)
Definition: elog.h:122
#define IsParallelWorker()
Definition: parallel.h:53
void CommandCounterIncrement(void)
Definition: xact.c:922
Oid MyDatabaseId
Definition: globals.c:76
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4408
#define Assert(condition)
Definition: c.h:675
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:649
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:3853
#define BOOTSTRAP_SUPERUSERID
Definition: pg_authid.h:104
#define InvalidSubTransactionId
Definition: c.h:403
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ACL_CREATE_TEMP
Definition: parsenodes.h:76
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
Definition: pg_namespace.c:41
bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 2990 of file namespace.c.

References get_namespace_name(), and pfree().

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

2991 {
2992  bool result;
2993  char *nspname;
2994 
2995  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
2996  nspname = get_namespace_name(namespaceId);
2997  if (!nspname)
2998  return false; /* no such namespace? */
2999  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3000  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3001  pfree(nspname);
3002  return result;
3003 }
void pfree(void *pointer)
Definition: mcxt.c:950
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3013 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

3014 {
3015  /* If it's my own temp namespace, say "false" */
3016  if (isTempOrTempToastNamespace(namespaceId))
3017  return false;
3018  /* Else, if it's any temp namespace, say "true" */
3019  return isAnyTempNamespace(namespaceId);
3020 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:2976
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:2990
bool isTempNamespace ( Oid  namespaceId)

Definition at line 2952 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

2953 {
2954  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
2955  return true;
2956  return false;
2957 }
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:538
bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 2976 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

2977 {
2978  if (OidIsValid(myTempNamespace) &&
2979  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
2980  return true;
2981  return false;
2982 }
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:538
bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 2964 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

2965 {
2966  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
2967  return true;
2968  return false;
2969 }
static Oid myTempToastNamespace
Definition: namespace.c:182
#define OidIsValid(objectId)
Definition: c.h:538
Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2730 of file namespace.c.

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

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

2731 {
2732  Oid namespaceId;
2733  AclResult aclresult;
2734 
2735  /* check for pg_temp alias */
2736  if (strcmp(nspname, "pg_temp") == 0)
2737  {
2738  /* Initialize temp namespace if first time through */
2741  return myTempNamespace;
2742  }
2743 
2744  namespaceId = get_namespace_oid(nspname, false);
2745 
2746  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2747  if (aclresult != ACLCHECK_OK)
2749  nspname);
2750 
2751  return namespaceId;
2752 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2839
Oid GetUserId(void)
Definition: miscinit.c:283
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4458
#define ACL_CREATE
Definition: parsenodes.h:75
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3377
static void InitTempTableNamespace(void)
Definition: namespace.c:3629
AclResult
Definition: acl.h:170
Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2687 of file namespace.c.

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

Referenced by AfterTriggerSetState(), FuncnameGetCandidates(), get_collation_oid(), get_conversion_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), logicalrep_typmap_getid(), 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().

2688 {
2689  Oid namespaceId;
2690  AclResult aclresult;
2691 
2692  /* check for pg_temp alias */
2693  if (strcmp(nspname, "pg_temp") == 0)
2694  {
2696  return myTempNamespace;
2697 
2698  /*
2699  * Since this is used only for looking up existing objects, there is
2700  * no point in trying to initialize the temp namespace here; and doing
2701  * so might create problems for some callers --- just fall through.
2702  */
2703  }
2704 
2705  namespaceId = get_namespace_oid(nspname, missing_ok);
2706  if (missing_ok && !OidIsValid(namespaceId))
2707  return InvalidOid;
2708 
2709  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
2710  if (aclresult != ACLCHECK_OK)
2712  nspname);
2713  /* Schema search hook for this lookup */
2714  InvokeNamespaceSearchHook(namespaceId, true);
2715 
2716  return namespaceId;
2717 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2839
Oid GetUserId(void)
Definition: miscinit.c:283
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4458
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:174
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3377
#define ACL_USAGE
Definition: parsenodes.h:73
AclResult
Definition: acl.h:170
#define InvalidOid
Definition: postgres_ext.h:36
Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2657 of file namespace.c.

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

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

2658 {
2659  /* check for pg_temp alias */
2660  if (strcmp(nspname, "pg_temp") == 0)
2661  {
2663  {
2665  return myTempNamespace;
2666  }
2667 
2668  /*
2669  * Since this is used only for looking up existing objects, there is
2670  * no point in trying to initialize the temp namespace here; and doing
2671  * so might create problems for some callers. Just report "not found".
2672  */
2673  return InvalidOid;
2674  }
2675 
2676  return get_namespace_oid(nspname, true);
2677 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2839
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:538
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:174
#define InvalidOid
Definition: postgres_ext.h:36
RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 2857 of file namespace.c.

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

Referenced by bt_metap(), bt_page_items(), bt_page_stats(), convert_table_name(), currtid_byrelname(), 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().

2858 {
2859  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
2860 
2861  switch (list_length(names))
2862  {
2863  case 1:
2864  rel->relname = strVal(linitial(names));
2865  break;
2866  case 2:
2867  rel->schemaname = strVal(linitial(names));
2868  rel->relname = strVal(lsecond(names));
2869  break;
2870  case 3:
2871  rel->catalogname = strVal(linitial(names));
2872  rel->schemaname = strVal(lsecond(names));
2873  rel->relname = strVal(lthird(names));
2874  break;
2875  default:
2876  ereport(ERROR,
2877  (errcode(ERRCODE_SYNTAX_ERROR),
2878  errmsg("improper relation name (too many dotted names): %s",
2879  NameListToString(names))));
2880  break;
2881  }
2882 
2883  return rel;
2884 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
#define lsecond(l)
Definition: pg_list.h:114
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
#define linitial(l)
Definition: pg_list.h:110
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2897
#define NULL
Definition: c.h:229
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:118
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:419
char * catalogname
Definition: primnodes.h:66
static bool MatchNamedCall ( HeapTuple  proctup,
int  nargs,
List argnames,
int **  argnumbers 
)
static

Definition at line 1265 of file namespace.c.

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

Referenced by FuncnameGetCandidates().

1267 {
1268  Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
1269  int pronargs = procform->pronargs;
1270  int numposargs = nargs - list_length(argnames);
1271  int pronallargs;
1272  Oid *p_argtypes;
1273  char **p_argnames;
1274  char *p_argmodes;
1275  bool arggiven[FUNC_MAX_ARGS];
1276  bool isnull;
1277  int ap; /* call args position */
1278  int pp; /* proargs position */
1279  ListCell *lc;
1280 
1281  Assert(argnames != NIL);
1282  Assert(numposargs >= 0);
1283  Assert(nargs <= pronargs);
1284 
1285  /* Ignore this function if its proargnames is null */
1287  &isnull);
1288  if (isnull)
1289  return false;
1290 
1291  /* OK, let's extract the argument names and types */
1292  pronallargs = get_func_arg_info(proctup,
1293  &p_argtypes, &p_argnames, &p_argmodes);
1294  Assert(p_argnames != NULL);
1295 
1296  /* initialize state for matching */
1297  *argnumbers = (int *) palloc(pronargs * sizeof(int));
1298  memset(arggiven, false, pronargs * sizeof(bool));
1299 
1300  /* there are numposargs positional args before the named args */
1301  for (ap = 0; ap < numposargs; ap++)
1302  {
1303  (*argnumbers)[ap] = ap;
1304  arggiven[ap] = true;
1305  }
1306 
1307  /* now examine the named args */
1308  foreach(lc, argnames)
1309  {
1310  char *argname = (char *) lfirst(lc);
1311  bool found;
1312  int i;
1313 
1314  pp = 0;
1315  found = false;
1316  for (i = 0; i < pronallargs; i++)
1317  {
1318  /* consider only input parameters */
1319  if (p_argmodes &&
1320  (p_argmodes[i] != FUNC_PARAM_IN &&
1321  p_argmodes[i] != FUNC_PARAM_INOUT &&
1322  p_argmodes[i] != FUNC_PARAM_VARIADIC))
1323  continue;
1324  if (p_argnames[i] && strcmp(p_argnames[i], argname) == 0)
1325  {
1326  /* fail if argname matches a positional argument */
1327  if (arggiven[pp])
1328  return false;
1329  arggiven[pp] = true;
1330  (*argnumbers)[ap] = pp;
1331  found = true;
1332  break;
1333  }
1334  /* increase pp only for input parameters */
1335  pp++;
1336  }
1337  /* if name isn't in proargnames, fail */
1338  if (!found)
1339  return false;
1340  ap++;
1341  }
1342 
1343  Assert(ap == nargs); /* processed all actual parameters */
1344 
1345  /* Check for default arguments */
1346  if (nargs < pronargs)
1347  {
1348  int first_arg_with_default = pronargs - procform->pronargdefaults;
1349 
1350  for (pp = numposargs; pp < pronargs; pp++)
1351  {
1352  if (arggiven[pp])
1353  continue;
1354  /* fail if arg not given and no default available */
1355  if (pp < first_arg_with_default)
1356  return false;
1357  (*argnumbers)[ap++] = pp;
1358  }
1359  }
1360 
1361  Assert(ap == pronargs); /* processed all function parameters */
1362 
1363  return true;
1364 }
#define NIL
Definition: pg_list.h:69
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition: funcapi.c:791
unsigned int Oid
Definition: postgres_ext.h:31
#define FUNC_MAX_ARGS
#define Anum_pg_proc_proargnames
Definition: pg_proc.h:112
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1243
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#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:849
int i
char* NameListToQuotedString ( List names)

Definition at line 2931 of file namespace.c.

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

2932 {
2934  ListCell *l;
2935 
2936  initStringInfo(&string);
2937 
2938  foreach(l, names)
2939  {
2940  if (l != list_head(names))
2941  appendStringInfoChar(&string, '.');
2943  }
2944 
2945  return string.data;
2946 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10114
#define strVal(v)
Definition: value.h:54
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
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:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define lfirst(lc)
Definition: pg_list.h:106
char* NameListToString ( List names)

Definition at line 2897 of file namespace.c.

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

Referenced by AggregateCreate(), 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_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), lookup_fdw_handler_func(), lookup_index_am_handler_func(), LookupAggWithArgs(), LookupFuncName(), 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().

2898 {
2900  ListCell *l;
2901 
2902  initStringInfo(&string);
2903 
2904  foreach(l, names)
2905  {
2906  Node *name = (Node *) lfirst(l);
2907 
2908  if (l != list_head(names))
2909  appendStringInfoChar(&string, '.');
2910 
2911  if (IsA(name, String))
2912  appendStringInfoString(&string, strVal(name));
2913  else if (IsA(name, A_Star))
2914  appendStringInfoChar(&string, '*');
2915  else
2916  elog(ERROR, "unexpected node type in name list: %d",
2917  (int) nodeTag(name));
2918  }
2919 
2920  return string.data;
2921 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:569
Definition: nodes.h:518
#define strVal(v)
Definition: value.h:54
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
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:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define lfirst(lc)
Definition: pg_list.h:106
const char * name
Definition: encode.c:521
#define nodeTag(nodeptr)
Definition: nodes.h:523
#define elog
Definition: elog.h:219
static void NamespaceCallback ( Datum  arg,
int  cacheid,
uint32  hashvalue 
)
static

Definition at line 4000 of file namespace.c.

References baseSearchPathValid.

Referenced by InitializeSearchPath().

4001 {
4002  /* Force search path to be recomputed on next use */
4003  baseSearchPathValid = false;
4004 }
static bool baseSearchPathValid
Definition: namespace.c:152
bool OpclassIsVisible ( Oid  opcid)

Definition at line 1792 of file namespace.c.

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

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

1793 {
1794  HeapTuple opctup;
1795  Form_pg_opclass opcform;
1796  Oid opcnamespace;
1797  bool visible;
1798 
1799  opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
1800  if (!HeapTupleIsValid(opctup))
1801  elog(ERROR, "cache lookup failed for opclass %u", opcid);
1802  opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1803 
1805 
1806  /*
1807  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1808  * the system namespace are surely in the path and so we needn't even do
1809  * list_member_oid() for them.
1810  */
1811  opcnamespace = opcform->opcnamespace;
1812  if (opcnamespace != PG_CATALOG_NAMESPACE &&
1813  !list_member_oid(activeSearchPath, opcnamespace))
1814  visible = false;
1815  else
1816  {
1817  /*
1818  * If it is in the path, it might still not be visible; it could be
1819  * hidden by another opclass of the same name earlier in the path. So
1820  * we must do a slow check to see if this opclass would be found by
1821  * OpclassnameGetOpcid.
1822  */
1823  char *opcname = NameStr(opcform->opcname);
1824 
1825  visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1826  }
1827 
1828  ReleaseSysCache(opctup);
1829 
1830  return visible;
1831 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
unsigned int Oid
Definition: postgres_ext.h:31
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
Definition: namespace.c:1759
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1081
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:68
Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1759 of file namespace.c.

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

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

1760 {
1761  Oid opcid;
1762  ListCell *l;
1763 
1765 
1766  foreach(l, activeSearchPath)
1767  {
1768  Oid namespaceId = lfirst_oid(l);
1769 
1770  if (namespaceId == myTempNamespace)
1771  continue; /* do not look in temp namespace */
1772 
1773  opcid = GetSysCacheOid3(CLAAMNAMENSP,
1774  ObjectIdGetDatum(amid),
1775  PointerGetDatum(opcname),
1776  ObjectIdGetDatum(namespaceId));
1777  if (OidIsValid(opcid))
1778  return opcid;
1779  }
1780 
1781  /* Not found in path */
1782  return InvalidOid;
1783 }
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:180
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108
bool OperatorIsVisible ( Oid  oprid)

Definition at line 1706 of file namespace.c.

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

Referenced by format_operator_internal(), and pg_operator_is_visible().

1707 {
1708  HeapTuple oprtup;
1709  Form_pg_operator oprform;
1710  Oid oprnamespace;
1711  bool visible;
1712 
1714  if (!HeapTupleIsValid(oprtup))
1715  elog(ERROR, "cache lookup failed for operator %u", oprid);
1716  oprform = (Form_pg_operator) GETSTRUCT(oprtup);
1717 
1719 
1720  /*
1721  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1722  * the system namespace are surely in the path and so we needn't even do
1723  * list_member_oid() for them.
1724  */
1725  oprnamespace = oprform->oprnamespace;
1726  if (oprnamespace != PG_CATALOG_NAMESPACE &&
1727  !list_member_oid(activeSearchPath, oprnamespace))
1728  visible = false;
1729  else
1730  {
1731  /*
1732  * If it is in the path, it might still not be visible; it could be
1733  * hidden by another operator of the same name and arguments earlier
1734  * in the path. So we must do a slow check to see if this is the same
1735  * operator that would be found by OpernameGetOprid.
1736  */
1737  char *oprname = NameStr(oprform->oprname);
1738 
1739  visible = (OpernameGetOprid(list_make1(makeString(oprname)),
1740  oprform->oprleft, oprform->oprright)
1741  == oprid);
1742  }
1743 
1744  ReleaseSysCache(oprtup);
1745 
1746  return visible;
1747 }
Value * makeString(char *str)
Definition: value.c:53
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid oprid(Operator op)
Definition: parse_oper.c:245
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define list_make1(x1)
Definition: pg_list.h:133
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1444
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1081
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_operator* Form_pg_operator
Definition: pg_operator.h:57
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
FuncCandidateList OpernameGetCandidates ( List names,
char  oprkind,
bool  missing_schema_ok 
)

Definition at line 1546 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, NULL, _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().

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

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

1445 {
1446  char *schemaname;
1447  char *opername;
1448  CatCList *catlist;
1449  ListCell *l;
1450 
1451  /* deconstruct the name list */
1452  DeconstructQualifiedName(names, &schemaname, &opername);
1453 
1454  if (schemaname)
1455  {
1456  /* search only in exact schema given */
1457  Oid namespaceId;
1458 
1459  namespaceId = LookupExplicitNamespace(schemaname, true);
1460  if (OidIsValid(namespaceId))
1461  {
1462  HeapTuple opertup;
1463 
1464  opertup = SearchSysCache4(OPERNAMENSP,
1465  CStringGetDatum(opername),
1466  ObjectIdGetDatum(oprleft),
1467  ObjectIdGetDatum(oprright),
1468  ObjectIdGetDatum(namespaceId));
1469  if (HeapTupleIsValid(opertup))
1470  {
1471  Oid result = HeapTupleGetOid(opertup);
1472 
1473  ReleaseSysCache(opertup);
1474  return result;
1475  }
1476  }
1477 
1478  return InvalidOid;
1479  }
1480 
1481  /* Search syscache by name and argument types */
1482  catlist = SearchSysCacheList3(OPERNAMENSP,
1483  CStringGetDatum(opername),
1484  ObjectIdGetDatum(oprleft),
1485  ObjectIdGetDatum(oprright));
1486 
1487  if (catlist->n_members == 0)
1488  {
1489  /* no hope, fall out early */
1490  ReleaseSysCacheList(catlist);
1491  return InvalidOid;
1492  }
1493 
1494  /*
1495  * We have to find the list member that is first in the search path, if
1496  * there's more than one. This doubly-nested loop looks ugly, but in
1497  * practice there should usually be few catlist members.
1498  */
1500 
1501  foreach(l, activeSearchPath)
1502  {
1503  Oid namespaceId = lfirst_oid(l);
1504  int i;
1505 
1506  if (namespaceId == myTempNamespace)
1507  continue; /* do not look in temp namespace */
1508 
1509  for (i = 0; i < catlist->n_members; i++)
1510  {
1511  HeapTuple opertup = &catlist->members[i]->tuple;
1512  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1513 
1514  if (operform->oprnamespace == namespaceId)
1515  {
1516  Oid result = HeapTupleGetOid(opertup);
1517 
1518  ReleaseSysCacheList(catlist);
1519  return result;
1520  }
1521  }
1522  }
1523 
1524  ReleaseSysCacheList(catlist);
1525  return InvalidOid;
1526 }
int n_members
Definition: catcache.h:154
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2687
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SearchSysCache4(cacheId, key1, key2, key3, key4)
Definition: syscache.h:155
static Oid myTempNamespace
Definition: namespace.c:180
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2603
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:155
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ReleaseSysCacheList(x)
Definition: syscache.h:203
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1081
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_operator* Form_pg_operator
Definition: pg_operator.h:57
static List * activeSearchPath
Definition: namespace.c:133
#define SearchSysCacheList3(cacheId, key1, key2, key3)
Definition: syscache.h:198
int i
HeapTupleData tuple
Definition: catcache.h:116
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
#define lfirst_oid(lc)
Definition: pg_list.h:108
bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1875 of file namespace.c.

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

1876 {
1877  HeapTuple opftup;
1878  Form_pg_opfamily opfform;
1879  Oid opfnamespace;
1880  bool visible;
1881 
1882  opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
1883  if (!HeapTupleIsValid(opftup))
1884  elog(ERROR, "cache lookup failed for opfamily %u", opfid);
1885  opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
1886 
1888 
1889  /*
1890  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1891  * the system namespace are surely in the path and so we needn't even do
1892  * list_member_oid() for them.
1893  */
1894  opfnamespace = opfform->opfnamespace;
1895  if (opfnamespace != PG_CATALOG_NAMESPACE &&
1896  !list_member_oid(activeSearchPath, opfnamespace))
1897  visible = false;
1898  else
1899  {
1900  /*
1901  * If it is in the path, it might still not be visible; it could be
1902  * hidden by another opfamily of the same name earlier in the path. So
1903  * we must do a slow check to see if this opfamily would be found by
1904  * OpfamilynameGetOpfid.
1905  */
1906  char *opfname = NameStr(opfform->opfname);
1907 
1908  visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
1909  }
1910 
1911  ReleaseSysCache(opftup);
1912 
1913  return visible;
1914 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
Definition: namespace.c:1842
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:44
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1081
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static List * activeSearchPath
Definition: namespace.c:133
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1842 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

1843 {
1844  Oid opfid;
1845  ListCell *l;
1846 
1848 
1849  foreach(l, activeSearchPath)
1850  {
1851  Oid namespaceId = lfirst_oid(l);
1852 
1853  if (namespaceId == myTempNamespace)
1854  continue; /* do not look in temp namespace */
1855 
1857  ObjectIdGetDatum(amid),
1858  PointerGetDatum(opfname),
1859  ObjectIdGetDatum(namespaceId));
1860  if (OidIsValid(opfid))
1861  return opfid;
1862  }
1863 
1864  /* Not found in path */
1865  return InvalidOid;
1866 }
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:180
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:133
#define lfirst_oid(lc)
Definition: pg_list.h:108
bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3167 of file namespace.c.

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

Referenced by RevalidateCachedQuery().

3168 {
3169  ListCell *lc,
3170  *lcp;
3171 
3173 
3174  /* We scan down the activeSearchPath to see if it matches the input. */
3176 
3177  /* If path->addTemp, first item should be my temp namespace. */
3178  if (path->addTemp)
3179  {
3180  if (lc && lfirst_oid(lc) == myTempNamespace)
3181  lc = lnext(lc);
3182  else
3183  return false;
3184  }
3185  /* If path->addCatalog, next item should be pg_catalog. */
3186  if (path->addCatalog)
3187  {
3188  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3189  lc = lnext(lc);
3190  else
3191  return false;
3192  }
3193  /* We should now be looking at the activeCreationNamespace. */
3194  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3195  return false;
3196  /* The remainder of activeSearchPath should match path->schemas. */
3197  foreach(lcp, path->schemas)
3198  {
3199  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3200  lc = lnext(lc);
3201  else
3202  return false;
3203  }
3204  if (lc)
3205  return false;
3206  return true;
3207 }
static Oid myTempNamespace
Definition: namespace.c:180
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
static Oid activeCreationNamespace
Definition: namespace.c:136
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
#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
Datum pg_collation_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4161 of file namespace.c.

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

4162 {
4163  Oid oid = PG_GETARG_OID(0);
4164 
4166  PG_RETURN_NULL();
4167 
4169 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
bool CollationIsVisible(Oid collid)
Definition: namespace.c:1965
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_conversion_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4172 of file namespace.c.

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

4173 {
4174  Oid oid = PG_GETARG_OID(0);
4175 
4177  PG_RETURN_NULL();
4178 
4180 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
bool ConversionIsVisible(Oid conid)
Definition: namespace.c:2047
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4117 of file namespace.c.

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

4118 {
4119  Oid oid = PG_GETARG_OID(0);
4120 
4122  PG_RETURN_NULL();
4123 
4125 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1373
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_is_other_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4233 of file namespace.c.

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

4234 {
4235  Oid oid = PG_GETARG_OID(0);
4236 
4238 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
bool isOtherTempNamespace(Oid namespaceId)
Definition: namespace.c:3013
Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4227 of file namespace.c.

References myTempNamespace, and PG_RETURN_OID.

4228 {
4230 }
static Oid myTempNamespace
Definition: namespace.c:180
#define PG_RETURN_OID(x)
Definition: fmgr.h:312
Datum pg_opclass_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4139 of file namespace.c.

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

4140 {
4141  Oid oid = PG_GETARG_OID(0);
4142 
4144  PG_RETURN_NULL();
4145 
4147 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
bool OpclassIsVisible(Oid opcid)
Definition: namespace.c:1792
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4128 of file namespace.c.

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

4129 {
4130  Oid oid = PG_GETARG_OID(0);
4131 
4133  PG_RETURN_NULL();
4134 
4136 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1706
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_opfamily_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4150 of file namespace.c.

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

4151 {
4152  Oid oid = PG_GETARG_OID(0);
4153 
4155  PG_RETURN_NULL();
4156 
4158 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
bool OpfamilyIsVisible(Oid opfid)
Definition: namespace.c:1875
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_table_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4095 of file namespace.c.

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

4096 {
4097  Oid oid = PG_GETARG_OID(0);
4098 
4100  PG_RETURN_NULL();
4101 
4103 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
bool RelationIsVisible(Oid relid)
Definition: namespace.c:681
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_ts_config_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4216 of file namespace.c.

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

4217 {
4218  Oid oid = PG_GETARG_OID(0);
4219 
4221  PG_RETURN_NULL();
4222 
4224 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2531
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_ts_dict_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4194 of file namespace.c.

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

4195 {
4196  Oid oid = PG_GETARG_OID(0);
4197 
4199  PG_RETURN_NULL();
4200 
4202 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2278
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_ts_parser_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4183 of file namespace.c.

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

4184 {
4185  Oid oid = PG_GETARG_OID(0);
4186 
4188  PG_RETURN_NULL();
4189 
4191 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
bool TSParserIsVisible(Oid prsId)
Definition: namespace.c:2152
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4205 of file namespace.c.

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

4206 {
4207  Oid oid = PG_GETARG_OID(0);
4208 
4210  PG_RETURN_NULL();
4211 
4213 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
bool TSTemplateIsVisible(Oid tmplId)
Definition: namespace.c:2405
#define PG_RETURN_NULL()
Definition: fmgr.h:297
Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4106 of file namespace.c.

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

4107 {
4108  Oid oid = PG_GETARG_OID(0);
4109 
4111  PG_RETURN_NULL();
4112 
4114 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:167
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:232
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
bool TypeIsVisible(Oid typid)
Definition: namespace.c:776
#define PG_RETURN_NULL()
Definition: fmgr.h:297
void PopOverrideSearchPath ( void  )

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

3287 {
3288  OverrideStackEntry *entry;
3289 
3290  /* Sanity checks. */
3291  if (overrideStack == NIL)
3292  elog(ERROR, "bogus PopOverrideSearchPath call");
3294  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3295  elog(ERROR, "bogus PopOverrideSearchPath call");
3296 
3297  /* Pop the stack and free storage. */
3299  list_free(entry->searchPath);
3300  pfree(entry);
3301 
3302  /* Activate the next level down. */
3303  if (overrideStack)
3304  {
3306  activeSearchPath = entry->searchPath;
3308  activeTempCreationPending = false; /* XXX is this OK? */
3309  }
3310  else
3311  {
3312  /* If not baseSearchPathValid, this is useless but harmless */
3316  }
3317 }
#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:950
#define linitial(l)
Definition: pg_list.h:110
#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:761
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
void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3227 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(), PG_CATALOG_NAMESPACE, OverrideSearchPath::schemas, OverrideStackEntry::searchPath, and TopMemoryContext.

Referenced by CreateSchemaCommand().

3228 {
3229  OverrideStackEntry *entry;
3230  List *oidlist;
3231  Oid firstNS;
3232  MemoryContext oldcxt;
3233 
3234  /*
3235  * Copy the list for safekeeping, and insert implicitly-searched
3236  * namespaces as needed. This code should track recomputeNamespacePath.
3237  */
3239 
3240  oidlist = list_copy(newpath->schemas);
3241 
3242  /*
3243  * Remember the first member of the explicit list.
3244  */
3245  if (oidlist == NIL)
3246  firstNS = InvalidOid;
3247  else
3248  firstNS = linitial_oid(oidlist);
3249 
3250  /*
3251  * Add any implicitly-searched namespaces to the list. Note these go on
3252  * the front, not the back; also notice that we do not check USAGE
3253  * permissions for these.
3254  */
3255  if (newpath->addCatalog)
3256  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3257 
3258  if (newpath->addTemp && OidIsValid(myTempNamespace))
3259  oidlist = lcons_oid(myTempNamespace, oidlist);
3260 
3261  /*
3262  * Build the new stack entry, then insert it at the head of the list.
3263  */
3264  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3265  entry->searchPath = oidlist;
3266  entry->creationNamespace = firstNS;
3268 
3269  overrideStack = lcons(entry, overrideStack);
3270 
3271  /* And make it active. */
3272  activeSearchPath = entry->searchPath;
3274  activeTempCreationPending = false; /* XXX is this OK? */
3275 
3276  MemoryContextSwitchTo(oldcxt);
3277 }
#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:538
static Oid activeCreationNamespace
Definition: namespace.c:136
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
static bool activeTempCreationPending
Definition: namespace.c:139
MemoryContext TopMemoryContext
Definition: mcxt.c:43
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:761
List * lcons(void *datum, List *list)
Definition: list.c:259
#define linitial_oid(l)
Definition: pg_list.h:112
static List * activeSearchPath
Definition: namespace.c:133
void * palloc(Size size)
Definition: mcxt.c:849
Definition: pg_list.h:45
Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 2790 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(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), DefineType(), and get_other_operator().

2791 {
2792  char *schemaname;
2793  Oid namespaceId;
2794 
2795  /* deconstruct the name list */
2796  DeconstructQualifiedName(names, &schemaname, objname_p);
2797 
2798  if (schemaname)
2799  {
2800  /* check for pg_temp alias */
2801  if (strcmp(schemaname, "pg_temp") == 0)
2802  {
2803  /* Initialize temp namespace if first time through */
2806  return myTempNamespace;
2807  }
2808  /* use exact schema given */
2809  namespaceId = get_namespace_oid(schemaname, false);
2810  /* we do not check for USAGE rights here! */
2811  }
2812  else
2813  {
2814  /* use the default creation namespace */
2817  {
2818  /* Need to initialize temp namespace */
2820  return myTempNamespace;
2821  }
2822  namespaceId = activeCreationNamespace;
2823  if (!OidIsValid(namespaceId))
2824  ereport(ERROR,
2825  (errcode(ERRCODE_UNDEFINED_SCHEMA),
2826  errmsg("no schema has been selected to create in")));
2827  }
2828 
2829  return namespaceId;
2830 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2839
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:2603
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
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:3629
int errmsg(const char *fmt,...)
Definition: elog.c:797
void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 614 of file namespace.c.

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

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

615 {
616  switch (newRelation->relpersistence)
617  {
618  case RELPERSISTENCE_TEMP:
619  if (!isTempOrTempToastNamespace(nspid))
620  {
621  if (isAnyTempNamespace(nspid))
622  ereport(ERROR,
623  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
624  errmsg("cannot create relations in temporary schemas of other sessions")));
625  else
626  ereport(ERROR,
627  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
628  errmsg("cannot create temporary relation in non-temporary schema")));
629  }
630  break;
632  if (isTempOrTempToastNamespace(nspid))
633  newRelation->relpersistence = RELPERSISTENCE_TEMP;
634  else if (isAnyTempNamespace(nspid))
635  ereport(ERROR,
636  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
637  errmsg("cannot create relations in temporary schemas of other sessions")));
638  break;
639  default:
640  if (isAnyTempNamespace(nspid))
641  ereport(ERROR,
642  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
643  errmsg("only temporary relations may be created in temporary schemas")));
644  }
645 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:2976
int errcode(int sqlerrcode)
Definition: elog.c:575
#define RELPERSISTENCE_PERMANENT
Definition: pg_class.h:170
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:2990
#define RELPERSISTENCE_TEMP
Definition: pg_class.h:172
Oid RangeVarGetAndCheckCreationNamespace ( RangeVar relation,
LOCKMODE  lockmode,
Oid existing_relation_id 
)

Definition at line 507 of file namespace.c.

References AccessShareLock, ACL_CREATE, ACL_KIND_CLASS, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, RangeVar::catalogname, ereport, errcode(), errmsg(), ERROR, get_database_name(), get_namespace_name(), get_relname_relid(), GetUserId(), InvalidOid, IsBootstrapProcessingMode, LockDatabaseObject(), LockRelationOid(), MyDatabaseId, NamespaceRelationId, NoLock, NULL, 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().

510 {
511  uint64 inval_count;
512  Oid relid;
513  Oid oldrelid = InvalidOid;
514  Oid nspid;
515  Oid oldnspid = InvalidOid;
516  bool retry = false;
517 
518  /*
519  * We check the catalog name and then ignore it.
520  */
521  if (relation->catalogname)
522  {
523  if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
524  ereport(ERROR,
525  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
526  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
527  relation->catalogname, relation->schemaname,
528  relation->relname)));
529  }
530 
531  /*
532  * As in RangeVarGetRelidExtended(), we guard against concurrent DDL
533  * operations by tracking whether any invalidation messages are processed
534  * while we're doing the name lookups and acquiring locks. See comments
535  * in that function for a more detailed explanation of this logic.
536  */
537  for (;;)
538  {
539  AclResult aclresult;
540 
541  inval_count = SharedInvalidMessageCounter;
542 
543  /* Look up creation namespace and check for existing relation. */
544  nspid = RangeVarGetCreationNamespace(relation);
545  Assert(OidIsValid(nspid));
546  if (existing_relation_id != NULL)
547  relid = get_relname_relid(relation->relname, nspid);
548  else
549  relid = InvalidOid;
550 
551  /*
552  * In bootstrap processing mode, we don't bother with permissions or
553  * locking. Permissions might not be working yet, and locking is
554  * unnecessary.
555  */
557  break;
558 
559  /* Check namespace permissions. */
560  aclresult = pg_namespace_aclcheck(nspid, GetUserId(), ACL_CREATE);
561  if (aclresult != ACLCHECK_OK)
563  get_namespace_name(nspid));
564 
565  if (retry)
566  {
567  /* If nothing changed, we're done. */
568  if (relid == oldrelid && nspid == oldnspid)
569  break;
570  /* If creation namespace has changed, give up old lock. */
571  if (nspid != oldnspid)
574  /* If name points to something different, give up old lock. */
575  if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock)
576  UnlockRelationOid(oldrelid, lockmode);
577  }
578 
579  /* Lock namespace. */
580  if (nspid != oldnspid)
582 
583  /* Lock relation, if required if and we have permission. */
584  if (lockmode != NoLock && OidIsValid(relid))
585  {
586  if (!pg_class_ownercheck(relid, GetUserId()))
588  relation->relname);
589  if (relid != oldrelid)
590  LockRelationOid(relid, lockmode);
591  }
592 
593  /* If no invalidation message were processed, we're done! */
594  if (inval_count == SharedInvalidMessageCounter)
595  break;
596 
597  /* Something may have changed, so recheck our work. */
598  retry = true;
599  oldrelid = relid;
600  oldnspid = nspid;
601  }
602 
603  RangeVarAdjustRelationPersistence(relation, nspid);
604  if (existing_relation_id != NULL)
605  *existing_relation_id = relid;
606  return nspid;
607 }
#define NamespaceRelationId
Definition: pg_namespace.h:34
Oid GetUserId(void)
Definition: miscinit.c:283
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:182
#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:538
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4458
void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
Definition: namespace.c:614
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:75
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1651
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2048
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
#define NoLock
Definition: lockdefs.h:34
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3377
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:830
#define ereport(elevel, rest)
Definition: elog.h:122
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:851
AclResult
Definition: acl.h:170
Oid MyDatabaseId
Definition: globals.c:76
uint64 SharedInvalidMessageCounter
Definition: sinval.c:26
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool pg_class_ownercheck(Oid class_oid, Oid roleid)
Definition: aclchk.c:4520
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
int errmsg(const char *fmt,...)
Definition: elog.c:797
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:105
char * catalogname
Definition: primnodes.h:66
Oid RangeVarGetCreationNamespace(const RangeVar *newRelation)
Definition: namespace.c:420
Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 420 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, RELPERSISTENCE_TEMP, and RangeVar::schemaname.

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

421 {
422  Oid namespaceId;
423 
424  /*
425  * We check the catalog name and then ignore it.
426  */
427  if (newRelation->catalogname)
428  {
429  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
430  ereport(ERROR,
431  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
432  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
433  newRelation->catalogname, newRelation->schemaname,
434  newRelation->relname)));
435  }
436 
437  if (newRelation->schemaname)
438  {
439  /* check for pg_temp alias */
440  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
441  {
442  /* Initialize temp namespace if first time through */
445  return myTempNamespace;
446  }
447  /* use exact schema given */
448  namespaceId = get_namespace_oid(newRelation->schemaname, false);
449  /* we do not check for USAGE rights here! */
450  }
451  else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
452  {
453  /* Initialize temp namespace if first time through */
456  return myTempNamespace;
457  }
458  else
459  {
460  /* use the default creation namespace */
463  {
464  /* Need to initialize temp namespace */
466  return myTempNamespace;
467  }
468  namespaceId = activeCreationNamespace;
469  if (!OidIsValid(namespaceId))
470  ereport(ERROR,
471  (errcode(ERRCODE_UNDEFINED_SCHEMA),
472  errmsg("no schema has been selected to create in")));
473  }
474 
475  /* Note: callers will check for CREATE rights when appropriate */
476 
477  return namespaceId;
478 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2839
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:538
static void recomputeNamespacePath(void)
Definition: namespace.c:3479
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
static Oid activeCreationNamespace
Definition: namespace.c:136
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2048
static bool activeTempCreationPending
Definition: namespace.c:139
#define ereport(elevel, rest)
Definition: elog.h:122
static void InitTempTableNamespace(void)
Definition: namespace.c:3629
Oid MyDatabaseId
Definition: globals.c:76
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELPERSISTENCE_TEMP
Definition: pg_class.h:172
char * catalogname
Definition: primnodes.h:66
Oid RangeVarGetRelidExtended ( const RangeVar relation,
LOCKMODE  lockmode,
bool  missing_ok,
bool  nowait,
RangeVarGetRelidCallback  callback,
void *  callback_arg 
)

Definition at line 217 of file namespace.c.

References AcceptInvalidationMessages(), callback(), RangeVar::catalogname, ConditionalLockRelationOid(), 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, RELPERSISTENCE_TEMP, RangeVar::schemaname, SharedInvalidMessageCounter, and UnlockRelationOid().

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

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

Definition at line 3479 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_CATALOG_NAMESPACE, 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_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(), TSConfigIsVisible(), TSDictionaryIsVisible(), TSParserIsVisible(), TSTemplateIsVisible(), TypeIsVisible(), and TypenameGetTypid().

3480 {
3481  Oid roleid = GetUserId();
3482  char *rawname;
3483  List *namelist;
3484  List *oidlist;
3485  List *newpath;
3486  ListCell *l;
3487  bool temp_missing;
3488  Oid firstNS;
3489  MemoryContext oldcxt;
3490 
3491  /* Do nothing if an override search spec is active. */
3492  if (overrideStack)
3493  return;
3494 
3495  /* Do nothing if path is already valid. */
3496  if (baseSearchPathValid && namespaceUser == roleid)
3497  return;
3498 
3499  /* Need a modifiable copy of namespace_search_path string */
3500  rawname = pstrdup(namespace_search_path);
3501 
3502  /* Parse string into list of identifiers */
3503  if (!SplitIdentifierString(rawname, ',', &namelist))
3504  {
3505  /* syntax error in name list */
3506  /* this should not happen if GUC checked check_search_path */
3507  elog(ERROR, "invalid list syntax");
3508  }
3509 
3510  /*
3511  * Convert the list of names to a list of OIDs. If any names are not
3512  * recognizable or we don't have read access, just leave them out of the
3513  * list. (We can't raise an error, since the search_path setting has
3514  * already been accepted.) Don't make duplicate entries, either.
3515  */
3516  oidlist = NIL;
3517  temp_missing = false;
3518  foreach(l, namelist)
3519  {
3520  char *curname = (char *) lfirst(l);
3521  Oid namespaceId;
3522 
3523  if (strcmp(curname, "$user") == 0)
3524  {
3525  /* $user --- substitute namespace matching user name, if any */
3526  HeapTuple tuple;
3527 
3528  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
3529  if (HeapTupleIsValid(tuple))
3530  {
3531  char *rname;
3532 
3533  rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
3534  namespaceId = get_namespace_oid(rname, true);
3535  ReleaseSysCache(tuple);
3536  if (OidIsValid(namespaceId) &&
3537  !list_member_oid(oidlist, namespaceId) &&
3538  pg_namespace_aclcheck(namespaceId, roleid,
3539  ACL_USAGE) == ACLCHECK_OK &&
3540  InvokeNamespaceSearchHook(namespaceId, false))
3541  oidlist = lappend_oid(oidlist, namespaceId);
3542  }
3543  }
3544  else if (strcmp(curname, "pg_temp") == 0)
3545  {
3546  /* pg_temp --- substitute temp namespace, if any */
3548  {
3549  if (!list_member_oid(oidlist, myTempNamespace) &&
3551  oidlist = lappend_oid(oidlist, myTempNamespace);
3552  }
3553  else
3554  {
3555  /* If it ought to be the creation namespace, set flag */
3556  if (oidlist == NIL)
3557  temp_missing = true;
3558  }
3559  }
3560  else
3561  {
3562  /* normal namespace reference */
3563  namespaceId = get_namespace_oid(curname, true);
3564  if (OidIsValid(namespaceId) &&
3565  !list_member_oid(oidlist, namespaceId) &&
3566  pg_namespace_aclcheck(namespaceId, roleid,
3567  ACL_USAGE) == ACLCHECK_OK &&
3568  InvokeNamespaceSearchHook(namespaceId, false))
3569  oidlist = lappend_oid(oidlist, namespaceId);
3570  }
3571  }
3572 
3573  /*
3574  * Remember the first member of the explicit list. (Note: this is
3575  * nominally wrong if temp_missing, but we need it anyway to distinguish
3576  * explicit from implicit mention of pg_catalog.)
3577  */
3578  if (oidlist == NIL)
3579  firstNS = InvalidOid;
3580  else
3581  firstNS = linitial_oid(oidlist);
3582 
3583  /*
3584  * Add any implicitly-searched namespaces to the list. Note these go on
3585  * the front, not the back; also notice that we do not check USAGE
3586  * permissions for these.
3587  */
3588  if (!list_member_oid(oidlist, PG_CATALOG_NAMESPACE))
3589  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3590 
3591  if (OidIsValid(myTempNamespace) &&
3592  !list_member_oid(oidlist, myTempNamespace))
3593  oidlist = lcons_oid(myTempNamespace, oidlist);
3594 
3595  /*
3596  * Now that we've successfully built the new list of namespace OIDs, save
3597  * it in permanent storage.
3598  */
3600  newpath = list_copy(oidlist);
3601  MemoryContextSwitchTo(oldcxt);
3602 
3603  /* Now safe to assign to state variables. */
3605  baseSearchPath = newpath;
3606  baseCreationNamespace = firstNS;
3607  baseTempCreationPending = temp_missing;
3608 
3609  /* Mark the path valid. */
3610  baseSearchPathValid = true;
3611  namespaceUser = roleid;
3612 
3613  /* And make it active. */
3617 
3618  /* Clean up. */
3619  pfree(rawname);
3620  list_free(namelist);
3621  list_free(oidlist);
3622 }
#define NIL
Definition: pg_list.h:69
static bool baseSearchPathValid
Definition: namespace.c:152
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2839
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid GetUserId(void)
Definition: miscinit.c:283
char * pstrdup(const char *in)
Definition: mcxt.c:1077
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
static Oid namespaceUser
Definition: namespace.c:149
List * lcons_oid(Oid datum, List *list)
Definition: list.c:295
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define OidIsValid(objectId)
Definition: c.h:538
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4458
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:174
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
static Oid activeCreationNamespace
Definition: namespace.c:136
void pfree(void *pointer)
Definition: mcxt.c:950
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
static bool baseTempCreationPending
Definition: namespace.c:147
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3115
#define ACL_USAGE
Definition: parsenodes.h:73
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
static bool activeTempCreationPending
Definition: namespace.c:139
MemoryContext TopMemoryC