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)
 
static Oid lookup_collation (const char *collname, Oid collnamespace, int32 encoding)
 
Oid CollationGetCollid (const char *collname)
 
bool CollationIsVisible (Oid collid)
 
Oid ConversionGetConid (const char *conname)
 
bool ConversionIsVisible (Oid conid)
 
Oid get_statistics_object_oid (List *names, bool missing_ok)
 
bool StatisticsObjIsVisible (Oid relid)
 
Oid get_ts_parser_oid (List *names, bool missing_ok)
 
bool TSParserIsVisible (Oid prsId)
 
Oid get_ts_dict_oid (List *names, bool missing_ok)
 
bool TSDictionaryIsVisible (Oid dictId)
 
Oid get_ts_template_oid (List *names, bool missing_ok)
 
bool TSTemplateIsVisible (Oid tmplId)
 
Oid get_ts_config_oid (List *names, bool missing_ok)
 
bool TSConfigIsVisible (Oid cfgid)
 
void DeconstructQualifiedName (List *names, char **nspname_p, char **objname_p)
 
Oid LookupNamespaceNoError (const char *nspname)
 
Oid LookupExplicitNamespace (const char *nspname, bool missing_ok)
 
Oid LookupCreationNamespace (const char *nspname)
 
void CheckSetNamespace (Oid oldNspOid, Oid nspOid)
 
Oid QualifiedNameGetCreationNamespace (List *names, char **objname_p)
 
Oid get_namespace_oid (const char *nspname, bool missing_ok)
 
RangeVarmakeRangeVarFromNameList (List *names)
 
char * NameListToString (List *names)
 
char * NameListToQuotedString (List *names)
 
bool isTempNamespace (Oid namespaceId)
 
bool isTempToastNamespace (Oid namespaceId)
 
bool isTempOrTempToastNamespace (Oid namespaceId)
 
bool isAnyTempNamespace (Oid namespaceId)
 
bool isOtherTempNamespace (Oid namespaceId)
 
int GetTempNamespaceBackendId (Oid namespaceId)
 
Oid GetTempToastNamespace (void)
 
void GetTempNamespaceState (Oid *tempNamespaceId, Oid *tempToastNamespaceId)
 
void SetTempNamespaceState (Oid tempNamespaceId, Oid tempToastNamespaceId)
 
OverrideSearchPathGetOverrideSearchPath (MemoryContext context)
 
OverrideSearchPathCopyOverrideSearchPath (OverrideSearchPath *path)
 
bool OverrideSearchPathMatchesCurrent (OverrideSearchPath *path)
 
void PushOverrideSearchPath (OverrideSearchPath *newpath)
 
void PopOverrideSearchPath (void)
 
Oid get_collation_oid (List *name, bool missing_ok)
 
Oid get_conversion_oid (List *name, bool missing_ok)
 
Oid FindDefaultConversionProc (int32 for_encoding, int32 to_encoding)
 
void AtEOXact_Namespace (bool isCommit, bool parallel)
 
void AtEOSubXact_Namespace (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void ResetTempTableNamespace (void)
 
bool check_search_path (char **newval, void **extra, GucSource source)
 
void assign_search_path (const char *newval, void *extra)
 
void InitializeSearchPath (void)
 
Listfetch_search_path (bool includeImplicit)
 
int fetch_search_path_array (Oid *sarray, int sarray_len)
 
Datum pg_table_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_type_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_function_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_operator_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_opclass_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_opfamily_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_collation_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_conversion_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_statistics_obj_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_parser_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_dict_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_template_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_ts_config_is_visible (PG_FUNCTION_ARGS)
 
Datum pg_my_temp_schema (PG_FUNCTION_ARGS)
 
Datum pg_is_other_temp_schema (PG_FUNCTION_ARGS)
 

Variables

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

Macro Definition Documentation

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

Referenced by OpernameGetCandidates().

Function Documentation

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

Definition at line 4094 of file namespace.c.

References baseSearchPathValid.

4095 {
4096  /*
4097  * We mark the path as needing recomputation, but don't do anything until
4098  * it's needed. This avoids trying to do database access during GUC
4099  * initialization, or outside a transaction.
4100  */
4101  baseSearchPathValid = false;
4102 }
static bool baseSearchPathValid
Definition: namespace.c:153
void AtEOSubXact_Namespace ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

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

3945 {
3946  OverrideStackEntry *entry;
3947 
3948  if (myTempNamespaceSubID == mySubid)
3949  {
3950  if (isCommit)
3951  myTempNamespaceSubID = parentSubid;
3952  else
3953  {
3955  /* TEMP namespace creation failed, so reset state */
3958  baseSearchPathValid = false; /* need to rebuild list */
3959  }
3960  }
3961 
3962  /*
3963  * Clean up if someone failed to do PopOverrideSearchPath
3964  */
3965  while (overrideStack)
3966  {
3969  break;
3970  if (isCommit)
3971  elog(WARNING, "leaked override search path");
3973  list_free(entry->searchPath);
3974  pfree(entry);
3975  }
3976 
3977  /* Activate the next level down. */
3978  if (overrideStack)
3979  {
3981  activeSearchPath = entry->searchPath;
3983  activeTempCreationPending = false; /* XXX is this OK? */
3984  }
3985  else
3986  {
3987  /* If not baseSearchPathValid, this is useless but harmless */
3991  }
3992 }
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:949
#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:762
#define InvalidSubTransactionId
Definition: c.h:397
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 3888 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().

3889 {
3890  /*
3891  * If we abort the transaction in which a temp namespace was selected,
3892  * we'll have to do any creation or cleanout work over again. So, just
3893  * forget the namespace entirely until next time. On the other hand, if
3894  * we commit then register an exit callback to clean out the temp tables
3895  * at backend shutdown. (We only want to register the callback once per
3896  * session, so this is a good place to do it.)
3897  */
3898  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
3899  {
3900  if (isCommit)
3902  else
3903  {
3906  baseSearchPathValid = false; /* need to rebuild list */
3907  }
3909  }
3910 
3911  /*
3912  * Clean up if someone failed to do PopOverrideSearchPath
3913  */
3914  if (overrideStack)
3915  {
3916  if (isCommit)
3917  elog(WARNING, "leaked override search path");
3918  while (overrideStack)
3919  {
3920  OverrideStackEntry *entry;
3921 
3924  list_free(entry->searchPath);
3925  pfree(entry);
3926  }
3927  /* If not baseSearchPathValid, this is useless but harmless */
3931  }
3932 }
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:949
#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:397
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:4029
List * list_delete_first(List *list)
Definition: list.c:666
bool check_search_path ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 4060 of file namespace.c.

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

4061 {
4062  char *rawname;
4063  List *namelist;
4064 
4065  /* Need a modifiable copy of string */
4066  rawname = pstrdup(*newval);
4067 
4068  /* Parse string into list of identifiers */
4069  if (!SplitIdentifierString(rawname, ',', &namelist))
4070  {
4071  /* syntax error in name list */
4072  GUC_check_errdetail("List syntax is invalid.");
4073  pfree(rawname);
4074  list_free(namelist);
4075  return false;
4076  }
4077 
4078  /*
4079  * We used to try to check that the named schemas exist, but there are
4080  * many valid use-cases for having search_path settings that include
4081  * schemas that don't exist; and often, we are not inside a transaction
4082  * here and so can't consult the system catalogs anyway. So now, the only
4083  * requirement is syntactic validity of the identifier list.
4084  */
4085 
4086  pfree(rawname);
4087  list_free(namelist);
4088 
4089  return true;
4090 }
#define GUC_check_errdetail
Definition: guc.h:408
char * pstrdup(const char *in)
Definition: mcxt.c:1076
void pfree(void *pointer)
Definition: mcxt.c:949
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3260
#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 2928 of file namespace.c.

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

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

2929 {
2930  /* disallow renaming into or out of temp schemas */
2931  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2932  ereport(ERROR,
2933  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2934  errmsg("cannot move objects into or out of temporary schemas")));
2935 
2936  /* same for TOAST schema */
2937  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
2938  ereport(ERROR,
2939  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2940  errmsg("cannot move objects into or out of TOAST schema")));
2941 }
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:3156
Oid CollationGetCollid ( const char *  collname)

Definition at line 1974 of file namespace.c.

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

Referenced by CollationIsVisible().

1975 {
1976  int32 dbencoding = GetDatabaseEncoding();
1977  ListCell *l;
1978 
1980 
1981  foreach(l, activeSearchPath)
1982  {
1983  Oid namespaceId = lfirst_oid(l);
1984  Oid collid;
1985 
1986  if (namespaceId == myTempNamespace)
1987  continue; /* do not look in temp namespace */
1988 
1989  collid = lookup_collation(collname, namespaceId, dbencoding);
1990  if (OidIsValid(collid))
1991  return collid;
1992  }
1993 
1994  /* Not found in path */
1995  return InvalidOid;
1996 }
static Oid myTempNamespace
Definition: namespace.c:181
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
signed int int32
Definition: c.h:246
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1923
int GetDatabaseEncoding(void)
Definition: mbutils.c:1015
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:134
#define lfirst_oid(lc)
Definition: pg_list.h:108
bool CollationIsVisible ( Oid  collid)

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

2009 {
2010  HeapTuple colltup;
2011  Form_pg_collation collform;
2012  Oid collnamespace;
2013  bool visible;
2014 
2015  colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
2016  if (!HeapTupleIsValid(colltup))
2017  elog(ERROR, "cache lookup failed for collation %u", collid);
2018  collform = (Form_pg_collation) GETSTRUCT(colltup);
2019 
2021 
2022  /*
2023  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2024  * the system namespace are surely in the path and so we needn't even do
2025  * list_member_oid() for them.
2026  */
2027  collnamespace = collform->collnamespace;
2028  if (collnamespace != PG_CATALOG_NAMESPACE &&
2029  !list_member_oid(activeSearchPath, collnamespace))
2030  visible = false;
2031  else
2032  {
2033  /*
2034  * If it is in the path, it might still not be visible; it could be
2035  * hidden by another collation of the same name earlier in the path,
2036  * or it might not work with the current DB encoding. So we must do a
2037  * slow check to see if this collation would be found by
2038  * CollationGetCollid.
2039  */
2040  char *collname = NameStr(collform->collname);
2041 
2042  visible = (CollationGetCollid(collname) == collid);
2043  }
2044 
2045  ReleaseSysCache(colltup);
2046 
2047  return visible;
2048 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid CollationGetCollid(const char *collname)
Definition: namespace.c:1974
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:159
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:493
#define elog
Definition: elog.h:219
Oid ConversionGetConid ( const char *  conname)

Definition at line 2059 of file namespace.c.

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

Referenced by ConversionIsVisible().

2060 {
2061  Oid conid;
2062  ListCell *l;
2063 
2065 
2066  foreach(l, activeSearchPath)
2067  {
2068  Oid namespaceId = lfirst_oid(l);
2069 
2070  if (namespaceId == myTempNamespace)
2071  continue; /* do not look in temp namespace */
2072 
2073  conid = GetSysCacheOid2(CONNAMENSP,
2074  PointerGetDatum(conname),
2075  ObjectIdGetDatum(namespaceId));
2076  if (OidIsValid(conid))
2077  return conid;
2078  }
2079 
2080  /* Not found in path */
2081  return InvalidOid;
2082 }
#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:532
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:188
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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 2091 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().

2092 {
2093  HeapTuple contup;
2094  Form_pg_conversion conform;
2095  Oid connamespace;
2096  bool visible;
2097 
2098  contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
2099  if (!HeapTupleIsValid(contup))
2100  elog(ERROR, "cache lookup failed for conversion %u", conid);
2101  conform = (Form_pg_conversion) GETSTRUCT(contup);
2102 
2104 
2105  /*
2106  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2107  * the system namespace are surely in the path and so we needn't even do
2108  * list_member_oid() for them.
2109  */
2110  connamespace = conform->connamespace;
2111  if (connamespace != PG_CATALOG_NAMESPACE &&
2112  !list_member_oid(activeSearchPath, connamespace))
2113  visible = false;
2114  else
2115  {
2116  /*
2117  * If it is in the path, it might still not be visible; it could be
2118  * hidden by another conversion of the same name earlier in the path.
2119  * So we must do a slow check to see if this conversion would be found
2120  * by ConversionGetConid.
2121  */
2122  char *conname = NameStr(conform->conname);
2123 
2124  visible = (ConversionGetConid(conname) == conid);
2125  }
2126 
2127  ReleaseSysCache(contup);
2128 
2129  return visible;
2130 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:159
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
Oid ConversionGetConid(const char *conname)
Definition: namespace.c:2059
#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:493
#define elog
Definition: elog.h:219
OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3317 of file namespace.c.

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

Referenced by CopyCachedPlan().

3318 {
3320 
3321  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3322  result->schemas = list_copy(path->schemas);
3323  result->addCatalog = path->addCatalog;
3324  result->addTemp = path->addTemp;
3325 
3326  return result;
3327 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
return result
Definition: formatting.c:1633
void * palloc(Size size)
Definition: mcxt.c:848
void DeconstructQualifiedName ( List names,
char **  nspname_p,
char **  objname_p 
)

Definition at line 2769 of file namespace.c.

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

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

2772 {
2773  char *catalogname;
2774  char *schemaname = NULL;
2775  char *objname = NULL;
2776 
2777  switch (list_length(names))
2778  {
2779  case 1:
2780  objname = strVal(linitial(names));
2781  break;
2782  case 2:
2783  schemaname = strVal(linitial(names));
2784  objname = strVal(lsecond(names));
2785  break;
2786  case 3:
2787  catalogname = strVal(linitial(names));
2788  schemaname = strVal(lsecond(names));
2789  objname = strVal(lthird(names));
2790 
2791  /*
2792  * We check the catalog name and then ignore it.
2793  */
2794  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2795  ereport(ERROR,
2796  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2797  errmsg("cross-database references are not implemented: %s",
2798  NameListToString(names))));
2799  break;
2800  default:
2801  ereport(ERROR,
2802  (errcode(ERRCODE_SYNTAX_ERROR),
2803  errmsg("improper qualified name (too many dotted names): %s",
2804  NameListToString(names))));
2805  break;
2806  }
2807 
2808  *nspname_p = schemaname;
2809  *objname_p = objname;
2810 }
#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:3063
Oid MyDatabaseId
Definition: globals.c:77
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 4168 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().

4169 {
4170  List *result;
4171 
4173 
4174  /*
4175  * If the temp namespace should be first, force it to exist. This is so
4176  * that callers can trust the result to reflect the actual default
4177  * creation namespace. It's a bit bogus to do this here, since
4178  * current_schema() is supposedly a stable function without side-effects,
4179  * but the alternatives seem worse.
4180  */
4182  {
4185  }
4186 
4187  result = list_copy(activeSearchPath);
4188  if (!includeImplicit)
4189  {
4190  while (result && linitial_oid(result) != activeCreationNamespace)
4191  result = list_delete_first(result);
4192  }
4193 
4194  return result;
4195 }
List * list_copy(const List *oldlist)
Definition: list.c:1160
return result
Definition: formatting.c:1633
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
static Oid activeCreationNamespace
Definition: namespace.c:137
static bool activeTempCreationPending
Definition: namespace.c:140
static void InitTempTableNamespace(void)
Definition: namespace.c:3779
#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 4208 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4209 {
4210  int count = 0;
4211  ListCell *l;
4212 
4214 
4215  foreach(l, activeSearchPath)
4216  {
4217  Oid namespaceId = lfirst_oid(l);
4218 
4219  if (namespaceId == myTempNamespace)
4220  continue; /* do not include temp namespace */
4221 
4222  if (count < sarray_len)
4223  sarray[count] = namespaceId;
4224  count++;
4225  }
4226 
4227  return count;
4228 }
static Oid myTempNamespace
Definition: namespace.c:181
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
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 3602 of file namespace.c.

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

Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().

3603 {
3604  Oid proc;
3605  ListCell *l;
3606 
3608 
3609  foreach(l, activeSearchPath)
3610  {
3611  Oid namespaceId = lfirst_oid(l);
3612 
3613  if (namespaceId == myTempNamespace)
3614  continue; /* do not look in temp namespace */
3615 
3616  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3617  if (OidIsValid(proc))
3618  return proc;
3619  }
3620 
3621  /* Not found in path */
3622  return InvalidOid;
3623 }
static Oid myTempNamespace
Definition: namespace.c:181
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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, _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:2853
#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:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
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:949
struct _FuncCandidateList * FuncCandidateList
#define CStringGetDatum(X)
Definition: postgres.h:584
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:204
struct _FuncCandidateList * next
Definition: namespace.h:30
#define ReleaseSysCacheList(x)
Definition: syscache.h:213
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:789
#define Assert(condition)
Definition: c.h:664
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:848
int i
HeapTupleData tuple
Definition: catcache.h:116
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
#define offsetof(type, field)
Definition: c.h:549
#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:159
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:493
#define elog
Definition: elog.h:219
Oid get_collation_oid ( List name,
bool  missing_ok 
)

Definition at line 3493 of file namespace.c.

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

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

3494 {
3495  char *schemaname;
3496  char *collation_name;
3497  int32 dbencoding = GetDatabaseEncoding();
3498  Oid namespaceId;
3499  Oid colloid;
3500  ListCell *l;
3501 
3502  /* deconstruct the name list */
3503  DeconstructQualifiedName(name, &schemaname, &collation_name);
3504 
3505  if (schemaname)
3506  {
3507  /* use exact schema given */
3508  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3509  if (missing_ok && !OidIsValid(namespaceId))
3510  return InvalidOid;
3511 
3512  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3513  if (OidIsValid(colloid))
3514  return colloid;
3515  }
3516  else
3517  {
3518  /* search for it in search path */
3520 
3521  foreach(l, activeSearchPath)
3522  {
3523  namespaceId = lfirst_oid(l);
3524 
3525  if (namespaceId == myTempNamespace)
3526  continue; /* do not look in temp namespace */
3527 
3528  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3529  if (OidIsValid(colloid))
3530  return colloid;
3531  }
3532  }
3533 
3534  /* Not found in path */
3535  if (!missing_ok)
3536  ereport(ERROR,
3537  (errcode(ERRCODE_UNDEFINED_OBJECT),
3538  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3540  return InvalidOid;
3541 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2853
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:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
signed int int32
Definition: c.h:246
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:1923
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
char * NameListToString(List *names)
Definition: namespace.c:3063
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
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 3547 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().

3548 {
3549  char *schemaname;
3550  char *conversion_name;
3551  Oid namespaceId;
3552  Oid conoid = InvalidOid;
3553  ListCell *l;
3554 
3555  /* deconstruct the name list */
3556  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3557 
3558  if (schemaname)
3559  {
3560  /* use exact schema given */
3561  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3562  if (missing_ok && !OidIsValid(namespaceId))
3563  conoid = InvalidOid;
3564  else
3565  conoid = GetSysCacheOid2(CONNAMENSP,
3566  PointerGetDatum(conversion_name),
3567  ObjectIdGetDatum(namespaceId));
3568  }
3569  else
3570  {
3571  /* search for it in search path */
3573 
3574  foreach(l, activeSearchPath)
3575  {
3576  namespaceId = lfirst_oid(l);
3577 
3578  if (namespaceId == myTempNamespace)
3579  continue; /* do not look in temp namespace */
3580 
3581  conoid = GetSysCacheOid2(CONNAMENSP,
3582  PointerGetDatum(conversion_name),
3583  ObjectIdGetDatum(namespaceId));
3584  if (OidIsValid(conoid))
3585  return conoid;
3586  }
3587  }
3588 
3589  /* Not found in path */
3590  if (!OidIsValid(conoid) && !missing_ok)
3591  ereport(ERROR,
3592  (errcode(ERRCODE_UNDEFINED_OBJECT),
3593  errmsg("conversion \"%s\" does not exist",
3594  NameListToString(name))));
3595  return conoid;
3596 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2853
#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:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:188
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:3063
#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 3005 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().

3006 {
3007  Oid oid;
3008 
3010  if (!OidIsValid(oid) && !missing_ok)
3011  ereport(ERROR,
3012  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3013  errmsg("schema \"%s\" does not exist", nspname)));
3014 
3015  return oid;
3016 }
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define GetSysCacheOid1(cacheId, key1)
Definition: syscache.h:186
#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 2138 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().

2139 {
2140  char *schemaname;
2141  char *stats_name;
2142  Oid namespaceId;
2143  Oid stats_oid = InvalidOid;
2144  ListCell *l;
2145 
2146  /* deconstruct the name list */
2147  DeconstructQualifiedName(names, &schemaname, &stats_name);
2148 
2149  if (schemaname)
2150  {
2151  /* use exact schema given */
2152  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2153  if (missing_ok && !OidIsValid(namespaceId))
2154  stats_oid = InvalidOid;
2155  else
2156  stats_oid = GetSysCacheOid2(STATEXTNAMENSP,
2157  PointerGetDatum(stats_name),
2158  ObjectIdGetDatum(namespaceId));
2159  }
2160  else
2161  {
2162  /* search for it in search path */
2164 
2165  foreach(l, activeSearchPath)
2166  {
2167  namespaceId = lfirst_oid(l);
2168 
2169  if (namespaceId == myTempNamespace)
2170  continue; /* do not look in temp namespace */
2171  stats_oid = GetSysCacheOid2(STATEXTNAMENSP,
2172  PointerGetDatum(stats_name),
2173  ObjectIdGetDatum(namespaceId));
2174  if (OidIsValid(stats_oid))
2175  break;
2176  }
2177  }
2178 
2179  if (!OidIsValid(stats_oid) && !missing_ok)
2180  ereport(ERROR,
2181  (errcode(ERRCODE_UNDEFINED_OBJECT),
2182  errmsg("statistics object \"%s\" does not exist",
2183  NameListToString(names))));
2184 
2185  return stats_oid;
2186 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2853
#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:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:188
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:3063
#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 2639 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().

2640 {
2641  char *schemaname;
2642  char *config_name;
2643  Oid namespaceId;
2644  Oid cfgoid = InvalidOid;
2645  ListCell *l;
2646 
2647  /* deconstruct the name list */
2648  DeconstructQualifiedName(names, &schemaname, &config_name);
2649 
2650  if (schemaname)
2651  {
2652  /* use exact schema given */
2653  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2654  if (missing_ok && !OidIsValid(namespaceId))
2655  cfgoid = InvalidOid;
2656  else
2658  PointerGetDatum(config_name),
2659  ObjectIdGetDatum(namespaceId));
2660  }
2661  else
2662  {
2663  /* search for it in search path */
2665 
2666  foreach(l, activeSearchPath)
2667  {
2668  namespaceId = lfirst_oid(l);
2669 
2670  if (namespaceId == myTempNamespace)
2671  continue; /* do not look in temp namespace */
2672 
2674  PointerGetDatum(config_name),
2675  ObjectIdGetDatum(namespaceId));
2676  if (OidIsValid(cfgoid))
2677  break;
2678  }
2679  }
2680 
2681  if (!OidIsValid(cfgoid) && !missing_ok)
2682  ereport(ERROR,
2683  (errcode(ERRCODE_UNDEFINED_OBJECT),
2684  errmsg("text search configuration \"%s\" does not exist",
2685  NameListToString(names))));
2686 
2687  return cfgoid;
2688 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2853
#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:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:188
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:3063
#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 2386 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().

2387 {
2388  char *schemaname;
2389  char *dict_name;
2390  Oid namespaceId;
2391  Oid dictoid = InvalidOid;
2392  ListCell *l;
2393 
2394  /* deconstruct the name list */
2395  DeconstructQualifiedName(names, &schemaname, &dict_name);
2396 
2397  if (schemaname)
2398  {
2399  /* use exact schema given */
2400  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2401  if (missing_ok && !OidIsValid(namespaceId))
2402  dictoid = InvalidOid;
2403  else
2404  dictoid = GetSysCacheOid2(TSDICTNAMENSP,
2405  PointerGetDatum(dict_name),
2406  ObjectIdGetDatum(namespaceId));
2407  }
2408  else
2409  {
2410  /* search for it in search path */
2412 
2413  foreach(l, activeSearchPath)
2414  {
2415  namespaceId = lfirst_oid(l);
2416 
2417  if (namespaceId == myTempNamespace)
2418  continue; /* do not look in temp namespace */
2419 
2420  dictoid = GetSysCacheOid2(TSDICTNAMENSP,
2421  PointerGetDatum(dict_name),
2422  ObjectIdGetDatum(namespaceId));
2423  if (OidIsValid(dictoid))
2424  break;
2425  }
2426  }
2427 
2428  if (!OidIsValid(dictoid) && !missing_ok)
2429  ereport(ERROR,
2430  (errcode(ERRCODE_UNDEFINED_OBJECT),
2431  errmsg("text search dictionary \"%s\" does not exist",
2432  NameListToString(names))));
2433 
2434  return dictoid;
2435 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2853
#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:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:188
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:3063
#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 2260 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().

2261 {
2262  char *schemaname;
2263  char *parser_name;
2264  Oid namespaceId;
2265  Oid prsoid = InvalidOid;
2266  ListCell *l;
2267 
2268  /* deconstruct the name list */
2269  DeconstructQualifiedName(names, &schemaname, &parser_name);
2270 
2271  if (schemaname)
2272  {
2273  /* use exact schema given */
2274  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2275  if (missing_ok && !OidIsValid(namespaceId))
2276  prsoid = InvalidOid;
2277  else
2279  PointerGetDatum(parser_name),
2280  ObjectIdGetDatum(namespaceId));
2281  }
2282  else
2283  {
2284  /* search for it in search path */
2286 
2287  foreach(l, activeSearchPath)
2288  {
2289  namespaceId = lfirst_oid(l);
2290 
2291  if (namespaceId == myTempNamespace)
2292  continue; /* do not look in temp namespace */
2293 
2295  PointerGetDatum(parser_name),
2296  ObjectIdGetDatum(namespaceId));
2297  if (OidIsValid(prsoid))
2298  break;
2299  }
2300  }
2301 
2302  if (!OidIsValid(prsoid) && !missing_ok)
2303  ereport(ERROR,
2304  (errcode(ERRCODE_UNDEFINED_OBJECT),
2305  errmsg("text search parser \"%s\" does not exist",
2306  NameListToString(names))));
2307 
2308  return prsoid;
2309 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2853
#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:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:188
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:3063
#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 2513 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().

2514 {
2515  char *schemaname;
2516  char *template_name;
2517  Oid namespaceId;
2518  Oid tmploid = InvalidOid;
2519  ListCell *l;
2520 
2521  /* deconstruct the name list */
2522  DeconstructQualifiedName(names, &schemaname, &template_name);
2523 
2524  if (schemaname)
2525  {
2526  /* use exact schema given */
2527  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2528  if (missing_ok && !OidIsValid(namespaceId))
2529  tmploid = InvalidOid;
2530  else
2532  PointerGetDatum(template_name),
2533  ObjectIdGetDatum(namespaceId));
2534  }
2535  else
2536  {
2537  /* search for it in search path */
2539 
2540  foreach(l, activeSearchPath)
2541  {
2542  namespaceId = lfirst_oid(l);
2543 
2544  if (namespaceId == myTempNamespace)
2545  continue; /* do not look in temp namespace */
2546 
2548  PointerGetDatum(template_name),
2549  ObjectIdGetDatum(namespaceId));
2550  if (OidIsValid(tmploid))
2551  break;
2552  }
2553  }
2554 
2555  if (!OidIsValid(tmploid) && !missing_ok)
2556  ereport(ERROR,
2557  (errcode(ERRCODE_UNDEFINED_OBJECT),
2558  errmsg("text search template \"%s\" does not exist",
2559  NameListToString(names))));
2560 
2561  return tmploid;
2562 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2853
#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:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:188
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:3063
#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 3281 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().

3282 {
3284  List *schemas;
3285  MemoryContext oldcxt;
3286 
3288 
3289  oldcxt = MemoryContextSwitchTo(context);
3290 
3291  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3292  schemas = list_copy(activeSearchPath);
3293  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3294  {
3295  if (linitial_oid(schemas) == myTempNamespace)
3296  result->addTemp = true;
3297  else
3298  {
3300  result->addCatalog = true;
3301  }
3302  schemas = list_delete_first(schemas);
3303  }
3304  result->schemas = schemas;
3305 
3306  MemoryContextSwitchTo(oldcxt);
3307 
3308  return result;
3309 }
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:1633
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
static Oid activeCreationNamespace
Definition: namespace.c:137
#define PG_CATALOG_NAMESPACE
Definition: pg_namespace.h:71
void * palloc0(Size size)
Definition: mcxt.c:877
#define Assert(condition)
Definition: c.h:664
#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 3195 of file namespace.c.

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

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

3196 {
3197  int result;
3198  char *nspname;
3199 
3200  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3201  nspname = get_namespace_name(namespaceId);
3202  if (!nspname)
3203  return InvalidBackendId; /* no such namespace? */
3204  if (strncmp(nspname, "pg_temp_", 8) == 0)
3205  result = atoi(nspname + 8);
3206  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3207  result = atoi(nspname + 14);
3208  else
3209  result = InvalidBackendId;
3210  pfree(nspname);
3211  return result;
3212 }
return result
Definition: formatting.c:1633
void pfree(void *pointer)
Definition: mcxt.c:949
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 3234 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3235 {
3236  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3237  *tempNamespaceId = myTempNamespace;
3238  *tempToastNamespaceId = myTempToastNamespace;
3239 }
static Oid myTempToastNamespace
Definition: namespace.c:183
static Oid myTempNamespace
Definition: namespace.c:181
Oid GetTempToastNamespace ( void  )

Definition at line 3220 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3221 {
3223  return myTempToastNamespace;
3224 }
static Oid myTempToastNamespace
Definition: namespace.c:183
#define OidIsValid(objectId)
Definition: c.h:532
#define Assert(condition)
Definition: c.h:664
void InitializeSearchPath ( void  )

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

4111 {
4113  {
4114  /*
4115  * In bootstrap mode, the search path must be 'pg_catalog' so that
4116  * tables are created in the proper namespace; ignore the GUC setting.
4117  */
4118  MemoryContext oldcxt;
4119 
4122  MemoryContextSwitchTo(oldcxt);
4124  baseTempCreationPending = false;
4125  baseSearchPathValid = true;
4130  }
4131  else
4132  {
4133  /*
4134  * In normal mode, arrange for a callback on any syscache invalidation
4135  * of pg_namespace rows.
4136  */
4139  (Datum) 0);
4140  /* Force search path to be recomputed on next use */
4141  baseSearchPathValid = false;
4142  }
4143 }
static bool baseSearchPathValid
Definition: namespace.c:153
Oid GetUserId(void)
Definition: miscinit.c:284
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:4150
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:368
static List * activeSearchPath
Definition: namespace.c:134
static void InitTempTableNamespace ( void  )
static

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

3780 {
3781  char namespaceName[NAMEDATALEN];
3782  Oid namespaceId;
3783  Oid toastspaceId;
3784 
3786 
3787  /*
3788  * First, do permission check to see if we are authorized to make temp
3789  * tables. We use a nonstandard error message here since "databasename:
3790  * permission denied" might be a tad cryptic.
3791  *
3792  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
3793  * that's necessary since current user ID could change during the session.
3794  * But there's no need to make the namespace in the first place until a
3795  * temp table creation request is made by someone with appropriate rights.
3796  */
3799  ereport(ERROR,
3800  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3801  errmsg("permission denied to create temporary tables in database \"%s\"",
3803 
3804  /*
3805  * Do not allow a Hot Standby session to make temp tables. Aside from
3806  * problems with modifying the system catalogs, there is a naming
3807  * conflict: pg_temp_N belongs to the session with BackendId N on the
3808  * master, not to a hot standby session with the same BackendId. We
3809  * should not be able to get here anyway due to XactReadOnly checks, but
3810  * let's just make real sure. Note that this also backstops various
3811  * operations that allow XactReadOnly transactions to modify temp tables;
3812  * they'd need RecoveryInProgress checks if not for this.
3813  */
3814  if (RecoveryInProgress())
3815  ereport(ERROR,
3816  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3817  errmsg("cannot create temporary tables during recovery")));
3818 
3819  /* Parallel workers can't create temporary tables, either. */
3820  if (IsParallelWorker())
3821  ereport(ERROR,
3822  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
3823  errmsg("cannot create temporary tables during a parallel operation")));
3824 
3825  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
3826 
3827  namespaceId = get_namespace_oid(namespaceName, true);
3828  if (!OidIsValid(namespaceId))
3829  {
3830  /*
3831  * First use of this temp namespace in this database; create it. The
3832  * temp namespaces are always owned by the superuser. We leave their
3833  * permissions at default --- i.e., no access except to superuser ---
3834  * to ensure that unprivileged users can't peek at other backends'
3835  * temp tables. This works because the places that access the temp
3836  * namespace for my own backend skip permissions checks on it.
3837  */
3838  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3839  true);
3840  /* Advance command counter to make namespace visible */
3842  }
3843  else
3844  {
3845  /*
3846  * If the namespace already exists, clean it out (in case the former
3847  * owner crashed without doing so).
3848  */
3849  RemoveTempRelations(namespaceId);
3850  }
3851 
3852  /*
3853  * If the corresponding toast-table namespace doesn't exist yet, create
3854  * it. (We assume there is no need to clean it out if it does exist, since
3855  * dropping a parent table should make its toast table go away.)
3856  */
3857  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
3858  MyBackendId);
3859 
3860  toastspaceId = get_namespace_oid(namespaceName, true);
3861  if (!OidIsValid(toastspaceId))
3862  {
3863  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
3864  true);
3865  /* Advance command counter to make namespace visible */
3867  }
3868 
3869  /*
3870  * Okay, we've prepared the temp namespace ... but it's not committed yet,
3871  * so all our work could be undone by transaction rollback. Set flag for
3872  * AtEOXact_Namespace to know what to do.
3873  */
3874  myTempNamespace = namespaceId;
3875  myTempToastNamespace = toastspaceId;
3876 
3877  /* It should not be done already. */
3880 
3881  baseSearchPathValid = false; /* need to rebuild list */
3882 }
static bool baseSearchPathValid
Definition: namespace.c:153
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3005
BackendId MyBackendId
Definition: globals.c:73
#define AssertState(condition)
Definition: c.h:667
Oid GetUserId(void)
Definition: miscinit.c:284
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:7962
#define OidIsValid(objectId)
Definition: c.h:532
#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:923
Oid MyDatabaseId
Definition: globals.c:77
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4434
#define Assert(condition)
Definition: c.h:664
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:650
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4003
#define BOOTSTRAP_SUPERUSERID
Definition: pg_authid.h:102
#define InvalidSubTransactionId
Definition: c.h:397
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 3156 of file namespace.c.

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

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

3157 {
3158  bool result;
3159  char *nspname;
3160 
3161  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3162  nspname = get_namespace_name(namespaceId);
3163  if (!nspname)
3164  return false; /* no such namespace? */
3165  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3166  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3167  pfree(nspname);
3168  return result;
3169 }
return result
Definition: formatting.c:1633
void pfree(void *pointer)
Definition: mcxt.c:949
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3179 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

3180 {
3181  /* If it's my own temp namespace, say "false" */
3182  if (isTempOrTempToastNamespace(namespaceId))
3183  return false;
3184  /* Else, if it's any temp namespace, say "true" */
3185  return isAnyTempNamespace(namespaceId);
3186 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3142
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3156
bool isTempNamespace ( Oid  namespaceId)

Definition at line 3118 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

3119 {
3120  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3121  return true;
3122  return false;
3123 }
static Oid myTempNamespace
Definition: namespace.c:181
#define OidIsValid(objectId)
Definition: c.h:532
bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3142 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

3143 {
3144  if (OidIsValid(myTempNamespace) &&
3145  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3146  return true;
3147  return false;
3148 }
static Oid myTempToastNamespace
Definition: namespace.c:183
static Oid myTempNamespace
Definition: namespace.c:181
#define OidIsValid(objectId)
Definition: c.h:532
bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3130 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

3131 {
3132  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3133  return true;
3134  return false;
3135 }
static Oid myTempToastNamespace
Definition: namespace.c:183
#define OidIsValid(objectId)
Definition: c.h:532
static Oid lookup_collation ( const char *  collname,
Oid  collnamespace,
int32  encoding 
)
static

Definition at line 1923 of file namespace.c.

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

Referenced by CollationGetCollid(), and get_collation_oid().

1924 {
1925  Oid collid;
1926  HeapTuple colltup;
1927  Form_pg_collation collform;
1928 
1929  /* Check for encoding-specific entry (exact match) */
1931  PointerGetDatum(collname),
1933  ObjectIdGetDatum(collnamespace));
1934  if (OidIsValid(collid))
1935  return collid;
1936 
1937  /*
1938  * Check for any-encoding entry. This takes a bit more work: while libc
1939  * collations with collencoding = -1 do work with all encodings, ICU
1940  * collations only work with certain encodings, so we have to check that
1941  * aspect before deciding it's a match.
1942  */
1943  colltup = SearchSysCache3(COLLNAMEENCNSP,
1944  PointerGetDatum(collname),
1945  Int32GetDatum(-1),
1946  ObjectIdGetDatum(collnamespace));
1947  if (!HeapTupleIsValid(colltup))
1948  return InvalidOid;
1949  collform = (Form_pg_collation) GETSTRUCT(colltup);
1950  if (collform->collprovider == COLLPROVIDER_ICU)
1951  {
1953  collid = HeapTupleGetOid(colltup);
1954  else
1955  collid = InvalidOid;
1956  }
1957  else
1958  {
1959  collid = HeapTupleGetOid(colltup);
1960  }
1961  ReleaseSysCache(colltup);
1962  return collid;
1963 }
#define COLLPROVIDER_ICU
Definition: pg_collation.h:85
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define PointerGetDatum(X)
Definition: postgres.h:562
bool is_encoding_supported_by_icu(int encoding)
Definition: encnames.c:455
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:190
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
#define InvalidOid
Definition: postgres_ext.h:36
static char * encoding
Definition: initdb.c:123
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:52
#define Int32GetDatum(X)
Definition: postgres.h:485
#define SearchSysCache3(cacheId, key1, key2, key3)
Definition: syscache.h:163
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
Oid LookupCreationNamespace ( const char *  nspname)

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

2897 {
2898  Oid namespaceId;
2899  AclResult aclresult;
2900 
2901  /* check for pg_temp alias */
2902  if (strcmp(nspname, "pg_temp") == 0)
2903  {
2904  /* Initialize temp namespace if first time through */
2907  return myTempNamespace;
2908  }
2909 
2910  namespaceId = get_namespace_oid(nspname, false);
2911 
2912  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2913  if (aclresult != ACLCHECK_OK)
2915  nspname);
2916 
2917  return namespaceId;
2918 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3005
Oid GetUserId(void)
Definition: miscinit.c:284
static Oid myTempNamespace
Definition: namespace.c:181
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
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:3779
AclResult
Definition: acl.h:178
Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

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

2854 {
2855  Oid namespaceId;
2856  AclResult aclresult;
2857 
2858  /* check for pg_temp alias */
2859  if (strcmp(nspname, "pg_temp") == 0)
2860  {
2862  return myTempNamespace;
2863 
2864  /*
2865  * Since this is used only for looking up existing objects, there is
2866  * no point in trying to initialize the temp namespace here; and doing
2867  * so might create problems for some callers --- just fall through.
2868  */
2869  }
2870 
2871  namespaceId = get_namespace_oid(nspname, missing_ok);
2872  if (missing_ok && !OidIsValid(namespaceId))
2873  return InvalidOid;
2874 
2875  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
2876  if (aclresult != ACLCHECK_OK)
2878  nspname);
2879  /* Schema search hook for this lookup */
2880  InvokeNamespaceSearchHook(namespaceId, true);
2881 
2882  return namespaceId;
2883 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3005
Oid GetUserId(void)
Definition: miscinit.c:284
static Oid myTempNamespace
Definition: namespace.c:181
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
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:178
#define InvalidOid
Definition: postgres_ext.h:36
Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2823 of file namespace.c.

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

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

2824 {
2825  /* check for pg_temp alias */
2826  if (strcmp(nspname, "pg_temp") == 0)
2827  {
2829  {
2831  return myTempNamespace;
2832  }
2833 
2834  /*
2835  * Since this is used only for looking up existing objects, there is
2836  * no point in trying to initialize the temp namespace here; and doing
2837  * so might create problems for some callers. Just report "not found".
2838  */
2839  return InvalidOid;
2840  }
2841 
2842  return get_namespace_oid(nspname, true);
2843 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3005
static Oid myTempNamespace
Definition: namespace.c:181
#define OidIsValid(objectId)
Definition: c.h:532
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:174
#define InvalidOid
Definition: postgres_ext.h:36
RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 3023 of file namespace.c.

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

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

3024 {
3025  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3026 
3027  switch (list_length(names))
3028  {
3029  case 1:
3030  rel->relname = strVal(linitial(names));
3031  break;
3032  case 2:
3033  rel->schemaname = strVal(linitial(names));
3034  rel->relname = strVal(lsecond(names));
3035  break;
3036  case 3:
3037  rel->catalogname = strVal(linitial(names));
3038  rel->schemaname = strVal(lsecond(names));
3039  rel->relname = strVal(lthird(names));
3040  break;
3041  default:
3042  ereport(ERROR,
3043  (errcode(ERRCODE_SYNTAX_ERROR),
3044  errmsg("improper relation name (too many dotted names): %s",
3045  NameListToString(names))));
3046  break;
3047  }
3048 
3049  return rel;
3050 }
#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:3063
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, 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:793
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:1325
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
#define Assert(condition)
Definition: c.h:664
#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:848
int i
char* NameListToQuotedString ( List names)

Definition at line 3097 of file namespace.c.

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

3098 {
3100  ListCell *l;
3101 
3102  initStringInfo(&string);
3103 
3104  foreach(l, names)
3105  {
3106  if (l != list_head(names))
3107  appendStringInfoChar(&string, '.');
3109  }
3110 
3111  return string.data;
3112 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10390
#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 3063 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().

3064 {
3066  ListCell *l;
3067 
3068  initStringInfo(&string);
3069 
3070  foreach(l, names)
3071  {
3072  Node *name = (Node *) lfirst(l);
3073 
3074  if (l != list_head(names))
3075  appendStringInfoChar(&string, '.');
3076 
3077  if (IsA(name, String))
3078  appendStringInfoString(&string, strVal(name));
3079  else if (IsA(name, A_Star))
3080  appendStringInfoChar(&string, '*');
3081  else
3082  elog(ERROR, "unexpected node type in name list: %d",
3083  (int) nodeTag(name));
3084  }
3085 
3086  return string.data;
3087 }
#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 4150 of file namespace.c.

References baseSearchPathValid.

Referenced by InitializeSearchPath().

4151 {
4152  /* Force search path to be recomputed on next use */
4153  baseSearchPathValid = false;
4154 }
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:159
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:493
#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:532
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:190
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:159
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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:493
#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, _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:2853
#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:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:155
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:37
struct _FuncCandidateList * FuncCandidateList
#define CStringGetDatum(X)
Definition: postgres.h:584
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:204
#define SPACE_PER_OP
struct _FuncCandidateList * next
Definition: namespace.h:30
#define ReleaseSysCacheList(x)
Definition: syscache.h:213
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:664
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:848
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:2853
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SearchSysCache4(cacheId, key1, key2, key3, key4)
Definition: syscache.h:165
static Oid myTempNamespace
Definition: namespace.c:181
return result
Definition: formatting.c:1633
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
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:213
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:208
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:159
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
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:493
#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:532
#define GetSysCacheOid3(cacheId, key1, key2, key3)
Definition: syscache.h:190
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
#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 3333 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().

3334 {
3335  ListCell *lc,
3336  *lcp;
3337 
3339 
3340  /* We scan down the activeSearchPath to see if it matches the input. */
3342 
3343  /* If path->addTemp, first item should be my temp namespace. */
3344  if (path->addTemp)
3345  {
3346  if (lc && lfirst_oid(lc) == myTempNamespace)
3347  lc = lnext(lc);
3348  else
3349  return false;
3350  }
3351  /* If path->addCatalog, next item should be pg_catalog. */
3352  if (path->addCatalog)
3353  {
3354  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3355  lc = lnext(lc);
3356  else
3357  return false;
3358  }
3359  /* We should now be looking at the activeCreationNamespace. */
3360  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3361  return false;
3362  /* The remainder of activeSearchPath should match path->schemas. */
3363  foreach(lcp, path->schemas)
3364  {
3365  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3366  lc = lnext(lc);
3367  else
3368  return false;
3369  }
3370  if (lc)
3371  return false;
3372  return true;
3373 }
static Oid myTempNamespace
Definition: namespace.c:181
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
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 4311 of file namespace.c.

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

4312 {
4313  Oid oid = PG_GETARG_OID(0);
4314 
4316  PG_RETURN_NULL();
4317 
4319 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
bool CollationIsVisible(Oid collid)
Definition: namespace.c:2008
#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 4322 of file namespace.c.

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

4323 {
4324  Oid oid = PG_GETARG_OID(0);
4325 
4327  PG_RETURN_NULL();
4328 
4330 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#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:2091
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4267 of file namespace.c.

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

4268 {
4269  Oid oid = PG_GETARG_OID(0);
4270 
4272  PG_RETURN_NULL();
4273 
4275 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#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 4394 of file namespace.c.

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

4395 {
4396  Oid oid = PG_GETARG_OID(0);
4397 
4399 }
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:3179
Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4388 of file namespace.c.

References myTempNamespace, and PG_RETURN_OID.

4389 {
4391 }
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 4289 of file namespace.c.

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

4290 {
4291  Oid oid = PG_GETARG_OID(0);
4292 
4294  PG_RETURN_NULL();
4295 
4297 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#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 4278 of file namespace.c.

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

4279 {
4280  Oid oid = PG_GETARG_OID(0);
4281 
4283  PG_RETURN_NULL();
4284 
4286 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1707
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#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 4300 of file namespace.c.

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

4301 {
4302  Oid oid = PG_GETARG_OID(0);
4303 
4305  PG_RETURN_NULL();
4306 
4308 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#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 4333 of file namespace.c.

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

4334 {
4335  Oid oid = PG_GETARG_OID(0);
4336 
4338  PG_RETURN_NULL();
4339 
4341 }
bool StatisticsObjIsVisible(Oid relid)
Definition: namespace.c:2195
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#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 4245 of file namespace.c.

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

4246 {
4247  Oid oid = PG_GETARG_OID(0);
4248 
4250  PG_RETURN_NULL();
4251 
4253 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#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 4377 of file namespace.c.

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

4378 {
4379  Oid oid = PG_GETARG_OID(0);
4380 
4382  PG_RETURN_NULL();
4383 
4385 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2697
#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 4355 of file namespace.c.

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

4356 {
4357  Oid oid = PG_GETARG_OID(0);
4358 
4360  PG_RETURN_NULL();
4361 
4363 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2444
#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 4344 of file namespace.c.

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

4345 {
4346  Oid oid = PG_GETARG_OID(0);
4347 
4349  PG_RETURN_NULL();
4350 
4352 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#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:2318
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4366 of file namespace.c.

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

4367 {
4368  Oid oid = PG_GETARG_OID(0);
4369 
4371  PG_RETURN_NULL();
4372 
4374 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#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:2571
#define PG_RETURN_NULL()
Definition: fmgr.h:305
Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4256 of file namespace.c.

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

4257 {
4258  Oid oid = PG_GETARG_OID(0);
4259 
4261  PG_RETURN_NULL();
4262 
4264 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:177
#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 3452 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().

3453 {
3454  OverrideStackEntry *entry;
3455 
3456  /* Sanity checks. */
3457  if (overrideStack == NIL)
3458  elog(ERROR, "bogus PopOverrideSearchPath call");
3460  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3461  elog(ERROR, "bogus PopOverrideSearchPath call");
3462 
3463  /* Pop the stack and free storage. */
3465  list_free(entry->searchPath);
3466  pfree(entry);
3467 
3468  /* Activate the next level down. */
3469  if (overrideStack)
3470  {
3472  activeSearchPath = entry->searchPath;
3474  activeTempCreationPending = false; /* XXX is this OK? */
3475  }
3476  else
3477  {
3478  /* If not baseSearchPathValid, this is useless but harmless */
3482  }
3483 }
#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:949
#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:762
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 3393 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().

3394 {
3395  OverrideStackEntry *entry;
3396  List *oidlist;
3397  Oid firstNS;
3398  MemoryContext oldcxt;
3399 
3400  /*
3401  * Copy the list for safekeeping, and insert implicitly-searched
3402  * namespaces as needed. This code should track recomputeNamespacePath.
3403  */
3405 
3406  oidlist = list_copy(newpath->schemas);
3407 
3408  /*
3409  * Remember the first member of the explicit list.
3410  */
3411  if (oidlist == NIL)
3412  firstNS = InvalidOid;
3413  else
3414  firstNS = linitial_oid(oidlist);
3415 
3416  /*
3417  * Add any implicitly-searched namespaces to the list. Note these go on
3418  * the front, not the back; also notice that we do not check USAGE
3419  * permissions for these.
3420  */
3421  if (newpath->addCatalog)
3422  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3423 
3424  if (newpath->addTemp && OidIsValid(myTempNamespace))
3425  oidlist = lcons_oid(myTempNamespace, oidlist);
3426 
3427  /*
3428  * Build the new stack entry, then insert it at the head of the list.
3429  */
3430  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3431  entry->searchPath = oidlist;
3432  entry->creationNamespace = firstNS;
3434 
3435  overrideStack = lcons(entry, overrideStack);
3436 
3437  /* And make it active. */
3438  activeSearchPath = entry->searchPath;
3440  activeTempCreationPending = false; /* XXX is this OK? */
3441 
3442  MemoryContextSwitchTo(oldcxt);
3443 }
#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:532
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:762
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:848
Definition: pg_list.h:45
Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

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

2957 {
2958  char *schemaname;
2959  Oid namespaceId;
2960 
2961  /* deconstruct the name list */
2962  DeconstructQualifiedName(names, &schemaname, objname_p);
2963 
2964  if (schemaname)
2965  {
2966  /* check for pg_temp alias */
2967  if (strcmp(schemaname, "pg_temp") == 0)
2968  {
2969  /* Initialize temp namespace if first time through */
2972  return myTempNamespace;
2973  }
2974  /* use exact schema given */
2975  namespaceId = get_namespace_oid(schemaname, false);
2976  /* we do not check for USAGE rights here! */
2977  }
2978  else
2979  {
2980  /* use the default creation namespace */
2983  {
2984  /* Need to initialize temp namespace */
2986  return myTempNamespace;
2987  }
2988  namespaceId = activeCreationNamespace;
2989  if (!OidIsValid(namespaceId))
2990  ereport(ERROR,
2991  (errcode(ERRCODE_UNDEFINED_SCHEMA),
2992  errmsg("no schema has been selected to create in")));
2993  }
2994 
2995  return namespaceId;
2996 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3005
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:2769
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
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:3779
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:3142
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:3156
#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, 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:284
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:532
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:178
Oid MyDatabaseId
Definition: globals.c:77
uint64 SharedInvalidMessageCounter
Definition: sinval.c:26
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:664
bool pg_class_ownercheck(Oid class_oid, Oid roleid)
Definition: aclchk.c:4546
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:368
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:3005
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:532
static void recomputeNamespacePath(void)
Definition: namespace.c:3629
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:3779
Oid MyDatabaseId
Definition: globals.c:77
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(), AlterSequence(), 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:2853
#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:532
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:77
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 3629 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().

3630 {
3631  Oid roleid = GetUserId();
3632  char *rawname;
3633  List *namelist;
3634  List *oidlist;
3635  List *newpath;
3636  ListCell *l;
3637  bool temp_missing;
3638  Oid firstNS;
3639  MemoryContext oldcxt;
3640 
3641  /* Do nothing if an override search spec is active. */
3642  if (overrideStack)
3643  return;
3644 
3645  /* Do nothing if path is already valid. */
3646  if (baseSearchPathValid && namespaceUser == roleid)
3647  return;
3648 
3649  /* Need a modifiable copy of namespace_search_path string */
3650  rawname = pstrdup(