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_statistic_ext.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_ts_parser.h"
#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "funcapi.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_func.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/sinval.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/catcache.h"
#include "utils/guc.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/syscache.h"
#include "utils/varlena.h"
Include dependency graph for namespace.c:

Go to the source code of this file.

Data Structures

struct  OverrideStackEntry
 

Macros

#define SPACE_PER_OP
 

Functions

static void recomputeNamespacePath (void)
 
static void InitTempTableNamespace (void)
 
static void RemoveTempRelations (Oid tempNamespaceId)
 
static void RemoveTempRelationsCallback (int code, Datum arg)
 
static void NamespaceCallback (Datum arg, int cacheid, uint32 hashvalue)
 
static bool MatchNamedCall (HeapTuple proctup, int nargs, List *argnames, int **argnumbers)
 
Oid RangeVarGetRelidExtended (const RangeVar *relation, LOCKMODE lockmode, 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_object_oid (List *names, bool missing_ok)
 
bool StatisticsObjIsVisible (Oid relid)
 
Oid get_ts_parser_oid (List *names, bool missing_ok)
 
bool TSParserIsVisible (Oid prsId)
 
Oid get_ts_dict_oid (List *names, bool missing_ok)
 
bool TSDictionaryIsVisible (Oid dictId)
 
Oid get_ts_template_oid (List *names, bool missing_ok)
 
bool TSTemplateIsVisible (Oid tmplId)
 
Oid get_ts_config_oid (List *names, bool missing_ok)
 
bool TSConfigIsVisible (Oid cfgid)
 
void DeconstructQualifiedName (List *names, char **nspname_p, char **objname_p)
 
Oid LookupNamespaceNoError (const char *nspname)
 
Oid LookupExplicitNamespace (const char *nspname, bool missing_ok)
 
Oid LookupCreationNamespace (const char *nspname)
 
void CheckSetNamespace (Oid oldNspOid, Oid nspOid)
 
Oid QualifiedNameGetCreationNamespace (List *names, char **objname_p)
 
Oid get_namespace_oid (const char *nspname, bool missing_ok)
 
RangeVarmakeRangeVarFromNameList (List *names)
 
char * NameListToString (List *names)
 
char * NameListToQuotedString (List *names)
 
bool isTempNamespace (Oid namespaceId)
 
bool isTempToastNamespace (Oid namespaceId)
 
bool isTempOrTempToastNamespace (Oid namespaceId)
 
bool isAnyTempNamespace (Oid namespaceId)
 
bool isOtherTempNamespace (Oid namespaceId)
 
int GetTempNamespaceBackendId (Oid namespaceId)
 
Oid GetTempToastNamespace (void)
 
void GetTempNamespaceState (Oid *tempNamespaceId, Oid *tempToastNamespaceId)
 
void SetTempNamespaceState (Oid tempNamespaceId, Oid tempToastNamespaceId)
 
OverrideSearchPathGetOverrideSearchPath (MemoryContext context)
 
OverrideSearchPathCopyOverrideSearchPath (OverrideSearchPath *path)
 
bool OverrideSearchPathMatchesCurrent (OverrideSearchPath *path)
 
void PushOverrideSearchPath (OverrideSearchPath *newpath)
 
void PopOverrideSearchPath (void)
 
Oid get_collation_oid (List *name, bool missing_ok)
 
Oid get_conversion_oid (List *name, bool missing_ok)
 
Oid FindDefaultConversionProc (int32 for_encoding, int32 to_encoding)
 
void AtEOXact_Namespace (bool isCommit, bool parallel)
 
void AtEOSubXact_Namespace (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void ResetTempTableNamespace (void)
 
bool check_search_path (char **newval, void **extra, GucSource source)
 
void assign_search_path (const char *newval, void *extra)
 
void InitializeSearchPath (void)
 
Listfetch_search_path (bool includeImplicit)
 
int fetch_search_path_array (Oid *sarray, int sarray_len)
 
Datum pg_table_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_type_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_function_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_operator_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_opclass_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_opfamily_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_collation_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_conversion_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_statistics_obj_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_parser_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_dict_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_template_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_config_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_my_temp_schema (PG_FUNCTION_ARGS)
 
Datum pg_is_other_temp_schema (PG_FUNCTION_ARGS)
 

Variables

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

Macro Definition Documentation

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

References baseSearchPathValid.

4068 {
4069  /*
4070  * We mark the path as needing recomputation, but don't do anything until
4071  * it's needed. This avoids trying to do database access during GUC
4072  * initialization, or outside a transaction.
4073  */
4074  baseSearchPathValid = false;
4075 }
static bool baseSearchPathValid
Definition: namespace.c:153
void AtEOSubXact_Namespace ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

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

3918 {
3919  OverrideStackEntry *entry;
3920 
3921  if (myTempNamespaceSubID == mySubid)
3922  {
3923  if (isCommit)
3924  myTempNamespaceSubID = parentSubid;
3925  else
3926  {
3928  /* TEMP namespace creation failed, so reset state */
3931  baseSearchPathValid = false; /* need to rebuild list */
3932  }
3933  }
3934 
3935  /*
3936  * Clean up if someone failed to do PopOverrideSearchPath
3937  */
3938  while (overrideStack)
3939  {
3942  break;
3943  if (isCommit)
3944  elog(WARNING, "leaked override search path");
3946  list_free(entry->searchPath);
3947  pfree(entry);
3948  }
3949 
3950  /* Activate the next level down. */
3951  if (overrideStack)
3952  {
3954  activeSearchPath = entry->searchPath;
3956  activeTempCreationPending = false; /* XXX is this OK? */
3957  }
3958  else
3959  {
3960  /* If not baseSearchPathValid, this is useless but harmless */
3964  }
3965 }
static bool baseSearchPathValid
Definition: namespace.c:153
static Oid myTempToastNamespace
Definition: namespace.c:183
static Oid myTempNamespace
Definition: namespace.c:181
static List * overrideStack
Definition: namespace.c:164
static Oid activeCreationNamespace
Definition: namespace.c:137
void pfree(void *pointer)
Definition: mcxt.c:950
#define linitial(l)
Definition: pg_list.h:111
static bool baseTempCreationPending
Definition: namespace.c:148
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:185
static bool activeTempCreationPending
Definition: namespace.c:140
static Oid baseCreationNamespace
Definition: namespace.c:146
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:144
#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:134
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 3861 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().

3862 {
3863  /*
3864  * If we abort the transaction in which a temp namespace was selected,
3865  * we'll have to do any creation or cleanout work over again. So, just
3866  * forget the namespace entirely until next time. On the other hand, if
3867  * we commit then register an exit callback to clean out the temp tables
3868  * at backend shutdown. (We only want to register the callback once per
3869  * session, so this is a good place to do it.)
3870  */
3871  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
3872  {
3873  if (isCommit)
3875  else
3876  {
3879  baseSearchPathValid = false; /* need to rebuild list */
3880  }
3882  }
3883 
3884  /*
3885  * Clean up if someone failed to do PopOverrideSearchPath
3886  */
3887  if (overrideStack)
3888  {
3889  if (isCommit)
3890  elog(WARNING, "leaked override search path");
3891  while (overrideStack)
3892  {
3893  OverrideStackEntry *entry;
3894 
3897  list_free(entry->searchPath);
3898  pfree(entry);
3899  }
3900  /* If not baseSearchPathValid, this is useless but harmless */
3904  }
3905 }
static bool baseSearchPathValid
Definition: namespace.c:153
static Oid myTempToastNamespace
Definition: namespace.c:183
static Oid myTempNamespace
Definition: namespace.c:181
static List * overrideStack
Definition: namespace.c:164
static Oid activeCreationNamespace
Definition: namespace.c:137
void pfree(void *pointer)
Definition: mcxt.c:950
#define linitial(l)
Definition: pg_list.h:111
static bool baseTempCreationPending
Definition: namespace.c:148
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:320
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:185
static bool activeTempCreationPending
Definition: namespace.c:140
static Oid baseCreationNamespace
Definition: namespace.c:146
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:144
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidSubTransactionId
Definition: c.h:403
static List * activeSearchPath
Definition: namespace.c:134
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:4002
List * list_delete_first(List *list)
Definition: list.c:666
bool check_search_path ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 4033 of file namespace.c.

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

4034 {
4035  char *rawname;
4036  List *namelist;
4037 
4038  /* Need a modifiable copy of string */
4039  rawname = pstrdup(*newval);
4040 
4041  /* Parse string into list of identifiers */
4042  if (!SplitIdentifierString(rawname, ',', &namelist))
4043  {
4044  /* syntax error in name list */
4045  GUC_check_errdetail("List syntax is invalid.");
4046  pfree(rawname);
4047  list_free(namelist);
4048  return false;
4049  }
4050 
4051  /*
4052  * We used to try to check that the named schemas exist, but there are
4053  * many valid use-cases for having search_path settings that include
4054  * schemas that don't exist; and often, we are not inside a transaction
4055  * here and so can't consult the system catalogs anyway. So now, the only
4056  * requirement is syntactic validity of the identifier list.
4057  */
4058 
4059  pfree(rawname);
4060  list_free(namelist);
4061 
4062  return true;
4063 }
#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:3247
#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 2885 of file namespace.c.

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

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

2886 {
2887  /* disallow renaming into or out of temp schemas */
2888  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2889  ereport(ERROR,
2890  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2891  errmsg("cannot move objects into or out of temporary schemas")));
2892 
2893  /* same for TOAST schema */
2894  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
2895  ereport(ERROR,
2896  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2897  errmsg("cannot move objects into or out of TOAST schema")));
2898 }
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:3113
Oid CollationGetCollid ( const char *  collname)

Definition at line 1923 of file namespace.c.

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

Referenced by CollationIsVisible().

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

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

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

Definition at line 2016 of file namespace.c.

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

Referenced by ConversionIsVisible().

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

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

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

Definition at line 3274 of file namespace.c.

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

Referenced by CopyCachedPlan().

3275 {
3277 
3278  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3279  result->schemas = list_copy(path->schemas);
3280  result->addCatalog = path->addCatalog;
3281  result->addTemp = path->addTemp;
3282 
3283  return result;
3284 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
return result
Definition: formatting.c:1632
void * palloc(Size size)
Definition: mcxt.c:849
void DeconstructQualifiedName ( List names,
char **  nspname_p,
char **  objname_p 
)

Definition at line 2726 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_object_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), LookupTypeName(), make_oper_cache_key(), OpClassCacheLookup(), OpernameGetCandidates(), OpernameGetOprid(), OpFamilyCacheLookup(), QualifiedNameGetCreationNamespace(), and ResolveOpClass().

2729 {
2730  char *catalogname;
2731  char *schemaname = NULL;
2732  char *objname = NULL;
2733 
2734  switch (list_length(names))
2735  {
2736  case 1:
2737  objname = strVal(linitial(names));
2738  break;
2739  case 2:
2740  schemaname = strVal(linitial(names));
2741  objname = strVal(lsecond(names));
2742  break;
2743  case 3:
2744  catalogname = strVal(linitial(names));
2745  schemaname = strVal(lsecond(names));
2746  objname = strVal(lthird(names));
2747 
2748  /*
2749  * We check the catalog name and then ignore it.
2750  */
2751  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2752  ereport(ERROR,
2753  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2754  errmsg("cross-database references are not implemented: %s",
2755  NameListToString(names))));
2756  break;
2757  default:
2758  ereport(ERROR,
2759  (errcode(ERRCODE_SYNTAX_ERROR),
2760  errmsg("improper qualified name (too many dotted names): %s",
2761  NameListToString(names))));
2762  break;
2763  }
2764 
2765  *nspname_p = schemaname;
2766  *objname_p = objname;
2767 }
#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:3020
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 4141 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().

4142 {
4143  List *result;
4144 
4146 
4147  /*
4148  * If the temp namespace should be first, force it to exist. This is so
4149  * that callers can trust the result to reflect the actual default
4150  * creation namespace. It's a bit bogus to do this here, since
4151  * current_schema() is supposedly a stable function without side-effects,
4152  * but the alternatives seem worse.
4153  */
4155  {
4158  }
4159 
4160  result = list_copy(activeSearchPath);
4161  if (!includeImplicit)
4162  {
4163  while (result && linitial_oid(result) != activeCreationNamespace)
4164  result = list_delete_first(result);
4165  }
4166 
4167  return result;
4168 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
return result
Definition: formatting.c:1632
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
static Oid activeCreationNamespace
Definition: namespace.c:137
static bool activeTempCreationPending
Definition: namespace.c:140
static void InitTempTableNamespace(void)
Definition: namespace.c:3752
#define linitial_oid(l)
Definition: pg_list.h:113
static List * activeSearchPath
Definition: namespace.c:134
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 4181 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4182 {
4183  int count = 0;
4184  ListCell *l;
4185 
4187 
4188  foreach(l, activeSearchPath)
4189  {
4190  Oid namespaceId = lfirst_oid(l);
4191 
4192  if (namespaceId == myTempNamespace)
4193  continue; /* do not include temp namespace */
4194 
4195  if (count < sarray_len)
4196  sarray[count] = namespaceId;
4197  count++;
4198  }
4199 
4200  return count;
4201 }
static Oid myTempNamespace
Definition: namespace.c:181
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
static List * activeSearchPath
Definition: namespace.c:134
#define lfirst_oid(lc)
Definition: pg_list.h:108
Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3575 of file namespace.c.

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

Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().

3576 {
3577  Oid proc;
3578  ListCell *l;
3579 
3581 
3582  foreach(l, activeSearchPath)
3583  {
3584  Oid namespaceId = lfirst_oid(l);
3585 
3586  if (namespaceId == myTempNamespace)
3587  continue; /* do not look in temp namespace */
3588 
3589  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3590  if (OidIsValid(proc))
3591  return proc;
3592  }
3593 
3594  /* Not found in path */
3595  return InvalidOid;
3596 }
static Oid myTempNamespace
Definition: namespace.c:181
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:134
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 903 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().

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

1375 {
1376  HeapTuple proctup;
1377  Form_pg_proc procform;
1378  Oid pronamespace;
1379  bool visible;
1380 
1381  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1382  if (!HeapTupleIsValid(proctup))
1383  elog(ERROR, "cache lookup failed for function %u", funcid);
1384  procform = (Form_pg_proc) GETSTRUCT(proctup);
1385 
1387 
1388  /*
1389  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1390  * the system namespace are surely in the path and so we needn't even do
1391  * list_member_oid() for them.
1392  */
1393  pronamespace = procform->pronamespace;
1394  if (pronamespace != PG_CATALOG_NAMESPACE &&
1395  !list_member_oid(activeSearchPath, pronamespace))
1396  visible = false;
1397  else
1398  {
1399  /*
1400  * If it is in the path, it might still not be visible; it could be
1401  * hidden by another proc of the same name and arguments earlier in
1402  * the path. So we must do a slow check to see if this is the same
1403  * proc that would be found by FuncnameGetCandidates.
1404  */
1405  char *proname = NameStr(procform->proname);
1406  int nargs = procform->pronargs;
1407  FuncCandidateList clist;
1408 
1409  visible = false;
1410 
1411  clist = FuncnameGetCandidates(list_make1(makeString(proname)),
1412  nargs, NIL, false, false, false);
1413 
1414  for (; clist; clist = clist->next)
1415  {
1416  if (memcmp(clist->args, procform->proargtypes.values,
1417  nargs * sizeof(Oid)) == 0)
1418  {
1419  /* Found the expected entry; is it the right proc? */
1420  visible = (clist->oid == funcid);
1421  break;
1422  }
1423  }
1424  }
1425 
1426  ReleaseSysCache(proctup);
1427 
1428  return visible;
1429 }
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:156
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#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:903
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
struct _FuncCandidateList * next
Definition: namespace.h:30
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
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:134
#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 3447 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().

3448 {
3449  char *schemaname;
3450  char *collation_name;
3451  int32 dbencoding = GetDatabaseEncoding();
3452  Oid namespaceId;
3453  Oid colloid;
3454  ListCell *l;
3455 
3456  /* deconstruct the name list */
3457  DeconstructQualifiedName(name, &schemaname, &collation_name);
3458 
3459  if (schemaname)
3460  {
3461  /* use exact schema given */
3462  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3463  if (missing_ok && !OidIsValid(namespaceId))
3464  return InvalidOid;
3465 
3466  /* first try for encoding-specific entry, then any-encoding */
3467  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3468  PointerGetDatum(collation_name),
3469  Int32GetDatum(dbencoding),
3470  ObjectIdGetDatum(namespaceId));
3471  if (OidIsValid(colloid))
3472  return colloid;
3473  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3474  PointerGetDatum(collation_name),
3475  Int32GetDatum(-1),
3476  ObjectIdGetDatum(namespaceId));
3477  if (OidIsValid(colloid))
3478  return colloid;
3479  }
3480  else
3481  {
3482  /* search for it in search path */
3484 
3485  foreach(l, activeSearchPath)
3486  {
3487  namespaceId = lfirst_oid(l);
3488 
3489  if (namespaceId == myTempNamespace)
3490  continue; /* do not look in temp namespace */
3491 
3492  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3493  PointerGetDatum(collation_name),
3494  Int32GetDatum(dbencoding),
3495  ObjectIdGetDatum(namespaceId));
3496  if (OidIsValid(colloid))
3497  return colloid;
3498  colloid = GetSysCacheOid3(COLLNAMEENCNSP,
3499  PointerGetDatum(collation_name),
3500  Int32GetDatum(-1),
3501  ObjectIdGetDatum(namespaceId));
3502  if (OidIsValid(colloid))
3503  return colloid;
3504  }
3505  }
3506 
3507  /* Not found in path */
3508  if (!missing_ok)
3509  ereport(ERROR,
3510  (errcode(ERRCODE_UNDEFINED_OBJECT),
3511  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3513  return InvalidOid;
3514 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2810
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:181
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2726
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:187
signed int int32
Definition: c.h:256
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#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:3020
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:134
#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 3520 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().

3521 {
3522  char *schemaname;
3523  char *conversion_name;
3524  Oid namespaceId;
3525  Oid conoid = InvalidOid;
3526  ListCell *l;
3527 
3528  /* deconstruct the name list */
3529  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3530 
3531  if (schemaname)
3532  {
3533  /* use exact schema given */
3534  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3535  if (missing_ok && !OidIsValid(namespaceId))
3536  conoid = InvalidOid;
3537  else
3538  conoid = GetSysCacheOid2(CONNAMENSP,
3539  PointerGetDatum(conversion_name),
3540  ObjectIdGetDatum(namespaceId));
3541  }
3542  else
3543  {
3544  /* search for it in search path */
3546 
3547  foreach(l, activeSearchPath)
3548  {
3549  namespaceId = lfirst_oid(l);
3550 
3551  if (namespaceId == myTempNamespace)
3552  continue; /* do not look in temp namespace */
3553 
3554  conoid = GetSysCacheOid2(CONNAMENSP,
3555  PointerGetDatum(conversion_name),
3556  ObjectIdGetDatum(namespaceId));
3557  if (OidIsValid(conoid))
3558  return conoid;
3559  }
3560  }
3561 
3562  /* Not found in path */
3563  if (!OidIsValid(conoid) && !missing_ok)
3564  ereport(ERROR,
3565  (errcode(ERRCODE_UNDEFINED_OBJECT),
3566  errmsg("conversion \"%s\" does not exist",
3567  NameListToString(name))));
3568  return conoid;
3569 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2810
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:181
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2726
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:185
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#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:3020
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:134
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 2962 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().

2963 {
2964  Oid oid;
2965 
2967  if (!OidIsValid(oid) && !missing_ok)
2968  ereport(ERROR,
2969  (errcode(ERRCODE_UNDEFINED_SCHEMA),
2970  errmsg("schema \"%s\" does not exist", nspname)));
2971 
2972  return oid;
2973 }
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:183
#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_object_oid ( List names,
bool  missing_ok 
)

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

2096 {
2097  char *schemaname;
2098  char *stats_name;
2099  Oid namespaceId;
2100  Oid stats_oid = InvalidOid;
2101  ListCell *l;
2102 
2103  /* deconstruct the name list */
2104  DeconstructQualifiedName(names, &schemaname, &stats_name);
2105 
2106  if (schemaname)
2107  {
2108  /* use exact schema given */
2109  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2110  if (missing_ok && !OidIsValid(namespaceId))
2111  stats_oid = InvalidOid;
2112  else
2113  stats_oid = GetSysCacheOid2(STATEXTNAMENSP,
2114  PointerGetDatum(stats_name),
2115  ObjectIdGetDatum(namespaceId));
2116  }
2117  else
2118  {
2119  /* search for it in search path */
2121 
2122  foreach(l, activeSearchPath)
2123  {
2124  namespaceId = lfirst_oid(l);
2125 
2126  if (namespaceId == myTempNamespace)
2127  continue; /* do not look in temp namespace */
2128  stats_oid = GetSysCacheOid2(STATEXTNAMENSP,
2129  PointerGetDatum(stats_name),
2130  ObjectIdGetDatum(namespaceId));
2131  if (OidIsValid(stats_oid))
2132  break;
2133  }
2134  }
2135 
2136  if (!OidIsValid(stats_oid) && !missing_ok)
2137  ereport(ERROR,
2138  (errcode(ERRCODE_UNDEFINED_OBJECT),
2139  errmsg("statistics object \"%s\" does not exist",
2140  NameListToString(names))));
2141 
2142  return stats_oid;
2143 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2810
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:181
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2726
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:185
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#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:3020
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:134
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 2596 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().

2597 {
2598  char *schemaname;
2599  char *config_name;
2600  Oid namespaceId;
2601  Oid cfgoid = InvalidOid;
2602  ListCell *l;
2603 
2604  /* deconstruct the name list */
2605  DeconstructQualifiedName(names, &schemaname, &config_name);
2606 
2607  if (schemaname)
2608  {
2609  /* use exact schema given */
2610  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2611  if (missing_ok && !OidIsValid(namespaceId))
2612  cfgoid = InvalidOid;
2613  else
2615  PointerGetDatum(config_name),
2616  ObjectIdGetDatum(namespaceId));
2617  }
2618  else
2619  {
2620  /* search for it in search path */
2622 
2623  foreach(l, activeSearchPath)
2624  {
2625  namespaceId = lfirst_oid(l);
2626 
2627  if (namespaceId == myTempNamespace)
2628  continue; /* do not look in temp namespace */
2629 
2631  PointerGetDatum(config_name),
2632  ObjectIdGetDatum(namespaceId));
2633  if (OidIsValid(cfgoid))
2634  break;
2635  }
2636  }
2637 
2638  if (!OidIsValid(cfgoid) && !missing_ok)
2639  ereport(ERROR,
2640  (errcode(ERRCODE_UNDEFINED_OBJECT),
2641  errmsg("text search configuration \"%s\" does not exist",
2642  NameListToString(names))));
2643 
2644  return cfgoid;
2645 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2810
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:181
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2726
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:185
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#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:3020
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:134
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 2343 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().

2344 {
2345  char *schemaname;
2346  char *dict_name;
2347  Oid namespaceId;
2348  Oid dictoid = InvalidOid;
2349  ListCell *l;
2350 
2351  /* deconstruct the name list */
2352  DeconstructQualifiedName(names, &schemaname, &dict_name);
2353 
2354  if (schemaname)
2355  {
2356  /* use exact schema given */
2357  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2358  if (missing_ok && !OidIsValid(namespaceId))
2359  dictoid = InvalidOid;
2360  else
2361  dictoid = GetSysCacheOid2(TSDICTNAMENSP,
2362  PointerGetDatum(dict_name),
2363  ObjectIdGetDatum(namespaceId));
2364  }
2365  else
2366  {
2367  /* search for it in search path */
2369 
2370  foreach(l, activeSearchPath)
2371  {
2372  namespaceId = lfirst_oid(l);
2373 
2374  if (namespaceId == myTempNamespace)
2375  continue; /* do not look in temp namespace */
2376 
2377  dictoid = GetSysCacheOid2(TSDICTNAMENSP,
2378  PointerGetDatum(dict_name),
2379  ObjectIdGetDatum(namespaceId));
2380  if (OidIsValid(dictoid))
2381  break;
2382  }
2383  }
2384 
2385  if (!OidIsValid(dictoid) && !missing_ok)
2386  ereport(ERROR,
2387  (errcode(ERRCODE_UNDEFINED_OBJECT),
2388  errmsg("text search dictionary \"%s\" does not exist",
2389  NameListToString(names))));
2390 
2391  return dictoid;
2392 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2810
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:181
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2726
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:185
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#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:3020
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:134
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 2217 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().

2218 {
2219  char *schemaname;
2220  char *parser_name;
2221  Oid namespaceId;
2222  Oid prsoid = InvalidOid;
2223  ListCell *l;
2224 
2225  /* deconstruct the name list */
2226  DeconstructQualifiedName(names, &schemaname, &parser_name);
2227 
2228  if (schemaname)
2229  {
2230  /* use exact schema given */
2231  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2232  if (missing_ok && !OidIsValid(namespaceId))
2233  prsoid = InvalidOid;
2234  else
2236  PointerGetDatum(parser_name),
2237  ObjectIdGetDatum(namespaceId));
2238  }
2239  else
2240  {
2241  /* search for it in search path */
2243 
2244  foreach(l, activeSearchPath)
2245  {
2246  namespaceId = lfirst_oid(l);
2247 
2248  if (namespaceId == myTempNamespace)
2249  continue; /* do not look in temp namespace */
2250 
2252  PointerGetDatum(parser_name),
2253  ObjectIdGetDatum(namespaceId));
2254  if (OidIsValid(prsoid))
2255  break;
2256  }
2257  }
2258 
2259  if (!OidIsValid(prsoid) && !missing_ok)
2260  ereport(ERROR,
2261  (errcode(ERRCODE_UNDEFINED_OBJECT),
2262  errmsg("text search parser \"%s\" does not exist",
2263  NameListToString(names))));
2264 
2265  return prsoid;
2266 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2810
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:181
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2726
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:185
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#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:3020
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:134
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 2470 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().

2471 {
2472  char *schemaname;
2473  char *template_name;
2474  Oid namespaceId;
2475  Oid tmploid = InvalidOid;
2476  ListCell *l;
2477 
2478  /* deconstruct the name list */
2479  DeconstructQualifiedName(names, &schemaname, &template_name);
2480 
2481  if (schemaname)
2482  {
2483  /* use exact schema given */
2484  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2485  if (missing_ok && !OidIsValid(namespaceId))
2486  tmploid = InvalidOid;
2487  else
2489  PointerGetDatum(template_name),
2490  ObjectIdGetDatum(namespaceId));
2491  }
2492  else
2493  {
2494  /* search for it in search path */
2496 
2497  foreach(l, activeSearchPath)
2498  {
2499  namespaceId = lfirst_oid(l);
2500 
2501  if (namespaceId == myTempNamespace)
2502  continue; /* do not look in temp namespace */
2503 
2505  PointerGetDatum(template_name),
2506  ObjectIdGetDatum(namespaceId));
2507  if (OidIsValid(tmploid))
2508  break;
2509  }
2510  }
2511 
2512  if (!OidIsValid(tmploid) && !missing_ok)
2513  ereport(ERROR,
2514  (errcode(ERRCODE_UNDEFINED_OBJECT),
2515  errmsg("text search template \"%s\" does not exist",
2516  NameListToString(names))));
2517 
2518  return tmploid;
2519 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2810
#define PointerGetDatum(X)
Definition: postgres.h:562
static Oid myTempNamespace
Definition: namespace.c:181
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2726
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:185
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#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:3020
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:134
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 3238 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().

3239 {
3241  List *schemas;
3242  MemoryContext oldcxt;
3243 
3245 
3246  oldcxt = MemoryContextSwitchTo(context);
3247 
3248  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3249  schemas = list_copy(activeSearchPath);
3250  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3251  {
3252  if (linitial_oid(schemas) == myTempNamespace)
3253  result->addTemp = true;
3254  else
3255  {
3257  result->addCatalog = true;
3258  }
3259  schemas = list_delete_first(schemas);
3260  }
3261  result->schemas = schemas;
3262 
3263  MemoryContextSwitchTo(oldcxt);
3264 
3265  return result;
3266 }
static Oid myTempNamespace
Definition: namespace.c:181
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * list_copy(const List *oldlist)
Definition: list.c:1160
return result
Definition: formatting.c:1632
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
static Oid activeCreationNamespace
Definition: namespace.c:137
#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:134
Definition: pg_list.h:45
List * list_delete_first(List *list)
Definition: list.c:666
int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3152 of file namespace.c.

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

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

3153 {
3154  int result;
3155  char *nspname;
3156 
3157  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3158  nspname = get_namespace_name(namespaceId);
3159  if (!nspname)
3160  return InvalidBackendId; /* no such namespace? */
3161  if (strncmp(nspname, "pg_temp_", 8) == 0)
3162  result = atoi(nspname + 8);
3163  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3164  result = atoi(nspname + 14);
3165  else
3166  result = InvalidBackendId;
3167  pfree(nspname);
3168  return result;
3169 }
return result
Definition: formatting.c:1632
void pfree(void *pointer)
Definition: mcxt.c:950
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
#define InvalidBackendId
Definition: backendid.h:23
void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3191 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3192 {
3193  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3194  *tempNamespaceId = myTempNamespace;
3195  *tempToastNamespaceId = myTempToastNamespace;
3196 }
static Oid myTempToastNamespace
Definition: namespace.c:183
static Oid myTempNamespace
Definition: namespace.c:181
Oid GetTempToastNamespace ( void  )

Definition at line 3177 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3178 {
3180  return myTempToastNamespace;
3181 }
static Oid myTempToastNamespace
Definition: namespace.c:183
#define OidIsValid(objectId)
Definition: c.h:538
#define Assert(condition)
Definition: c.h:675
void InitializeSearchPath ( void  )

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

4084 {
4086  {
4087  /*
4088  * In bootstrap mode, the search path must be 'pg_catalog' so that
4089  * tables are created in the proper namespace; ignore the GUC setting.
4090  */
4091  MemoryContext oldcxt;
4092 
4095  MemoryContextSwitchTo(oldcxt);
4097  baseTempCreationPending = false;
4098  baseSearchPathValid = true;
4103  }
4104  else
4105  {
4106  /*
4107  * In normal mode, arrange for a callback on any syscache invalidation
4108  * of pg_namespace rows.
4109  */
4112  (Datum) 0);
4113  /* Force search path to be recomputed on next use */
4114  baseSearchPathValid = false;
4115  }
4116 }
static bool baseSearchPathValid
Definition: namespace.c:153
Oid GetUserId(void)
Definition: miscinit.c:283
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static Oid namespaceUser
Definition: namespace.c:150
static Oid activeCreationNamespace
Definition: namespace.c:137
static bool baseTempCreationPending
Definition: namespace.c:148
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4123
static bool activeTempCreationPending
Definition: namespace.c:140
MemoryContext TopMemoryContext
Definition: mcxt.c:43
static Oid baseCreationNamespace
Definition: namespace.c:146
static List * baseSearchPath
Definition: namespace.c:144
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1389
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:134
static void InitTempTableNamespace ( void  )
static

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

3753 {
3754  char namespaceName[NAMEDATALEN];
3755  Oid namespaceId;
3756  Oid toastspaceId;
3757 
3759 
3760  /*
3761  * First, do permission check to see if we are authorized to make temp
3762  * tables. We use a nonstandard error message here since "databasename:
3763  * permission denied" might be a tad cryptic.
3764  *
3765  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
3766  * that's necessary since current user ID could change during the session.
3767  * But there's no need to make the namespace in the first place until a
3768  * temp table creation request is made by someone with appropriate rights.
3769  */
3772  ereport(ERROR,
3773  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3774  errmsg("permission denied to create temporary tables in database \"%s\"",
3776 
3777  /*
3778  * Do not allow a Hot Standby slave session to make temp tables. Aside
3779  * from problems with modifying the system catalogs, there is a naming
3780  * conflict: pg_temp_N belongs to the session with BackendId N on the
3781  * master, not to a slave session with the same BackendId. We should not
3782  * be able to get here anyway due to XactReadOnly checks, but let's just
3783  * make real sure. Note that this also backstops various operations that
3784  * allow XactReadOnly transactions to modify temp tables; they'd need
3785  * RecoveryInProgress checks if not for this.
3786  */
3787  if (RecoveryInProgress())
3788  ereport(ERROR,
3789  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3790  errmsg("cannot create temporary tables during recovery")));
3791 
3792  /* Parallel workers can't create temporary tables, either. */
3793  if (IsParallelWorker())
3794  ereport(ERROR,
3795  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3796  errmsg("cannot create temporary tables in parallel mode")));
3797 
3798  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
3799 
3800  namespaceId = get_namespace_oid(namespaceName, true);
3801  if (!OidIsValid(namespaceId))
3802  {
3803  /*
3804  * First use of this temp namespace in this database; create it. The
3805  * temp namespaces are always owned by the superuser. We leave their
3806  * permissions at default --- i.e., no access except to superuser ---
3807  * to ensure that unprivileged users can't peek at other backends'
3808  * temp tables. This works because the places that access the temp
3809  * namespace for my own backend skip permissions checks on it.
3810  */
3811  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3812  true);
3813  /* Advance command counter to make namespace visible */
3815  }
3816  else
3817  {
3818  /*
3819  * If the namespace already exists, clean it out (in case the former
3820  * owner crashed without doing so).
3821  */
3822  RemoveTempRelations(namespaceId);
3823  }
3824 
3825  /*
3826  * If the corresponding toast-table namespace doesn't exist yet, create
3827  * it. (We assume there is no need to clean it out if it does exist, since
3828  * dropping a parent table should make its toast table go away.)
3829  */
3830  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
3831  MyBackendId);
3832 
3833  toastspaceId = get_namespace_oid(namespaceName, true);
3834  if (!OidIsValid(toastspaceId))
3835  {
3836  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3837  true);
3838  /* Advance command counter to make namespace visible */
3840  }
3841 
3842  /*
3843  * Okay, we've prepared the temp namespace ... but it's not committed yet,
3844  * so all our work could be undone by transaction rollback. Set flag for
3845  * AtEOXact_Namespace to know what to do.
3846  */
3847  myTempNamespace = namespaceId;
3848  myTempToastNamespace = toastspaceId;
3849 
3850  /* It should not be done already. */
3853 
3854  baseSearchPathValid = false; /* need to rebuild list */
3855 }
static bool baseSearchPathValid
Definition: namespace.c:153
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2962
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:183
static Oid myTempNamespace
Definition: namespace.c:181
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:7873
#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:185
#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:3976
#define BOOTSTRAP_SUPERUSERID
Definition: pg_authid.h:102
#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 3113 of file namespace.c.

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

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

3114 {
3115  bool result;
3116  char *nspname;
3117 
3118  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3119  nspname = get_namespace_name(namespaceId);
3120  if (!nspname)
3121  return false; /* no such namespace? */
3122  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3123  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3124  pfree(nspname);
3125  return result;
3126 }
return result
Definition: formatting.c:1632
void pfree(void *pointer)
Definition: mcxt.c:950
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3136 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

3137 {
3138  /* If it's my own temp namespace, say "false" */
3139  if (isTempOrTempToastNamespace(namespaceId))
3140  return false;
3141  /* Else, if it's any temp namespace, say "true" */
3142  return isAnyTempNamespace(namespaceId);
3143 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3099
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3113
bool isTempNamespace ( Oid  namespaceId)

Definition at line 3075 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

3076 {
3077  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3078  return true;
3079  return false;
3080 }
static Oid myTempNamespace
Definition: namespace.c:181
#define OidIsValid(objectId)
Definition: c.h:538
bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3099 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

3100 {
3101  if (OidIsValid(myTempNamespace) &&
3102  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3103  return true;
3104  return false;
3105 }
static Oid myTempToastNamespace
Definition: namespace.c:183
static Oid myTempNamespace
Definition: namespace.c:181
#define OidIsValid(objectId)
Definition: c.h:538
bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3087 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

3088 {
3089  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3090  return true;
3091  return false;
3092 }
static Oid myTempToastNamespace
Definition: namespace.c:183
#define OidIsValid(objectId)
Definition: c.h:538
Oid LookupCreationNamespace ( const char *  nspname)

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

2854 {
2855  Oid namespaceId;
2856  AclResult aclresult;
2857 
2858  /* check for pg_temp alias */
2859  if (strcmp(nspname, "pg_temp") == 0)
2860  {
2861  /* Initialize temp namespace if first time through */
2864  return myTempNamespace;
2865  }
2866 
2867  namespaceId = get_namespace_oid(nspname, false);
2868 
2869  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2870  if (aclresult != ACLCHECK_OK)
2872  nspname);
2873 
2874  return namespaceId;
2875 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2962
Oid GetUserId(void)
Definition: miscinit.c:283
static Oid myTempNamespace
Definition: namespace.c:181
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:3752
AclResult
Definition: acl.h:170
Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

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

2811 {
2812  Oid namespaceId;
2813  AclResult aclresult;
2814 
2815  /* check for pg_temp alias */
2816  if (strcmp(nspname, "pg_temp") == 0)
2817  {
2819  return myTempNamespace;
2820 
2821  /*
2822  * Since this is used only for looking up existing objects, there is
2823  * no point in trying to initialize the temp namespace here; and doing
2824  * so might create problems for some callers --- just fall through.
2825  */
2826  }
2827 
2828  namespaceId = get_namespace_oid(nspname, missing_ok);
2829  if (missing_ok && !OidIsValid(namespaceId))
2830  return InvalidOid;
2831 
2832  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
2833  if (aclresult != ACLCHECK_OK)
2835  nspname);
2836  /* Schema search hook for this lookup */
2837  InvokeNamespaceSearchHook(namespaceId, true);
2838 
2839  return namespaceId;
2840 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2962
Oid GetUserId(void)
Definition: miscinit.c:283
static Oid myTempNamespace
Definition: namespace.c:181
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 2780 of file namespace.c.

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

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

2781 {
2782  /* check for pg_temp alias */
2783  if (strcmp(nspname, "pg_temp") == 0)
2784  {
2786  {
2788  return myTempNamespace;
2789  }
2790 
2791  /*
2792  * Since this is used only for looking up existing objects, there is
2793  * no point in trying to initialize the temp namespace here; and doing
2794  * so might create problems for some callers. Just report "not found".
2795  */
2796  return InvalidOid;
2797  }
2798 
2799  return get_namespace_oid(nspname, true);
2800 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2962
static Oid myTempNamespace
Definition: namespace.c:181
#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 2980 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().

2981 {
2982  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
2983 
2984  switch (list_length(names))
2985  {
2986  case 1:
2987  rel->relname = strVal(linitial(names));
2988  break;
2989  case 2:
2990  rel->schemaname = strVal(linitial(names));
2991  rel->relname = strVal(lsecond(names));
2992  break;
2993  case 3:
2994  rel->catalogname = strVal(linitial(names));
2995  rel->schemaname = strVal(lsecond(names));
2996  rel->relname = strVal(lthird(names));
2997  break;
2998  default:
2999  ereport(ERROR,
3000  (errcode(ERRCODE_SYNTAX_ERROR),
3001  errmsg("improper relation name (too many dotted names): %s",
3002  NameListToString(names))));
3003  break;
3004  }
3005 
3006  return rel;
3007 }
#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:3020
#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 1266 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().

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

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

3055 {
3057  ListCell *l;
3058 
3059  initStringInfo(&string);
3060 
3061  foreach(l, names)
3062  {
3063  if (l != list_head(names))
3064  appendStringInfoChar(&string, '.');
3066  }
3067 
3068  return string.data;
3069 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10280
#define strVal(v)
Definition: value.h:54
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define lfirst(lc)
Definition: pg_list.h:106
char* NameListToString ( List names)

Definition at line 3020 of file namespace.c.

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

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

3021 {
3023  ListCell *l;
3024 
3025  initStringInfo(&string);
3026 
3027  foreach(l, names)
3028  {
3029  Node *name = (Node *) lfirst(l);
3030 
3031  if (l != list_head(names))
3032  appendStringInfoChar(&string, '.');
3033 
3034  if (IsA(name, String))
3035  appendStringInfoString(&string, strVal(name));
3036  else if (IsA(name, A_Star))
3037  appendStringInfoChar(&string, '*');
3038  else
3039  elog(ERROR, "unexpected node type in name list: %d",
3040  (int) nodeTag(name));
3041  }
3042 
3043  return string.data;
3044 }
#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:157
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define lfirst(lc)
Definition: pg_list.h:106
const char * name
Definition: encode.c:521
#define nodeTag(nodeptr)
Definition: nodes.h:514
#define elog
Definition: elog.h:219
static void NamespaceCallback ( Datum  arg,
int  cacheid,
uint32  hashvalue 
)
static

Definition at line 4123 of file namespace.c.

References baseSearchPathValid.

Referenced by InitializeSearchPath().

4124 {
4125  /* Force search path to be recomputed on next use */
4126  baseSearchPathValid = false;
4127 }
static bool baseSearchPathValid
Definition: namespace.c:153
bool OpclassIsVisible ( Oid  opcid)

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

1794 {
1795  HeapTuple opctup;
1796  Form_pg_opclass opcform;
1797  Oid opcnamespace;
1798  bool visible;
1799 
1800  opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
1801  if (!HeapTupleIsValid(opctup))
1802  elog(ERROR, "cache lookup failed for opclass %u", opcid);
1803  opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1804 
1806 
1807  /*
1808  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1809  * the system namespace are surely in the path and so we needn't even do
1810  * list_member_oid() for them.
1811  */
1812  opcnamespace = opcform->opcnamespace;
1813  if (opcnamespace != PG_CATALOG_NAMESPACE &&
1814  !list_member_oid(activeSearchPath, opcnamespace))
1815  visible = false;
1816  else
1817  {
1818  /*
1819  * If it is in the path, it might still not be visible; it could be
1820  * hidden by another opclass of the same name earlier in the path. So
1821  * we must do a slow check to see if this opclass would be found by
1822  * OpclassnameGetOpcid.
1823  */
1824  char *opcname = NameStr(opcform->opcname);
1825 
1826  visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1827  }
1828 
1829  ReleaseSysCache(opctup);
1830 
1831  return visible;
1832 }
#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:1760
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#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:1117
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:134
#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 1760 of file namespace.c.

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

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

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

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

1708 {
1709  HeapTuple oprtup;
1710  Form_pg_operator oprform;
1711  Oid oprnamespace;
1712  bool visible;
1713 
1715  if (!HeapTupleIsValid(oprtup))
1716  elog(ERROR, "cache lookup failed for operator %u", oprid);
1717  oprform = (Form_pg_operator) GETSTRUCT(oprtup);
1718 
1720 
1721  /*
1722  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1723  * the system namespace are surely in the path and so we needn't even do
1724  * list_member_oid() for them.
1725  */
1726  oprnamespace = oprform->oprnamespace;
1727  if (oprnamespace != PG_CATALOG_NAMESPACE &&
1728  !list_member_oid(activeSearchPath, oprnamespace))
1729  visible = false;
1730  else
1731  {
1732  /*
1733  * If it is in the path, it might still not be visible; it could be
1734  * hidden by another operator of the same name and arguments earlier
1735  * in the path. So we must do a slow check to see if this is the same
1736  * operator that would be found by OpernameGetOprid.
1737  */
1738  char *oprname = NameStr(oprform->oprname);
1739 
1740  visible = (OpernameGetOprid(list_make1(makeString(oprname)),
1741  oprform->oprleft, oprform->oprright)
1742  == oprid);
1743  }
1744 
1745  ReleaseSysCache(oprtup);
1746 
1747  return visible;
1748 }
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:156
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
#define list_make1(x1)
Definition: pg_list.h:139
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1445
#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:1117
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:134
#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 1547 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().

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

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

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

Definition at line 1843 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

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

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

3291 {
3292  ListCell *lc,
3293  *lcp;
3294 
3296 
3297  /* We scan down the activeSearchPath to see if it matches the input. */
3299 
3300  /* If path->addTemp, first item should be my temp namespace. */
3301  if (path->addTemp)
3302  {
3303  if (lc && lfirst_oid(lc) == myTempNamespace)
3304  lc = lnext(lc);
3305  else
3306  return false;
3307  }
3308  /* If path->addCatalog, next item should be pg_catalog. */
3309  if (path->addCatalog)
3310  {
3311  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3312  lc = lnext(lc);
3313  else
3314  return false;
3315  }
3316  /* We should now be looking at the activeCreationNamespace. */
3317  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3318  return false;
3319  /* The remainder of activeSearchPath should match path->schemas. */
3320  foreach(lcp, path->schemas)
3321  {
3322  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3323  lc = lnext(lc);
3324  else
3325  return false;
3326  }
3327  if (lc)
3328  return false;
3329  return true;
3330 }
static Oid myTempNamespace
Definition: namespace.c:181
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
static Oid activeCreationNamespace
Definition: namespace.c:137
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:134
#define lfirst_oid(lc)
Definition: pg_list.h:108
Datum pg_collation_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4284 of file namespace.c.

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

4285 {
4286  Oid oid = PG_GETARG_OID(0);
4287 
4289  PG_RETURN_NULL();
4290 
4292 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
bool CollationIsVisible(Oid collid)
Definition: namespace.c:1966
#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 4295 of file namespace.c.

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

4296 {
4297  Oid oid = PG_GETARG_OID(0);
4298 
4300  PG_RETURN_NULL();
4301 
4303 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#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:2048
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4240 of file namespace.c.

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

4241 {
4242  Oid oid = PG_GETARG_OID(0);
4243 
4245  PG_RETURN_NULL();
4246 
4248 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#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 4367 of file namespace.c.

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

4368 {
4369  Oid oid = PG_GETARG_OID(0);
4370 
4372 }
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:3136
Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4361 of file namespace.c.

References myTempNamespace, and PG_RETURN_OID.

4362 {
4364 }
static Oid myTempNamespace
Definition: namespace.c:181
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
Datum pg_opclass_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4262 of file namespace.c.

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

4263 {
4264  Oid oid = PG_GETARG_OID(0);
4265 
4267  PG_RETURN_NULL();
4268 
4270 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#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:1793
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4251 of file namespace.c.

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

4252 {
4253  Oid oid = PG_GETARG_OID(0);
4254 
4256  PG_RETURN_NULL();
4257 
4259 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1707
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#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 4273 of file namespace.c.

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

4274 {
4275  Oid oid = PG_GETARG_OID(0);
4276 
4278  PG_RETURN_NULL();
4279 
4281 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
bool OpfamilyIsVisible(Oid opfid)
Definition: namespace.c:1876
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_statistics_obj_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4306 of file namespace.c.

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

4307 {
4308  Oid oid = PG_GETARG_OID(0);
4309 
4311  PG_RETURN_NULL();
4312 
4314 }
bool StatisticsObjIsVisible(Oid relid)
Definition: namespace.c:2152
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#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_table_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4218 of file namespace.c.

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

4219 {
4220  Oid oid = PG_GETARG_OID(0);
4221 
4223  PG_RETURN_NULL();
4224 
4226 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#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:682
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_ts_config_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4350 of file namespace.c.

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

4351 {
4352  Oid oid = PG_GETARG_OID(0);
4353 
4355  PG_RETURN_NULL();
4356 
4358 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2654
#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 4328 of file namespace.c.

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

4329 {
4330  Oid oid = PG_GETARG_OID(0);
4331 
4333  PG_RETURN_NULL();
4334 
4336 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2401
#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 4317 of file namespace.c.

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

4318 {
4319  Oid oid = PG_GETARG_OID(0);
4320 
4322  PG_RETURN_NULL();
4323 
4325 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#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:2275
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4339 of file namespace.c.

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

4340 {
4341  Oid oid = PG_GETARG_OID(0);
4342 
4344  PG_RETURN_NULL();
4345 
4347 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#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:2528
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4229 of file namespace.c.

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

4230 {
4231  Oid oid = PG_GETARG_OID(0);
4232 
4234  PG_RETURN_NULL();
4235 
4237 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:174
#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:777
#define PG_RETURN_NULL()
Definition: fmgr.h:305
void PopOverrideSearchPath ( void  )

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

3410 {
3411  OverrideStackEntry *entry;
3412 
3413  /* Sanity checks. */
3414  if (overrideStack == NIL)
3415  elog(ERROR, "bogus PopOverrideSearchPath call");
3417  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3418  elog(ERROR, "bogus PopOverrideSearchPath call");
3419 
3420  /* Pop the stack and free storage. */
3422  list_free(entry->searchPath);
3423  pfree(entry);
3424 
3425  /* Activate the next level down. */
3426  if (overrideStack)
3427  {
3429  activeSearchPath = entry->searchPath;
3431  activeTempCreationPending = false; /* XXX is this OK? */
3432  }
3433  else
3434  {
3435  /* If not baseSearchPathValid, this is useless but harmless */
3439  }
3440 }
#define NIL
Definition: pg_list.h:69
static List * overrideStack
Definition: namespace.c:164
static Oid activeCreationNamespace
Definition: namespace.c:137
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:148
static bool activeTempCreationPending
Definition: namespace.c:140
static Oid baseCreationNamespace
Definition: namespace.c:146
static List * baseSearchPath
Definition: namespace.c:144
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:761
static List * activeSearchPath
Definition: namespace.c:134
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 3350 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().

3351 {
3352  OverrideStackEntry *entry;
3353  List *oidlist;
3354  Oid firstNS;
3355  MemoryContext oldcxt;
3356 
3357  /*
3358  * Copy the list for safekeeping, and insert implicitly-searched
3359  * namespaces as needed. This code should track recomputeNamespacePath.
3360  */
3362 
3363  oidlist = list_copy(newpath->schemas);
3364 
3365  /*
3366  * Remember the first member of the explicit list.
3367  */
3368  if (oidlist == NIL)
3369  firstNS = InvalidOid;
3370  else
3371  firstNS = linitial_oid(oidlist);
3372 
3373  /*
3374  * Add any implicitly-searched namespaces to the list. Note these go on
3375  * the front, not the back; also notice that we do not check USAGE
3376  * permissions for these.
3377  */
3378  if (newpath->addCatalog)
3379  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3380 
3381  if (newpath->addTemp && OidIsValid(myTempNamespace))
3382  oidlist = lcons_oid(myTempNamespace, oidlist);
3383 
3384  /*
3385  * Build the new stack entry, then insert it at the head of the list.
3386  */
3387  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3388  entry->searchPath = oidlist;
3389  entry->creationNamespace = firstNS;
3391 
3392  overrideStack = lcons(entry, overrideStack);
3393 
3394  /* And make it active. */
3395  activeSearchPath = entry->searchPath;
3397  activeTempCreationPending = false; /* XXX is this OK? */
3398 
3399  MemoryContextSwitchTo(oldcxt);
3400 }
#define NIL
Definition: pg_list.h:69
static Oid myTempNamespace
Definition: namespace.c:181
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static List * overrideStack
Definition: namespace.c:164
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:137
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
static bool activeTempCreationPending
Definition: namespace.c:140
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:134
void * palloc(Size size)
Definition: mcxt.c:849
Definition: pg_list.h:45
Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

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

2914 {
2915  char *schemaname;
2916  Oid namespaceId;
2917 
2918  /* deconstruct the name list */
2919  DeconstructQualifiedName(names, &schemaname, objname_p);
2920 
2921  if (schemaname)
2922  {
2923  /* check for pg_temp alias */
2924  if (strcmp(schemaname, "pg_temp") == 0)
2925  {
2926  /* Initialize temp namespace if first time through */
2929  return myTempNamespace;
2930  }
2931  /* use exact schema given */
2932  namespaceId = get_namespace_oid(schemaname, false);
2933  /* we do not check for USAGE rights here! */
2934  }
2935  else
2936  {
2937  /* use the default creation namespace */
2940  {
2941  /* Need to initialize temp namespace */
2943  return myTempNamespace;
2944  }
2945  namespaceId = activeCreationNamespace;
2946  if (!OidIsValid(namespaceId))
2947  ereport(ERROR,
2948  (errcode(ERRCODE_UNDEFINED_SCHEMA),
2949  errmsg("no schema has been selected to create in")));
2950  }
2951 
2952  return namespaceId;
2953 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2962
static Oid myTempNamespace
Definition: namespace.c:181
int errcode(int sqlerrcode)
Definition: elog.c:575
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2726
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
static void recomputeNamespacePath(void)
Definition: namespace.c:3602
static Oid activeCreationNamespace
Definition: namespace.c:137
#define ERROR
Definition: elog.h:43
static bool activeTempCreationPending
Definition: namespace.c:140
#define ereport(elevel, rest)
Definition: elog.h:122
static void InitTempTableNamespace(void)
Definition: namespace.c:3752
int errmsg(const char *fmt,...)
Definition: elog.c:797
void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 615 of file namespace.c.

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

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

616 {
617  switch (newRelation->relpersistence)
618  {
619  case RELPERSISTENCE_TEMP:
620  if (!isTempOrTempToastNamespace(nspid))
621  {
622  if (isAnyTempNamespace(nspid))
623  ereport(ERROR,
624  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
625  errmsg("cannot create relations in temporary schemas of other sessions")));
626  else
627  ereport(ERROR,
628  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
629  errmsg("cannot create temporary relation in non-temporary schema")));
630  }
631  break;
633  if (isTempOrTempToastNamespace(nspid))
634  newRelation->relpersistence = RELPERSISTENCE_TEMP;
635  else if (isAnyTempNamespace(nspid))
636  ereport(ERROR,
637  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
638  errmsg("cannot create relations in temporary schemas of other sessions")));
639  break;
640  default:
641  if (isAnyTempNamespace(nspid))
642  ereport(ERROR,
643  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
644  errmsg("only temporary relations may be created in temporary schemas")));
645  }
646 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3099
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:3113
#define RELPERSISTENCE_TEMP
Definition: pg_class.h:172
Oid RangeVarGetAndCheckCreationNamespace ( RangeVar relation,
LOCKMODE  lockmode,
Oid existing_relation_id 
)

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

511 {
512  uint64 inval_count;
513  Oid relid;
514  Oid oldrelid = InvalidOid;
515  Oid nspid;
516  Oid oldnspid = InvalidOid;
517  bool retry = false;
518 
519  /*
520  * We check the catalog name and then ignore it.
521  */
522  if (relation->catalogname)
523  {
524  if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
525  ereport(ERROR,
526  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
527  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
528  relation->catalogname, relation->schemaname,
529  relation->relname)));
530  }
531 
532  /*
533  * As in RangeVarGetRelidExtended(), we guard against concurrent DDL
534  * operations by tracking whether any invalidation messages are processed
535  * while we're doing the name lookups and acquiring locks. See comments
536  * in that function for a more detailed explanation of this logic.
537  */
538  for (;;)
539  {
540  AclResult aclresult;
541 
542  inval_count = SharedInvalidMessageCounter;
543 
544  /* Look up creation namespace and check for existing relation. */
545  nspid = RangeVarGetCreationNamespace(relation);
546  Assert(OidIsValid(nspid));
547  if (existing_relation_id != NULL)
548  relid = get_relname_relid(relation->relname, nspid);
549  else
550  relid = InvalidOid;
551 
552  /*
553  * In bootstrap processing mode, we don't bother with permissions or
554  * locking. Permissions might not be working yet, and locking is
555  * unnecessary.
556  */
558  break;
559 
560  /* Check namespace permissions. */
561  aclresult = pg_namespace_aclcheck(nspid, GetUserId(), ACL_CREATE);
562  if (aclresult != ACLCHECK_OK)
564  get_namespace_name(nspid));
565 
566  if (retry)
567  {
568  /* If nothing changed, we're done. */
569  if (relid == oldrelid && nspid == oldnspid)
570  break;
571  /* If creation namespace has changed, give up old lock. */
572  if (nspid != oldnspid)
575  /* If name points to something different, give up old lock. */
576  if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock)
577  UnlockRelationOid(oldrelid, lockmode);
578  }
579 
580  /* Lock namespace. */
581  if (nspid != oldnspid)
583 
584  /* Lock relation, if required if and we have permission. */
585  if (lockmode != NoLock && OidIsValid(relid))
586  {
587  if (!pg_class_ownercheck(relid, GetUserId()))
589  relation->relname);
590  if (relid != oldrelid)
591  LockRelationOid(relid, lockmode);
592  }
593 
594  /* If no invalidation message were processed, we're done! */
595  if (inval_count == SharedInvalidMessageCounter)
596  break;
597 
598  /* Something may have changed, so recheck our work. */
599  retry = true;
600  oldrelid = relid;
601  oldnspid = nspid;
602  }
603 
604  RangeVarAdjustRelationPersistence(relation, nspid);
605  if (existing_relation_id != NULL)
606  *existing_relation_id = relid;
607  return nspid;
608 }
#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:615
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:3033
#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:421
Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

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

422 {
423  Oid namespaceId;
424 
425  /*
426  * We check the catalog name and then ignore it.
427  */
428  if (newRelation->catalogname)
429  {
430  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
431  ereport(ERROR,
432  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
433  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
434  newRelation->catalogname, newRelation->schemaname,
435  newRelation->relname)));
436  }
437 
438  if (newRelation->schemaname)
439  {
440  /* check for pg_temp alias */
441  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
442  {
443  /* Initialize temp namespace if first time through */
446  return myTempNamespace;
447  }
448  /* use exact schema given */
449  namespaceId = get_namespace_oid(newRelation->schemaname, false);
450  /* we do not check for USAGE rights here! */
451  }
452  else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
453  {
454  /* Initialize temp namespace if first time through */
457  return myTempNamespace;
458  }
459  else
460  {
461  /* use the default creation namespace */
464  {
465  /* Need to initialize temp namespace */
467  return myTempNamespace;
468  }
469  namespaceId = activeCreationNamespace;
470  if (!OidIsValid(namespaceId))
471  ereport(ERROR,
472  (errcode(ERRCODE_UNDEFINED_SCHEMA),
473  errmsg("no schema has been selected to create in")));
474  }
475 
476  /* Note: callers will check for CREATE rights when appropriate */
477 
478  return namespaceId;
479 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:2962
static Oid myTempNamespace
Definition: namespace.c:181
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:3602
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
static Oid activeCreationNamespace
Definition: namespace.c:137
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
static bool activeTempCreationPending
Definition: namespace.c:140
#define ereport(elevel, rest)
Definition: elog.h:122
static void InitTempTableNamespace(void)
Definition: namespace.c:3752
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 218 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().

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

3603 {
3604  Oid roleid = GetUserId();
3605  char *rawname;
3606  List *namelist;
3607  List *oidlist;
3608  List *newpath;
3609  ListCell *l;
3610  bool temp_missing;
3611  Oid firstNS;
3612  MemoryContext oldcxt;
3613 
3614  /* Do nothing if an override search spec is active. */
3615  if (overrideStack)
3616  return;
3617 
3618  /* Do nothing if path is already valid. */
3619  if (baseSearchPathValid && namespaceUser == roleid)
3620  return;
3621 
3622  /* Need a modifiable copy of namespace_search_path string */
3623  rawname = pstrdup(namespace_search_path);
3624 
3625  /* Parse string into list of identifiers */
3626  if (!SplitIdentifierString(rawname, ',', &namelist))
3627  {
3628  /* syntax error in name list */
3629  /* this should not happen if GUC checked check_search_path */
3630  elog(ERROR, "invalid list syntax");
3631  }
3632 
3633  /*
3634  * Convert the list of names to a list of OIDs. If any names are not
3635  * recognizable or we don't have read access, just leave them out of the
3636  * list. (We can't raise an error, since the search_path setting has
3637  * already been accepted.) Don't make duplicate entries, either.
3638  */
3639  oidlist = NIL;
3640  temp_missing = false;
3641  foreach(l, namelist)
3642  {
3643  char *curname = (char *) lfirst(l);
3644