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_statistics_oid (List *names, bool missing_ok)
 
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 4000 of file namespace.c.

References baseSearchPathValid.

4001 {
4002  /*
4003  * We mark the path as needing recomputation, but don't do anything until
4004  * it's needed. This avoids trying to do database access during GUC
4005  * initialization, or outside a transaction.
4006  */
4007  baseSearchPathValid = false;
4008 }
static bool baseSearchPathValid
Definition: namespace.c:152
void AtEOSubXact_Namespace ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

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

3851 {
3852  OverrideStackEntry *entry;
3853 
3854  if (myTempNamespaceSubID == mySubid)
3855  {
3856  if (isCommit)
3857  myTempNamespaceSubID = parentSubid;
3858  else
3859  {
3861  /* TEMP namespace creation failed, so reset state */
3864  baseSearchPathValid = false; /* need to rebuild list */
3865  }
3866  }
3867 
3868  /*
3869  * Clean up if someone failed to do PopOverrideSearchPath
3870  */
3871  while (overrideStack)
3872  {
3875  break;
3876  if (isCommit)
3877  elog(WARNING, "leaked override search path");
3879  list_free(entry->searchPath);
3880  pfree(entry);
3881  }
3882 
3883  /* Activate the next level down. */
3884  if (overrideStack)
3885  {
3887  activeSearchPath = entry->searchPath;
3889  activeTempCreationPending = false; /* XXX is this OK? */
3890  }
3891  else
3892  {
3893  /* If not baseSearchPathValid, this is useless but harmless */
3897  }
3898 }
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:111
static bool baseTempCreationPending
Definition: namespace.c:147
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:143
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c: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 3794 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().

3795 {
3796  /*
3797  * If we abort the transaction in which a temp namespace was selected,
3798  * we'll have to do any creation or cleanout work over again. So, just
3799  * forget the namespace entirely until next time. On the other hand, if
3800  * we commit then register an exit callback to clean out the temp tables
3801  * at backend shutdown. (We only want to register the callback once per
3802  * session, so this is a good place to do it.)
3803  */
3804  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
3805  {
3806  if (isCommit)
3808  else
3809  {
3812  baseSearchPathValid = false; /* need to rebuild list */
3813  }
3815  }
3816 
3817  /*
3818  * Clean up if someone failed to do PopOverrideSearchPath
3819  */
3820  if (overrideStack)
3821  {
3822  if (isCommit)
3823  elog(WARNING, "leaked override search path");
3824  while (overrideStack)
3825  {
3826  OverrideStackEntry *entry;
3827 
3830  list_free(entry->searchPath);
3831  pfree(entry);
3832  }
3833  /* If not baseSearchPathValid, this is useless but harmless */
3837  }
3838 }
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:111
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:3935
List * list_delete_first(List *list)
Definition: list.c:666
bool check_search_path ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 3966 of file namespace.c.

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

3967 {
3968  char *rawname;
3969  List *namelist;
3970 
3971  /* Need a modifiable copy of string */
3972  rawname = pstrdup(*newval);
3973 
3974  /* Parse string into list of identifiers */
3975  if (!SplitIdentifierString(rawname, ',', &namelist))
3976  {
3977  /* syntax error in name list */
3978  GUC_check_errdetail("List syntax is invalid.");
3979  pfree(rawname);
3980  list_free(namelist);
3981  return false;
3982  }
3983 
3984  /*
3985  * We used to try to check that the named schemas exist, but there are
3986  * many valid use-cases for having search_path settings that include
3987  * schemas that don't exist; and often, we are not inside a transaction
3988  * here and so can't consult the system catalogs anyway. So now, the only
3989  * requirement is syntactic validity of the identifier list.
3990  */
3991 
3992  pfree(rawname);
3993  list_free(namelist);
3994 
3995  return true;
3996 }
#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:3240
#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 2818 of file namespace.c.

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

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

2819 {
2820  /* disallow renaming into or out of temp schemas */
2821  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2822  ereport(ERROR,
2823  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2824  errmsg("cannot move objects into or out of temporary schemas")));
2825 
2826  /* same for TOAST schema */
2827  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
2828  ereport(ERROR,
2829  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2830  errmsg("cannot move objects into or out of TOAST schema")));
2831 }
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:3046
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:183
signed int int32
Definition: c.h:256
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:152
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:1116
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:51
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:181
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:152
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
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:1116
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 3207 of file namespace.c.

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

Referenced by CopyCachedPlan().

3208 {
3210 
3211  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3212  result->schemas = list_copy(path->schemas);
3213  result->addCatalog = path->addCatalog;
3214  result->addTemp = path->addTemp;
3215 
3216  return result;
3217 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
return result
Definition: formatting.c:1618
void * palloc(Size size)
Definition: mcxt.c:849
void DeconstructQualifiedName ( List names,
char **  nspname_p,
char **  objname_p 
)

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

2662 {
2663  char *catalogname;
2664  char *schemaname = NULL;
2665  char *objname = NULL;
2666 
2667  switch (list_length(names))
2668  {
2669  case 1:
2670  objname = strVal(linitial(names));
2671  break;
2672  case 2:
2673  schemaname = strVal(linitial(names));
2674  objname = strVal(lsecond(names));
2675  break;
2676  case 3:
2677  catalogname = strVal(linitial(names));
2678  schemaname = strVal(lsecond(names));
2679  objname = strVal(lthird(names));
2680 
2681  /*
2682  * We check the catalog name and then ignore it.
2683  */
2684  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2685  ereport(ERROR,
2686  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2687  errmsg("cross-database references are not implemented: %s",
2688  NameListToString(names))));
2689  break;
2690  default:
2691  ereport(ERROR,
2692  (errcode(ERRCODE_SYNTAX_ERROR),
2693  errmsg("improper qualified name (too many dotted names): %s",
2694  NameListToString(names))));
2695  break;
2696  }
2697 
2698  *nspname_p = schemaname;
2699  *objname_p = objname;
2700 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
#define lsecond(l)
Definition: pg_list.h:116
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2953
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:121
List* fetch_search_path ( bool  includeImplicit)

Definition at line 4074 of file namespace.c.

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

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

4075 {
4076  List *result;
4077 
4079 
4080  /*
4081  * If the temp namespace should be first, force it to exist. This is so
4082  * that callers can trust the result to reflect the actual default
4083  * creation namespace. It's a bit bogus to do this here, since
4084  * current_schema() is supposedly a stable function without side-effects,
4085  * but the alternatives seem worse.
4086  */
4088  {
4091  }
4092 
4093  result = list_copy(activeSearchPath);
4094  if (!includeImplicit)
4095  {
4096  while (result && linitial_oid(result) != activeCreationNamespace)
4097  result = list_delete_first(result);
4098  }
4099 
4100  return result;
4101 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
return result
Definition: formatting.c:1618
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
static Oid activeCreationNamespace
Definition: namespace.c:136
static bool activeTempCreationPending
Definition: namespace.c:139
static void InitTempTableNamespace(void)
Definition: namespace.c:3685
#define linitial_oid(l)
Definition: pg_list.h:113
static List * activeSearchPath
Definition: namespace.c:133
Definition: pg_list.h:45
List * list_delete_first(List *list)
Definition: list.c:666
int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4114 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4115 {
4116  int count = 0;
4117  ListCell *l;
4118 
4120 
4121  foreach(l, activeSearchPath)
4122  {
4123  Oid namespaceId = lfirst_oid(l);
4124 
4125  if (namespaceId == myTempNamespace)
4126  continue; /* do not include temp namespace */
4127 
4128  if (count < sarray_len)
4129  sarray[count] = namespaceId;
4130  count++;
4131  }
4132 
4133  return count;
4134 }
static Oid myTempNamespace
Definition: namespace.c:180
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
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 3508 of file namespace.c.

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

Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().

3509 {
3510  Oid proc;
3511  ListCell *l;
3512 
3514 
3515  foreach(l, activeSearchPath)
3516  {
3517  Oid namespaceId = lfirst_oid(l);
3518 
3519  if (namespaceId == myTempNamespace)
3520  continue; /* do not look in temp namespace */
3521 
3522  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3523  if (OidIsValid(proc))
3524  return proc;
3525  }
3526 
3527  /* Not found in path */
3528  return InvalidOid;
3529 }
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:3535
#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:2743
#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:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
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:197
struct _FuncCandidateList * next
Definition: namespace.h:30
#define ReleaseSysCacheList(x)
Definition: syscache.h:206
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:152
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#define list_make1(x1)
Definition: pg_list.h:139
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:1116
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 3380 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 AlterCollation(), ComputeIndexAttrs(), ComputePartitionAttrs(), DefineCollation(), DefineDomain(), DefineRange(), get_object_address(), and LookupCollation().

3381 {
3382  char *schemaname;
3383  char *collation_name;
3384  int32 dbencoding = GetDatabaseEncoding();
3385  Oid namespaceId;
3386  Oid colloid;
3387  ListCell *l;
3388 
3389  /* deconstruct the name list */
3390  DeconstructQualifiedName(name, &schemaname, &collation_name);
3391 
3392  if (schemaname)
3393  {
3394  /* use exact schema given */
3395  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3396  if (missing_ok && !OidIsValid(namespaceId))
3397  return InvalidOid;
3398 
3399  /* first try for encoding-specific entry, then any-encoding */
3400  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3401  PointerGetDatum(collation_name),
3402  Int32GetDatum(dbencoding),
3403  ObjectIdGetDatum(namespaceId));
3404  if (OidIsValid(colloid))
3405  return colloid;
3406  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3407  PointerGetDatum(collation_name),
3408  Int32GetDatum(-1),
3409  ObjectIdGetDatum(namespaceId));
3410  if (OidIsValid(colloid))
3411  return colloid;
3412  }
3413  else
3414  {
3415  /* search for it in search path */
3417 
3418  foreach(l, activeSearchPath)
3419  {
3420  namespaceId = lfirst_oid(l);
3421 
3422  if (namespaceId == myTempNamespace)
3423  continue; /* do not look in temp namespace */
3424 
3425  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3426  PointerGetDatum(collation_name),
3427  Int32GetDatum(dbencoding),
3428  ObjectIdGetDatum(namespaceId));
3429  if (OidIsValid(colloid))
3430  return colloid;
3431  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3432  PointerGetDatum(collation_name),
3433  Int32GetDatum(-1),
3434  ObjectIdGetDatum(namespaceId));
3435  if (OidIsValid(colloid))
3436  return colloid;
3437  }
3438  }
3439 
3440  /* Not found in path */
3441  if (!missing_ok)
3442  ereport(ERROR,
3443  (errcode(ERRCODE_UNDEFINED_OBJECT),
3444  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3446  return InvalidOid;
3447 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2743
#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:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:183
signed int int32
Definition: c.h:256
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:2953
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 3453 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().

3454 {
3455  char *schemaname;
3456  char *conversion_name;
3457  Oid namespaceId;
3458  Oid conoid = InvalidOid;
3459  ListCell *l;
3460 
3461  /* deconstruct the name list */
3462  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3463 
3464  if (schemaname)
3465  {
3466  /* use exact schema given */
3467  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3468  if (missing_ok && !OidIsValid(namespaceId))
3469  conoid = InvalidOid;
3470  else
3471  conoid = GetSysCacheOid2(CONNAMENSP,
3472  PointerGetDatum(conversion_name),
3473  ObjectIdGetDatum(namespaceId));
3474  }
3475  else
3476  {
3477  /* search for it in search path */
3479 
3480  foreach(l, activeSearchPath)
3481  {
3482  namespaceId = lfirst_oid(l);
3483 
3484  if (namespaceId == myTempNamespace)
3485  continue; /* do not look in temp namespace */
3486 
3487  conoid = GetSysCacheOid2(CONNAMENSP,
3488  PointerGetDatum(conversion_name),
3489  ObjectIdGetDatum(namespaceId));
3490  if (OidIsValid(conoid))
3491  return conoid;
3492  }
3493  }
3494 
3495  /* Not found in path */
3496  if (!OidIsValid(conoid) && !missing_ok)
3497  ereport(ERROR,
3498  (errcode(ERRCODE_UNDEFINED_OBJECT),
3499  errmsg("conversion \"%s\" does not exist",
3500  NameListToString(name))));
3501  return conoid;
3502 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2743
#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:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:181
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:2953
#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 2895 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().

2896 {
2897  Oid oid;
2898 
2900  if (!OidIsValid(oid) && !missing_ok)
2901  ereport(ERROR,
2902  (errcode(ERRCODE_UNDEFINED_SCHEMA),
2903  errmsg("schema \"%s\" does not exist", nspname)));
2904 
2905  return oid;
2906 }
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:179
#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_statistics_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 STATEXTNAMENSP.

Referenced by get_object_address().

2095 {
2096  char *schemaname;
2097  char *stats_name;
2098  Oid namespaceId;
2099  Oid stats_oid = InvalidOid;
2100  ListCell *l;
2101 
2102  /* deconstruct the name list */
2103  DeconstructQualifiedName(names, &schemaname, &stats_name);
2104 
2105  if (schemaname)
2106  {
2107  /* use exact schema given */
2108  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2109  if (missing_ok && !OidIsValid(namespaceId))
2110  stats_oid = InvalidOid;
2111  else
2112  stats_oid = GetSysCacheOid2(STATEXTNAMENSP,
2113  PointerGetDatum(stats_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  stats_oid = GetSysCacheOid2(STATEXTNAMENSP,
2128  PointerGetDatum(stats_name),
2129  ObjectIdGetDatum(namespaceId));
2130  if (OidIsValid(stats_oid))
2131  break;
2132  }
2133  }
2134 
2135  if (!OidIsValid(stats_oid) && !missing_ok)
2136  ereport(ERROR,
2137  (errcode(ERRCODE_UNDEFINED_OBJECT),
2138  errmsg("statistics \"%s\" do not exist",
2139  NameListToString(names))));
2140 
2141  return stats_oid;
2142 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2743
#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:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:181
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:2953
#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_config_oid ( List names,
bool  missing_ok 
)

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

2530 {
2531  char *schemaname;
2532  char *config_name;
2533  Oid namespaceId;
2534  Oid cfgoid = InvalidOid;
2535  ListCell *l;
2536 
2537  /* deconstruct the name list */
2538  DeconstructQualifiedName(names, &schemaname, &config_name);
2539 
2540  if (schemaname)
2541  {
2542  /* use exact schema given */
2543  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2544  if (missing_ok && !OidIsValid(namespaceId))
2545  cfgoid = InvalidOid;
2546  else
2548  PointerGetDatum(config_name),
2549  ObjectIdGetDatum(namespaceId));
2550  }
2551  else
2552  {
2553  /* search for it in search path */
2555 
2556  foreach(l, activeSearchPath)
2557  {
2558  namespaceId = lfirst_oid(l);
2559 
2560  if (namespaceId == myTempNamespace)
2561  continue; /* do not look in temp namespace */
2562 
2564  PointerGetDatum(config_name),
2565  ObjectIdGetDatum(namespaceId));
2566  if (OidIsValid(cfgoid))
2567  break;
2568  }
2569  }
2570 
2571  if (!OidIsValid(cfgoid) && !missing_ok)
2572  ereport(ERROR,
2573  (errcode(ERRCODE_UNDEFINED_OBJECT),
2574  errmsg("text search configuration \"%s\" does not exist",
2575  NameListToString(names))));
2576 
2577  return cfgoid;
2578 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2743
#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:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:181
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:2953
#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 2276 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().

2277 {
2278  char *schemaname;
2279  char *dict_name;
2280  Oid namespaceId;
2281  Oid dictoid = InvalidOid;
2282  ListCell *l;
2283 
2284  /* deconstruct the name list */
2285  DeconstructQualifiedName(names, &schemaname, &dict_name);
2286 
2287  if (schemaname)
2288  {
2289  /* use exact schema given */
2290  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2291  if (missing_ok && !OidIsValid(namespaceId))
2292  dictoid = InvalidOid;
2293  else
2294  dictoid = GetSysCacheOid2(TSDICTNAMENSP,
2295  PointerGetDatum(dict_name),
2296  ObjectIdGetDatum(namespaceId));
2297  }
2298  else
2299  {
2300  /* search for it in search path */
2302 
2303  foreach(l, activeSearchPath)
2304  {
2305  namespaceId = lfirst_oid(l);
2306 
2307  if (namespaceId == myTempNamespace)
2308  continue; /* do not look in temp namespace */
2309 
2310  dictoid = GetSysCacheOid2(TSDICTNAMENSP,
2311  PointerGetDatum(dict_name),
2312  ObjectIdGetDatum(namespaceId));
2313  if (OidIsValid(dictoid))
2314  break;
2315  }
2316  }
2317 
2318  if (!OidIsValid(dictoid) && !missing_ok)
2319  ereport(ERROR,
2320  (errcode(ERRCODE_UNDEFINED_OBJECT),
2321  errmsg("text search dictionary \"%s\" does not exist",
2322  NameListToString(names))));
2323 
2324  return dictoid;
2325 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2743
#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:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:181
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:2953
#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 2150 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().

2151 {
2152  char *schemaname;
2153  char *parser_name;
2154  Oid namespaceId;
2155  Oid prsoid = InvalidOid;
2156  ListCell *l;
2157 
2158  /* deconstruct the name list */
2159  DeconstructQualifiedName(names, &schemaname, &parser_name);
2160 
2161  if (schemaname)
2162  {
2163  /* use exact schema given */
2164  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2165  if (missing_ok && !OidIsValid(namespaceId))
2166  prsoid = InvalidOid;
2167  else
2169  PointerGetDatum(parser_name),
2170  ObjectIdGetDatum(namespaceId));
2171  }
2172  else
2173  {
2174  /* search for it in search path */
2176 
2177  foreach(l, activeSearchPath)
2178  {
2179  namespaceId = lfirst_oid(l);
2180 
2181  if (namespaceId == myTempNamespace)
2182  continue; /* do not look in temp namespace */
2183 
2185  PointerGetDatum(parser_name),
2186  ObjectIdGetDatum(namespaceId));
2187  if (OidIsValid(prsoid))
2188  break;
2189  }
2190  }
2191 
2192  if (!OidIsValid(prsoid) && !missing_ok)
2193  ereport(ERROR,
2194  (errcode(ERRCODE_UNDEFINED_OBJECT),
2195  errmsg("text search parser \"%s\" does not exist",
2196  NameListToString(names))));
2197 
2198  return prsoid;
2199 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2743
#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:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:181
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:2953
#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 2403 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().

2404 {
2405  char *schemaname;
2406  char *template_name;
2407  Oid namespaceId;
2408  Oid tmploid = InvalidOid;
2409  ListCell *l;
2410 
2411  /* deconstruct the name list */
2412  DeconstructQualifiedName(names, &schemaname, &template_name);
2413 
2414  if (schemaname)
2415  {
2416  /* use exact schema given */
2417  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2418  if (missing_ok && !OidIsValid(namespaceId))
2419  tmploid = InvalidOid;
2420  else
2422  PointerGetDatum(template_name),
2423  ObjectIdGetDatum(namespaceId));
2424  }
2425  else
2426  {
2427  /* search for it in search path */
2429 
2430  foreach(l, activeSearchPath)
2431  {
2432  namespaceId = lfirst_oid(l);
2433 
2434  if (namespaceId == myTempNamespace)
2435  continue; /* do not look in temp namespace */
2436 
2438  PointerGetDatum(template_name),
2439  ObjectIdGetDatum(namespaceId));
2440  if (OidIsValid(tmploid))
2441  break;
2442  }
2443  }
2444 
2445  if (!OidIsValid(tmploid) && !missing_ok)
2446  ereport(ERROR,
2447  (errcode(ERRCODE_UNDEFINED_OBJECT),
2448  errmsg("text search template \"%s\" does not exist",
2449  NameListToString(names))));
2450 
2451  return tmploid;
2452 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2743
#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:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:181
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:2953
#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 3171 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(), result, and OverrideSearchPath::schemas.

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

3172 {
3174  List *schemas;
3175  MemoryContext oldcxt;
3176 
3178 
3179  oldcxt = MemoryContextSwitchTo(context);
3180 
3181  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3182  schemas = list_copy(activeSearchPath);
3183  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3184  {
3185  if (linitial_oid(schemas) == myTempNamespace)
3186  result->addTemp = true;
3187  else
3188  {
3190  result->addCatalog = true;
3191  }
3192  schemas = list_delete_first(schemas);
3193  }
3194  result->schemas = schemas;
3195 
3196  MemoryContextSwitchTo(oldcxt);
3197 
3198  return result;
3199 }
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
return result
Definition: formatting.c:1618
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
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:113
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 3085 of file namespace.c.

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

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

3086 {
3087  int result;
3088  char *nspname;
3089 
3090  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3091  nspname = get_namespace_name(namespaceId);
3092  if (!nspname)
3093  return InvalidBackendId; /* no such namespace? */
3094  if (strncmp(nspname, "pg_temp_", 8) == 0)
3095  result = atoi(nspname + 8);
3096  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3097  result = atoi(nspname + 14);
3098  else
3099  result = InvalidBackendId;
3100  pfree(nspname);
3101  return result;
3102 }
return result
Definition: formatting.c:1618
void pfree(void *pointer)
Definition: mcxt.c:950
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3038
#define InvalidBackendId
Definition: backendid.h:23
void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3124 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3125 {
3126  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3127  *tempNamespaceId = myTempNamespace;
3128  *tempToastNamespaceId = myTempToastNamespace;
3129 }
static Oid myTempToastNamespace
Definition: namespace.c:182
static Oid myTempNamespace
Definition: namespace.c:180
Oid GetTempToastNamespace ( void  )

Definition at line 3110 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3111 {
3113  return myTempToastNamespace;
3114 }
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 4016 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().

4017 {
4019  {
4020  /*
4021  * In bootstrap mode, the search path must be 'pg_catalog' so that
4022  * tables are created in the proper namespace; ignore the GUC setting.
4023  */
4024  MemoryContext oldcxt;
4025 
4028  MemoryContextSwitchTo(oldcxt);
4030  baseTempCreationPending = false;
4031  baseSearchPathValid = true;
4036  }
4037  else
4038  {
4039  /*
4040  * In normal mode, arrange for a callback on any syscache invalidation
4041  * of pg_namespace rows.
4042  */
4045  (Datum) 0);
4046  /* Force search path to be recomputed on next use */
4047  baseSearchPathValid = false;
4048  }
4049 }
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:4056
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:1382
uintptr_t Datum
Definition: postgres.h:372
#define list_make1_oid(x1)
Definition: pg_list.h:151
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
static List * activeSearchPath
Definition: namespace.c:133
static void InitTempTableNamespace ( void  )
static

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

3686 {
3687  char namespaceName[NAMEDATALEN];
3688  Oid namespaceId;
3689  Oid toastspaceId;
3690 
3692 
3693  /*
3694  * First, do permission check to see if we are authorized to make temp
3695  * tables. We use a nonstandard error message here since "databasename:
3696  * permission denied" might be a tad cryptic.
3697  *
3698  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
3699  * that's necessary since current user ID could change during the session.
3700  * But there's no need to make the namespace in the first place until a
3701  * temp table creation request is made by someone with appropriate rights.
3702  */
3705  ereport(ERROR,
3706  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3707  errmsg("permission denied to create temporary tables in database \"%s\"",
3709 
3710  /*
3711  * Do not allow a Hot Standby slave session to make temp tables. Aside
3712  * from problems with modifying the system catalogs, there is a naming
3713  * conflict: pg_temp_N belongs to the session with BackendId N on the
3714  * master, not to a slave session with the same BackendId. We should not
3715  * be able to get here anyway due to XactReadOnly checks, but let's just
3716  * make real sure. Note that this also backstops various operations that
3717  * allow XactReadOnly transactions to modify temp tables; they'd need
3718  * RecoveryInProgress checks if not for this.
3719  */
3720  if (RecoveryInProgress())
3721  ereport(ERROR,
3722  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3723  errmsg("cannot create temporary tables during recovery")));
3724 
3725  /* Parallel workers can't create temporary tables, either. */
3726  if (IsParallelWorker())
3727  ereport(ERROR,
3728  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3729  errmsg("cannot create temporary tables in parallel mode")));
3730 
3731  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
3732 
3733  namespaceId = get_namespace_oid(namespaceName, true);
3734  if (!OidIsValid(namespaceId))
3735  {
3736  /*
3737  * First use of this temp namespace in this database; create it. The
3738  * temp namespaces are always owned by the superuser. We leave their
3739  * permissions at default --- i.e., no access except to superuser ---
3740  * to ensure that unprivileged users can't peek at other backends'
3741  * temp tables. This works because the places that access the temp
3742  * namespace for my own backend skip permissions checks on it.
3743  */
3744  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3745  true);
3746  /* Advance command counter to make namespace visible */
3748  }
3749  else
3750  {
3751  /*
3752  * If the namespace already exists, clean it out (in case the former
3753  * owner crashed without doing so).
3754  */
3755  RemoveTempRelations(namespaceId);
3756  }
3757 
3758  /*
3759  * If the corresponding toast-table namespace doesn't exist yet, create
3760  * it. (We assume there is no need to clean it out if it does exist, since
3761  * dropping a parent table should make its toast table go away.)
3762  */
3763  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
3764  MyBackendId);
3765 
3766  toastspaceId = get_namespace_oid(namespaceName, true);
3767  if (!OidIsValid(toastspaceId))
3768  {
3769  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3770  true);
3771  /* Advance command counter to make namespace visible */
3773  }
3774 
3775  /*
3776  * Okay, we've prepared the temp namespace ... but it's not committed yet,
3777  * so all our work could be undone by transaction rollback. Set flag for
3778  * AtEOXact_Namespace to know what to do.
3779  */
3780  myTempNamespace = namespaceId;
3781  myTempToastNamespace = toastspaceId;
3782 
3783  /* It should not be done already. */
3786 
3787  baseSearchPathValid = false; /* need to rebuild list */
3788 }
static bool baseSearchPathValid
Definition: namespace.c:152
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2895
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:7874
#define OidIsValid(objectId)
Definition: c.h:538
#define NAMEDATALEN
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:184
#define ereport(elevel, rest)
Definition: elog.h:122
#define IsParallelWorker()
Definition: parallel.h:52
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:4434
#define Assert(condition)
Definition: c.h:675
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:649
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:3909
#define BOOTSTRAP_SUPERUSERID
Definition: pg_authid.h:108
#define InvalidSubTransactionId
Definition: c.h:403
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ACL_CREATE_TEMP
Definition: parsenodes.h:83
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
Definition: pg_namespace.c:42
bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3046 of file namespace.c.

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

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

3047 {
3048  bool result;
3049  char *nspname;
3050 
3051  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3052  nspname = get_namespace_name(namespaceId);
3053  if (!nspname)
3054  return false; /* no such namespace? */
3055  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3056  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3057  pfree(nspname);
3058  return result;
3059 }
return result
Definition: formatting.c:1618
void pfree(void *pointer)
Definition: mcxt.c:950
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3038
bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3069 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

3070 {
3071  /* If it's my own temp namespace, say "false" */
3072  if (isTempOrTempToastNamespace(namespaceId))
3073  return false;
3074  /* Else, if it's any temp namespace, say "true" */
3075  return isAnyTempNamespace(namespaceId);
3076 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3032
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3046
bool isTempNamespace ( Oid  namespaceId)

Definition at line 3008 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

3009 {
3010  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3011  return true;
3012  return false;
3013 }
static Oid myTempNamespace
Definition: namespace.c:180
#define OidIsValid(objectId)
Definition: c.h:538
bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3032 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

3033 {
3034  if (OidIsValid(myTempNamespace) &&
3035  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3036  return true;
3037  return false;
3038 }
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 3020 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

3021 {
3022  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3023  return true;
3024  return false;
3025 }
static Oid myTempToastNamespace
Definition: namespace.c:182
#define OidIsValid(objectId)
Definition: c.h:538
Oid LookupCreationNamespace ( const char *  nspname)

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

2787 {
2788  Oid namespaceId;
2789  AclResult aclresult;
2790 
2791  /* check for pg_temp alias */
2792  if (strcmp(nspname, "pg_temp") == 0)
2793  {
2794  /* Initialize temp namespace if first time through */
2797  return myTempNamespace;
2798  }
2799 
2800  namespaceId = get_namespace_oid(nspname, false);
2801 
2802  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2803  if (aclresult != ACLCHECK_OK)
2805  nspname);
2806 
2807  return namespaceId;
2808 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2895
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:4484
#define ACL_CREATE
Definition: parsenodes.h:82
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
static void InitTempTableNamespace(void)
Definition: namespace.c:3685
AclResult
Definition: acl.h:170
Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

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

2744 {
2745  Oid namespaceId;
2746  AclResult aclresult;
2747 
2748  /* check for pg_temp alias */
2749  if (strcmp(nspname, "pg_temp") == 0)
2750  {
2752  return myTempNamespace;
2753 
2754  /*
2755  * Since this is used only for looking up existing objects, there is
2756  * no point in trying to initialize the temp namespace here; and doing
2757  * so might create problems for some callers --- just fall through.
2758  */
2759  }
2760 
2761  namespaceId = get_namespace_oid(nspname, missing_ok);
2762  if (missing_ok && !OidIsValid(namespaceId))
2763  return InvalidOid;
2764 
2765  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
2766  if (aclresult != ACLCHECK_OK)
2768  nspname);
2769  /* Schema search hook for this lookup */
2770  InvokeNamespaceSearchHook(namespaceId, true);
2771 
2772  return namespaceId;
2773 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2895
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:4484
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:174
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
#define ACL_USAGE
Definition: parsenodes.h:80
AclResult
Definition: acl.h:170
#define InvalidOid
Definition: postgres_ext.h:36
Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2713 of file namespace.c.

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

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

2714 {
2715  /* check for pg_temp alias */
2716  if (strcmp(nspname, "pg_temp") == 0)
2717  {
2719  {
2721  return myTempNamespace;
2722  }
2723 
2724  /*
2725  * Since this is used only for looking up existing objects, there is
2726  * no point in trying to initialize the temp namespace here; and doing
2727  * so might create problems for some callers. Just report "not found".
2728  */
2729  return InvalidOid;
2730  }
2731 
2732  return get_namespace_oid(nspname, true);
2733 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2895
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 2913 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(), generateSerialExtraStmts(), get_object_address_attrdef(), get_object_address_attribute(), get_object_address_publication_rel(), get_object_address_relobject(), get_raw_page_internal(), get_rel_from_relname(), get_relation_by_qualified_name(), nextval(), owningrel_does_not_exist_skipping(), pg_get_serial_sequence(), pg_get_viewdef_name(), pg_get_viewdef_name_ext(), pg_relpages(), pg_relpages_v1_5(), pgrowlocks(), pgstatindex(), pgstatindex_v1_5(), pgstattuple(), pgstattuple_v1_5(), process_owned_by(), regclassin(), RelationNameGetTupleDesc(), RemoveRelations(), row_security_active_name(), schema_does_not_exist_skipping(), text_regclass(), and to_regclass().

2914 {
2915  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
2916 
2917  switch (list_length(names))
2918  {
2919  case 1:
2920  rel->relname = strVal(linitial(names));
2921  break;
2922  case 2:
2923  rel->schemaname = strVal(linitial(names));
2924  rel->relname = strVal(lsecond(names));
2925  break;
2926  case 3:
2927  rel->catalogname = strVal(linitial(names));
2928  rel->schemaname = strVal(lsecond(names));
2929  rel->relname = strVal(lthird(names));
2930  break;
2931  default:
2932  ereport(ERROR,
2933  (errcode(ERRCODE_SYNTAX_ERROR),
2934  errmsg("improper relation name (too many dotted names): %s",
2935  NameListToString(names))));
2936  break;
2937  }
2938 
2939  return rel;
2940 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
#define lsecond(l)
Definition: pg_list.h:116
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:2953
#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:121
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:1278
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 2987 of file namespace.c.

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

2988 {
2990  ListCell *l;
2991 
2992  initStringInfo(&string);
2993 
2994  foreach(l, names)
2995  {
2996  if (l != list_head(names))
2997  appendStringInfoChar(&string, '.');
2999  }
3000 
3001  return string.data;
3002 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10246
#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 2953 of file namespace.c.

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

Referenced by AggregateCreate(), AlterCollation(), AlterFunction(), AlterTSConfiguration(), AlterTSDictionary(), check_object_ownership(), CreateConversionCommand(), CreateEventTrigger(), CreateProceduralLanguage(), CreateTransform(), CreateTrigger(), DeconstructQualifiedName(), defGetString(), DefineOperator(), DefineType(), does_not_exist_skipping(), dropOperators(), dropProcedures(), ExpandColumnRefStar(), findRangeSubOpclass(), findTypeAnalyzeFunction(), findTypeInputFunction(), findTypeOutputFunction(), findTypeTypmodinFunction(), findTypeTypmodoutFunction(), func_signature_string(), get_collation_oid(), get_conversion_oid(), get_object_address_attrdef(), get_object_address_attribute(), get_statistics_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), lookup_fdw_handler_func(), lookup_index_am_handler_func(), 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().

2954 {
2956  ListCell *l;
2957 
2958  initStringInfo(&string);
2959 
2960  foreach(l, names)
2961  {
2962  Node *name = (Node *) lfirst(l);
2963 
2964  if (l != list_head(names))
2965  appendStringInfoChar(&string, '.');
2966 
2967  if (IsA(name, String))
2968  appendStringInfoString(&string, strVal(name));
2969  else if (IsA(name, A_Star))
2970  appendStringInfoChar(&string, '*');
2971  else
2972  elog(ERROR, "unexpected node type in name list: %d",
2973  (int) nodeTag(name));
2974  }
2975 
2976  return string.data;
2977 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Definition: nodes.h:509
#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:514
#define elog
Definition: elog.h:219
static void NamespaceCallback ( Datum  arg,
int  cacheid,
uint32  hashvalue 
)
static

Definition at line 4056 of file namespace.c.

References baseSearchPathValid.

Referenced by InitializeSearchPath().

4057 {
4058  /* Force search path to be recomputed on next use */
4059  baseSearchPathValid = false;
4060 }
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:152
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:1116
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:183
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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:152
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#define list_make1(x1)
Definition: pg_list.h:139
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:1116
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:2743
#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:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
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:197
#define SPACE_PER_OP
struct _FuncCandidateList * next
Definition: namespace.h:30
#define ReleaseSysCacheList(x)
Definition: syscache.h:206
#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, result, 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:2743
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SearchSysCache4(cacheId, key1, key2, key3, key4)
Definition: syscache.h:158
static Oid myTempNamespace
Definition: namespace.c:180
return result
Definition: formatting.c:1618
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
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:206
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1116
#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:201
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:152
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
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:1116
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:183
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
#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 3223 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().

3224 {
3225  ListCell *lc,
3226  *lcp;
3227 
3229 
3230  /* We scan down the activeSearchPath to see if it matches the input. */
3232 
3233  /* If path->addTemp, first item should be my temp namespace. */
3234  if (path->addTemp)
3235  {
3236  if (lc && lfirst_oid(lc) == myTempNamespace)
3237  lc = lnext(lc);
3238  else
3239  return false;
3240  }
3241  /* If path->addCatalog, next item should be pg_catalog. */
3242  if (path->addCatalog)
3243  {
3244  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3245  lc = lnext(lc);
3246  else
3247  return false;
3248  }
3249  /* We should now be looking at the activeCreationNamespace. */
3250  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3251  return false;
3252  /* The remainder of activeSearchPath should match path->schemas. */
3253  foreach(lcp, path->schemas)
3254  {
3255  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3256  lc = lnext(lc);
3257  else
3258  return false;
3259  }
3260  if (lc)
3261  return false;
3262  return true;
3263 }
static Oid myTempNamespace
Definition: namespace.c:180
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
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 4217 of file namespace.c.

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

4218 {
4219  Oid oid = PG_GETARG_OID(0);
4220 
4222  PG_RETURN_NULL();
4223 
4225 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
bool CollationIsVisible(Oid collid)
Definition: namespace.c:1965
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_conversion_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4228 of file namespace.c.

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

4229 {
4230  Oid oid = PG_GETARG_OID(0);
4231 
4233  PG_RETURN_NULL();
4234 
4236 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
bool ConversionIsVisible(Oid conid)
Definition: namespace.c:2047
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4173 of file namespace.c.

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

4174 {
4175  Oid oid = PG_GETARG_OID(0);
4176 
4178  PG_RETURN_NULL();
4179 
4181 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1373
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_is_other_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4289 of file namespace.c.

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

4290 {
4291  Oid oid = PG_GETARG_OID(0);
4292 
4294 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
bool isOtherTempNamespace(Oid namespaceId)
Definition: namespace.c:3069
Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4283 of file namespace.c.

References myTempNamespace, and PG_RETURN_OID.

4284 {
4286 }
static Oid myTempNamespace
Definition: namespace.c:180
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
Datum pg_opclass_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4195 of file namespace.c.

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

4196 {
4197  Oid oid = PG_GETARG_OID(0);
4198 
4200  PG_RETURN_NULL();
4201 
4203 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
bool OpclassIsVisible(Oid opcid)
Definition: namespace.c:1792
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4184 of file namespace.c.

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

4185 {
4186  Oid oid = PG_GETARG_OID(0);
4187 
4189  PG_RETURN_NULL();
4190 
4192 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1706
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_opfamily_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4206 of file namespace.c.

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

4207 {
4208  Oid oid = PG_GETARG_OID(0);
4209 
4211  PG_RETURN_NULL();
4212 
4214 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
bool OpfamilyIsVisible(Oid opfid)
Definition: namespace.c:1875
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_table_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4151 of file namespace.c.

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

4152 {
4153  Oid oid = PG_GETARG_OID(0);
4154 
4156  PG_RETURN_NULL();
4157 
4159 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
bool RelationIsVisible(Oid relid)
Definition: namespace.c:681
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_ts_config_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4272 of file namespace.c.

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

4273 {
4274  Oid oid = PG_GETARG_OID(0);
4275 
4277  PG_RETURN_NULL();
4278 
4280 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2587
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_ts_dict_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4250 of file namespace.c.

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

4251 {
4252  Oid oid = PG_GETARG_OID(0);
4253 
4255  PG_RETURN_NULL();
4256 
4258 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2334
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_ts_parser_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4239 of file namespace.c.

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

4240 {
4241  Oid oid = PG_GETARG_OID(0);
4242 
4244  PG_RETURN_NULL();
4245 
4247 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
bool TSParserIsVisible(Oid prsId)
Definition: namespace.c:2208
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4261 of file namespace.c.

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

4262 {
4263  Oid oid = PG_GETARG_OID(0);
4264 
4266  PG_RETURN_NULL();
4267 
4269 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
bool TSTemplateIsVisible(Oid tmplId)
Definition: namespace.c:2461
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4162 of file namespace.c.

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

4163 {
4164  Oid oid = PG_GETARG_OID(0);
4165 
4167  PG_RETURN_NULL();
4168 
4170 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:170
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
bool TypeIsVisible(Oid typid)
Definition: namespace.c:776
#define PG_RETURN_NULL()
Definition: fmgr.h:305
void PopOverrideSearchPath ( void  )

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

3343 {
3344  OverrideStackEntry *entry;
3345 
3346  /* Sanity checks. */
3347  if (overrideStack == NIL)
3348  elog(ERROR, "bogus PopOverrideSearchPath call");
3350  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3351  elog(ERROR, "bogus PopOverrideSearchPath call");
3352 
3353  /* Pop the stack and free storage. */
3355  list_free(entry->searchPath);
3356  pfree(entry);
3357 
3358  /* Activate the next level down. */
3359  if (overrideStack)
3360  {
3362  activeSearchPath = entry->searchPath;
3364  activeTempCreationPending = false; /* XXX is this OK? */
3365  }
3366  else
3367  {
3368  /* If not baseSearchPathValid, this is useless but harmless */
3372  }
3373 }
#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:111
#define ERROR
Definition: elog.h:43
static bool baseTempCreationPending
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:139
static Oid baseCreationNamespace
Definition: namespace.c:145
static List * baseSearchPath
Definition: namespace.c:143
int GetCurrentTransactionNestLevel(void)
Definition: xact.c: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 3283 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().

3284 {
3285  OverrideStackEntry *entry;
3286  List *oidlist;
3287  Oid firstNS;
3288  MemoryContext oldcxt;
3289 
3290  /*
3291  * Copy the list for safekeeping, and insert implicitly-searched
3292  * namespaces as needed. This code should track recomputeNamespacePath.
3293  */
3295 
3296  oidlist = list_copy(newpath->schemas);
3297 
3298  /*
3299  * Remember the first member of the explicit list.
3300  */
3301  if (oidlist == NIL)
3302  firstNS = InvalidOid;
3303  else
3304  firstNS = linitial_oid(oidlist);
3305 
3306  /*
3307  * Add any implicitly-searched namespaces to the list. Note these go on
3308  * the front, not the back; also notice that we do not check USAGE
3309  * permissions for these.
3310  */
3311  if (newpath->addCatalog)
3312  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3313 
3314  if (newpath->addTemp && OidIsValid(myTempNamespace))
3315  oidlist = lcons_oid(myTempNamespace, oidlist);
3316 
3317  /*
3318  * Build the new stack entry, then insert it at the head of the list.
3319  */
3320  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3321  entry->searchPath = oidlist;
3322  entry->creationNamespace = firstNS;
3324 
3325  overrideStack = lcons(entry, overrideStack);
3326 
3327  /* And make it active. */
3328  activeSearchPath = entry->searchPath;
3330  activeTempCreationPending = false; /* XXX is this OK? */
3331 
3332  MemoryContextSwitchTo(oldcxt);
3333 }
#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:113
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 2846 of file namespace.c.

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

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

2847 {
2848  char *schemaname;
2849  Oid namespaceId;
2850 
2851  /* deconstruct the name list */
2852  DeconstructQualifiedName(names, &schemaname, objname_p);
2853 
2854  if (schemaname)
2855  {
2856  /* check for pg_temp alias */
2857  if (strcmp(schemaname, "pg_temp") == 0)
2858  {
2859  /* Initialize temp namespace if first time through */
2862  return myTempNamespace;
2863  }
2864  /* use exact schema given */
2865  namespaceId = get_namespace_oid(schemaname, false);
2866  /* we do not check for USAGE rights here! */
2867  }
2868  else
2869  {
2870  /* use the default creation namespace */
2873  {
2874  /* Need to initialize temp namespace */
2876  return myTempNamespace;
2877  }
2878  namespaceId = activeCreationNamespace;
2879  if (!OidIsValid(namespaceId))
2880  ereport(ERROR,
2881  (errcode(ERRCODE_UNDEFINED_SCHEMA),
2882  errmsg("no schema has been selected to create in")));
2883  }
2884 
2885  return namespaceId;
2886 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2895
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:2659
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
static void recomputeNamespacePath(void)
Definition: namespace.c:3535
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:3685
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(), generateSerialExtraStmts(), and RangeVarGetAndCheckCreationNamespace().

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:3032
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:3046
#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:4484
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:82
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1683
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3038
#define NoLock
Definition: lockdefs.h:34
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
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:4546
#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(), generateSerialExtraStmts(), and RangeVarGetAndCheckCreationNamespace().

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:2895
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:3535
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:2056
static bool activeTempCreationPending
Definition: namespace.c:139
#define ereport(elevel, rest)
Definition: elog.h:122
static void InitTempTableNamespace(void)
Definition: namespace.c:3685
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:2743
#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:1683
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
#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 3535 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_statistics_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().

3536 {
3537  Oid roleid = GetUserId();
3538  char *rawname;
3539  List *namelist;
3540  List *oidlist;
3541  List *newpath;
3542  ListCell *l;
3543  bool temp_missing;
3544  Oid firstNS;
3545  MemoryContext oldcxt;
3546 
3547  /* Do nothing if an override search spec is active. */
3548  if (overrideStack)
3549  return;
3550 
3551  /* Do nothing if path is already valid. */
3552  if (baseSearchPathValid && namespaceUser == roleid)
3553  return;
3554 
3555  /* Need a modifiable copy of namespace_search_path string */
3556  rawname = pstrdup(namespace_search_path);
3557 
3558  /* Parse string into list of identifiers */
3559  if (!SplitIdentifierString(rawname, ',', &namelist))
3560  {
3561  /* syntax error in name list */
3562  /* this should not happen if GUC checked check_search_path */
3563  elog(ERROR, "invalid list syntax");
3564  }
3565 
3566  /*
3567  * Convert the list of names to a list of OIDs. If any names are not
3568  * recognizable or we don't have read access, just leave them out of the
3569  * list. (We can't raise an error, since the search_path setting has
3570  * already been accepted.) Don't make duplicate entries, either.
3571  */
3572  oidlist = NIL;
3573  temp_missing = false;
3574  foreach(l, namelist)
3575  {
3576  char *curname = (char *) lfirst(l);
3577  Oid namespaceId;
3578 
3579  if (strcmp(curname, "$user") == 0)
3580  {
3581  /* $user --- substitute namespace matching user name, if any */
3582  HeapTuple tuple;
3583 
3584  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
3585  if (HeapTupleIsValid(tuple))
3586  {
3587  char *rname;
3588 
3589  rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
3590  namespaceId = get_namespace_oid(rname, true);
3591  ReleaseSysCache(tuple);
3592  if (OidIsValid(namespaceId) &&
3593  !list_member_oid(oidlist, namespaceId) &&
3594  pg_namespace_aclcheck(namespaceId, roleid,
3595  ACL_USAGE) == ACLCHECK_OK &&
3596  InvokeNamespaceSearchHook(namespaceId, false))
3597  oidlist = lappend_oid(oidlist, namespaceId);
3598  }
3599  }
3600  else if (strcmp(curname, "pg_temp") == 0)
3601  {
3602  /* pg_temp --- substitute temp namespace, if any */
3604  {
3605  if (!list_member_oid(oidlist, myTempNamespace) &&
3607  oidlist = lappend_oid(oidlist, myTempNamespace);
3608  }
3609  else
3610  {
3611  /* If it ought to be the creation namespace, set flag */
3612  if (oidlist ==