PostgreSQL Source Code  git master
namespace.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/parallel.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/dependency.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_ts_parser.h"
#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "funcapi.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_func.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/sinvaladt.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 AccessTempTableNamespace (bool force)
 
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, bool include_out_arguments, int pronargs, int **argnumbers)
 
Oid RangeVarGetRelidExtended (const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
 
Oid RangeVarGetCreationNamespace (const RangeVar *newRelation)
 
Oid RangeVarGetAndCheckCreationNamespace (RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
 
void RangeVarAdjustRelationPersistence (RangeVar *newRelation, Oid nspid)
 
Oid RelnameGetRelid (const char *relname)
 
bool RelationIsVisible (Oid relid)
 
Oid TypenameGetTypid (const char *typname)
 
Oid TypenameGetTypidExtended (const char *typname, bool temp_ok)
 
bool TypeIsVisible (Oid typid)
 
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, 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)
 
TempNamespaceStatus checkTempNamespaceStatus (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 uint64 activePathGeneration = 1
 
static ListbaseSearchPath = NIL
 
static Oid baseCreationNamespace = InvalidOid
 
static bool baseTempCreationPending = false
 
static Oid namespaceUser = InvalidOid
 
static bool baseSearchPathValid = true
 
static ListoverrideStack = NIL
 
static Oid myTempNamespace = InvalidOid
 
static Oid myTempToastNamespace = InvalidOid
 
static SubTransactionId myTempNamespaceSubID = InvalidSubTransactionId
 
char * namespace_search_path = NULL
 

Macro Definition Documentation

◆ SPACE_PER_OP

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

Referenced by OpernameGetCandidates().

Function Documentation

◆ AccessTempTableNamespace()

static void AccessTempTableNamespace ( bool  force)
static

Definition at line 3960 of file namespace.c.

References InitTempTableNamespace(), myTempNamespace, MyXactFlags, OidIsValid, and XACT_FLAGS_ACCESSEDTEMPNAMESPACE.

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

3961 {
3962  /*
3963  * Make note that this temporary namespace has been accessed in this
3964  * transaction.
3965  */
3967 
3968  /*
3969  * If the caller attempting to access a temporary schema expects the
3970  * creation of the namespace to be pending and should be enforced, then go
3971  * through the creation.
3972  */
3973  if (!force && OidIsValid(myTempNamespace))
3974  return;
3975 
3976  /*
3977  * The temporary tablespace does not exist yet and is wanted, so
3978  * initialize it.
3979  */
3981 }
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:710
int MyXactFlags
Definition: xact.c:132
static void InitTempTableNamespace(void)
Definition: namespace.c:3988
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition: xact.h:102

◆ assign_search_path()

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

Definition at line 4353 of file namespace.c.

References baseSearchPathValid.

4354 {
4355  /*
4356  * We mark the path as needing recomputation, but don't do anything until
4357  * it's needed. This avoids trying to do database access during GUC
4358  * initialization, or outside a transaction.
4359  */
4360  baseSearchPathValid = false;
4361 }
static bool baseSearchPathValid
Definition: namespace.c:160

◆ AtEOSubXact_Namespace()

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

Definition at line 4177 of file namespace.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

4179 {
4180  OverrideStackEntry *entry;
4181 
4182  if (myTempNamespaceSubID == mySubid)
4183  {
4184  if (isCommit)
4185  myTempNamespaceSubID = parentSubid;
4186  else
4187  {
4189  /* TEMP namespace creation failed, so reset state */
4192  baseSearchPathValid = false; /* need to rebuild list */
4193 
4194  /*
4195  * Reset the temporary namespace flag in MyProc. We assume that
4196  * this operation is atomic.
4197  *
4198  * Because this subtransaction is aborting, the pg_namespace row
4199  * is not visible to anyone else anyway, but that doesn't matter:
4200  * it's not a problem if objects contained in this namespace are
4201  * removed concurrently.
4202  */
4204  }
4205  }
4206 
4207  /*
4208  * Clean up if someone failed to do PopOverrideSearchPath
4209  */
4210  while (overrideStack)
4211  {
4214  break;
4215  if (isCommit)
4216  elog(WARNING, "leaked override search path");
4218  list_free(entry->searchPath);
4219  pfree(entry);
4220  /* Always bump generation --- see note in recomputeNamespacePath */
4222  }
4223 
4224  /* Activate the next level down. */
4225  if (overrideStack)
4226  {
4228  activeSearchPath = entry->searchPath;
4230  activeTempCreationPending = false; /* XXX is this OK? */
4231 
4232  /*
4233  * It's probably unnecessary to bump generation here, but this should
4234  * not be a performance-critical case, so better to be over-cautious.
4235  */
4237  }
4238  else
4239  {
4240  /* If not baseSearchPathValid, this is useless but harmless */
4244 
4245  /*
4246  * If we popped an override stack entry, then we already bumped the
4247  * generation above. If we did not, then the above assignments did
4248  * nothing and we need not bump the generation.
4249  */
4250  }
4251 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid tempNamespaceId
Definition: proc.h:157
PGPROC * MyProc
Definition: proc.c:68
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1169
#define linitial(l)
Definition: pg_list.h:174
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:151
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
#define InvalidSubTransactionId
Definition: c.h:593
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1391
#define elog(elevel,...)
Definition: elog.h:232
List * list_delete_first(List *list)
Definition: list.c:875

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4109 of file namespace.c.

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

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

4110 {
4111  /*
4112  * If we abort the transaction in which a temp namespace was selected,
4113  * we'll have to do any creation or cleanout work over again. So, just
4114  * forget the namespace entirely until next time. On the other hand, if
4115  * we commit then register an exit callback to clean out the temp tables
4116  * at backend shutdown. (We only want to register the callback once per
4117  * session, so this is a good place to do it.)
4118  */
4119  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
4120  {
4121  if (isCommit)
4123  else
4124  {
4127  baseSearchPathValid = false; /* need to rebuild list */
4128 
4129  /*
4130  * Reset the temporary namespace flag in MyProc. We assume that
4131  * this operation is atomic.
4132  *
4133  * Because this transaction is aborting, the pg_namespace row is
4134  * not visible to anyone else anyway, but that doesn't matter:
4135  * it's not a problem if objects contained in this namespace are
4136  * removed concurrently.
4137  */
4139  }
4141  }
4142 
4143  /*
4144  * Clean up if someone failed to do PopOverrideSearchPath
4145  */
4146  if (overrideStack)
4147  {
4148  if (isCommit)
4149  elog(WARNING, "leaked override search path");
4150  while (overrideStack)
4151  {
4152  OverrideStackEntry *entry;
4153 
4156  list_free(entry->searchPath);
4157  pfree(entry);
4158  }
4159  /* If not baseSearchPathValid, this is useless but harmless */
4163  /* Always bump generation --- see note in recomputeNamespacePath */
4165  }
4166 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid tempNamespaceId
Definition: proc.h:157
PGPROC * MyProc
Definition: proc.c:68
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1169
#define linitial(l)
Definition: pg_list.h:174
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
#define WARNING
Definition: elog.h:40
static List * baseSearchPath
Definition: namespace.c:151
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidSubTransactionId
Definition: c.h:593
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1391
#define elog(elevel,...)
Definition: elog.h:232
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4288
List * list_delete_first(List *list)
Definition: list.c:875

◆ check_search_path()

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

Definition at line 4319 of file namespace.c.

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

4320 {
4321  char *rawname;
4322  List *namelist;
4323 
4324  /* Need a modifiable copy of string */
4325  rawname = pstrdup(*newval);
4326 
4327  /* Parse string into list of identifiers */
4328  if (!SplitIdentifierString(rawname, ',', &namelist))
4329  {
4330  /* syntax error in name list */
4331  GUC_check_errdetail("List syntax is invalid.");
4332  pfree(rawname);
4333  list_free(namelist);
4334  return false;
4335  }
4336 
4337  /*
4338  * We used to try to check that the named schemas exist, but there are
4339  * many valid use-cases for having search_path settings that include
4340  * schemas that don't exist; and often, we are not inside a transaction
4341  * here and so can't consult the system catalogs anyway. So now, the only
4342  * requirement is syntactic validity of the identifier list.
4343  */
4344 
4345  pfree(rawname);
4346  list_free(namelist);
4347 
4348  return true;
4349 }
#define GUC_check_errdetail
Definition: guc.h:416
char * pstrdup(const char *in)
Definition: mcxt.c:1299
void pfree(void *pointer)
Definition: mcxt.c:1169
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3753
#define newval
void list_free(List *list)
Definition: list.c:1391
Definition: pg_list.h:50

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 3012 of file namespace.c.

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

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

3013 {
3014  /* disallow renaming into or out of temp schemas */
3015  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
3016  ereport(ERROR,
3017  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3018  errmsg("cannot move objects into or out of temporary schemas")));
3019 
3020  /* same for TOAST schema */
3021  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
3022  ereport(ERROR,
3023  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3024  errmsg("cannot move objects into or out of TOAST schema")));
3025 }
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3240

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3282 of file namespace.c.

References Assert, BackendIdGetProc(), PGPROC::databaseId, GetTempNamespaceBackendId(), InvalidBackendId, MyDatabaseId, OidIsValid, TEMP_NAMESPACE_IDLE, TEMP_NAMESPACE_IN_USE, TEMP_NAMESPACE_NOT_TEMP, and PGPROC::tempNamespaceId.

Referenced by do_autovacuum().

3283 {
3284  PGPROC *proc;
3285  int backendId;
3286 
3288 
3289  backendId = GetTempNamespaceBackendId(namespaceId);
3290 
3291  /* No such namespace, or its name shows it's not temp? */
3292  if (backendId == InvalidBackendId)
3293  return TEMP_NAMESPACE_NOT_TEMP;
3294 
3295  /* Is the backend alive? */
3296  proc = BackendIdGetProc(backendId);
3297  if (proc == NULL)
3298  return TEMP_NAMESPACE_IDLE;
3299 
3300  /* Is the backend connected to the same database we are looking at? */
3301  if (proc->databaseId != MyDatabaseId)
3302  return TEMP_NAMESPACE_IDLE;
3303 
3304  /* Does the backend own the temporary namespace? */
3305  if (proc->tempNamespaceId != namespaceId)
3306  return TEMP_NAMESPACE_IDLE;
3307 
3308  /* Yup, so namespace is busy */
3309  return TEMP_NAMESPACE_IN_USE;
3310 }
Oid tempNamespaceId
Definition: proc.h:157
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3319
#define OidIsValid(objectId)
Definition: c.h:710
Oid databaseId
Definition: proc.h:154
#define InvalidBackendId
Definition: backendid.h:23
Oid MyDatabaseId
Definition: globals.c:88
#define Assert(condition)
Definition: c.h:804
Definition: proc.h:121
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:376

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2059 of file namespace.c.

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

Referenced by CollationIsVisible().

2060 {
2061  int32 dbencoding = GetDatabaseEncoding();
2062  ListCell *l;
2063 
2065 
2066  foreach(l, activeSearchPath)
2067  {
2068  Oid namespaceId = lfirst_oid(l);
2069  Oid collid;
2070 
2071  if (namespaceId == myTempNamespace)
2072  continue; /* do not look in temp namespace */
2073 
2074  collid = lookup_collation(collname, namespaceId, dbencoding);
2075  if (OidIsValid(collid))
2076  return collid;
2077  }
2078 
2079  /* Not found in path */
2080  return InvalidOid;
2081 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
signed int int32
Definition: c.h:429
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:2008
int GetDatabaseEncoding(void)
Definition: mbutils.c:1210
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2093 of file namespace.c.

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

Referenced by generate_collation_name(), getObjectDescription(), pg_collation_is_visible(), and regcollationout().

2094 {
2095  HeapTuple colltup;
2096  Form_pg_collation collform;
2097  Oid collnamespace;
2098  bool visible;
2099 
2100  colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
2101  if (!HeapTupleIsValid(colltup))
2102  elog(ERROR, "cache lookup failed for collation %u", collid);
2103  collform = (Form_pg_collation) GETSTRUCT(colltup);
2104 
2106 
2107  /*
2108  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2109  * the system namespace are surely in the path and so we needn't even do
2110  * list_member_oid() for them.
2111  */
2112  collnamespace = collform->collnamespace;
2113  if (collnamespace != PG_CATALOG_NAMESPACE &&
2114  !list_member_oid(activeSearchPath, collnamespace))
2115  visible = false;
2116  else
2117  {
2118  /*
2119  * If it is in the path, it might still not be visible; it could be
2120  * hidden by another collation of the same name earlier in the path,
2121  * or it might not work with the current DB encoding. So we must do a
2122  * slow check to see if this collation would be found by
2123  * CollationGetCollid.
2124  */
2125  char *collname = NameStr(collform->collname);
2126 
2127  visible = (CollationGetCollid(collname) == collid);
2128  }
2129 
2130  ReleaseSysCache(colltup);
2131 
2132  return visible;
2133 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
Oid CollationGetCollid(const char *collname)
Definition: namespace.c:2059
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:56
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2144 of file namespace.c.

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

Referenced by ConversionIsVisible().

2145 {
2146  Oid conid;
2147  ListCell *l;
2148 
2150 
2151  foreach(l, activeSearchPath)
2152  {
2153  Oid namespaceId = lfirst_oid(l);
2154 
2155  if (namespaceId == myTempNamespace)
2156  continue; /* do not look in temp namespace */
2157 
2158  conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2159  PointerGetDatum(conname),
2160  ObjectIdGetDatum(namespaceId));
2161  if (OidIsValid(conid))
2162  return conid;
2163  }
2164 
2165  /* Not found in path */
2166  return InvalidOid;
2167 }
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define InvalidOid
Definition: postgres_ext.h:36
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2176 of file namespace.c.

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

Referenced by getObjectDescription(), and pg_conversion_is_visible().

2177 {
2178  HeapTuple contup;
2179  Form_pg_conversion conform;
2180  Oid connamespace;
2181  bool visible;
2182 
2183  contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
2184  if (!HeapTupleIsValid(contup))
2185  elog(ERROR, "cache lookup failed for conversion %u", conid);
2186  conform = (Form_pg_conversion) GETSTRUCT(contup);
2187 
2189 
2190  /*
2191  * Quick check: if it ain't in the path at all, it ain't visible. Items in
2192  * the system namespace are surely in the path and so we needn't even do
2193  * list_member_oid() for them.
2194  */
2195  connamespace = conform->connamespace;
2196  if (connamespace != PG_CATALOG_NAMESPACE &&
2197  !list_member_oid(activeSearchPath, connamespace))
2198  visible = false;
2199  else
2200  {
2201  /*
2202  * If it is in the path, it might still not be visible; it could be
2203  * hidden by another conversion of the same name earlier in the path.
2204  * So we must do a slow check to see if this conversion would be found
2205  * by ConversionGetConid.
2206  */
2207  char *conname = NameStr(conform->conname);
2208 
2209  visible = (ConversionGetConid(conname) == conid);
2210  }
2211 
2212  ReleaseSysCache(contup);
2213 
2214  return visible;
2215 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
Oid ConversionGetConid(const char *conname)
Definition: namespace.c:2144
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:61
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681

◆ CopyOverrideSearchPath()

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path)

Definition at line 3442 of file namespace.c.

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

Referenced by CopyCachedPlan().

3443 {
3444  OverrideSearchPath *result;
3445 
3446  result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
3447  result->schemas = list_copy(path->schemas);
3448  result->addCatalog = path->addCatalog;
3449  result->addTemp = path->addTemp;
3450  result->generation = path->generation;
3451 
3452  return result;
3453 }
List * list_copy(const List *oldlist)
Definition: list.c:1418
void * palloc(Size size)
Definition: mcxt.c:1062

◆ DeconstructQualifiedName()

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

Definition at line 2854 of file namespace.c.

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

Referenced by AlterStatistics(), 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(), LookupTypeNameExtended(), make_oper_cache_key(), OpClassCacheLookup(), OpernameGetCandidates(), OpernameGetOprid(), OpFamilyCacheLookup(), QualifiedNameGetCreationNamespace(), and ResolveOpClass().

2857 {
2858  char *catalogname;
2859  char *schemaname = NULL;
2860  char *objname = NULL;
2861 
2862  switch (list_length(names))
2863  {
2864  case 1:
2865  objname = strVal(linitial(names));
2866  break;
2867  case 2:
2868  schemaname = strVal(linitial(names));
2869  objname = strVal(lsecond(names));
2870  break;
2871  case 3:
2872  catalogname = strVal(linitial(names));
2873  schemaname = strVal(lsecond(names));
2874  objname = strVal(lthird(names));
2875 
2876  /*
2877  * We check the catalog name and then ignore it.
2878  */
2879  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
2880  ereport(ERROR,
2881  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2882  errmsg("cross-database references are not implemented: %s",
2883  NameListToString(names))));
2884  break;
2885  default:
2886  ereport(ERROR,
2887  (errcode(ERRCODE_SYNTAX_ERROR),
2888  errmsg("improper qualified name (too many dotted names): %s",
2889  NameListToString(names))));
2890  break;
2891  }
2892 
2893  *nspname_p = schemaname;
2894  *objname_p = objname;
2895 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:698
#define lsecond(l)
Definition: pg_list.h:179
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:46
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2113
char * NameListToString(List *names)
Definition: namespace.c:3147
Oid MyDatabaseId
Definition: globals.c:88
#define ereport(elevel,...)
Definition: elog.h:157
static int list_length(const List *l)
Definition: pg_list.h:149
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lthird(l)
Definition: pg_list.h:184

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4428 of file namespace.c.

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

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

4429 {
4430  List *result;
4431 
4433 
4434  /*
4435  * If the temp namespace should be first, force it to exist. This is so
4436  * that callers can trust the result to reflect the actual default
4437  * creation namespace. It's a bit bogus to do this here, since
4438  * current_schema() is supposedly a stable function without side-effects,
4439  * but the alternatives seem worse.
4440  */
4442  {
4445  }
4446 
4447  result = list_copy(activeSearchPath);
4448  if (!includeImplicit)
4449  {
4450  while (result && linitial_oid(result) != activeCreationNamespace)
4451  result = list_delete_first(result);
4452  }
4453 
4454  return result;
4455 }
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3960
List * list_copy(const List *oldlist)
Definition: list.c:1418
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static Oid activeCreationNamespace
Definition: namespace.c:141
static bool activeTempCreationPending
Definition: namespace.c:144
#define linitial_oid(l)
Definition: pg_list.h:176
static List * activeSearchPath
Definition: namespace.c:138
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:875

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4468 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

4469 {
4470  int count = 0;
4471  ListCell *l;
4472 
4474 
4475  foreach(l, activeSearchPath)
4476  {
4477  Oid namespaceId = lfirst_oid(l);
4478 
4479  if (namespaceId == myTempNamespace)
4480  continue; /* do not include temp namespace */
4481 
4482  if (count < sarray_len)
4483  sarray[count] = namespaceId;
4484  count++;
4485  }
4486 
4487  return count;
4488 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3755 of file namespace.c.

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

Referenced by BeginCopyFrom(), InitializeClientEncoding(), pg_do_encoding_conversion(), PrepareClientEncoding(), and test_enc_conversion().

3756 {
3757  Oid proc;
3758  ListCell *l;
3759 
3761 
3762  foreach(l, activeSearchPath)
3763  {
3764  Oid namespaceId = lfirst_oid(l);
3765 
3766  if (namespaceId == myTempNamespace)
3767  continue; /* do not look in temp namespace */
3768 
3769  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
3770  if (OidIsValid(proc))
3771  return proc;
3772  }
3773 
3774  /* Not found in path */
3775  return InvalidOid;
3776 }
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ FuncnameGetCandidates()

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

Definition at line 950 of file namespace.c.

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

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

953 {
954  FuncCandidateList resultList = NULL;
955  bool any_special = false;
956  char *schemaname;
957  char *funcname;
958  Oid namespaceId;
959  CatCList *catlist;
960  int i;
961 
962  /* check for caller error */
963  Assert(nargs >= 0 || !(expand_variadic | expand_defaults));
964 
965  /* deconstruct the name list */
966  DeconstructQualifiedName(names, &schemaname, &funcname);
967 
968  if (schemaname)
969  {
970  /* use exact schema given */
971  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
972  if (!OidIsValid(namespaceId))
973  return NULL;
974  }
975  else
976  {
977  /* flag to indicate we need namespace search */
978  namespaceId = InvalidOid;
980  }
981 
982  /* Search syscache by name only */
984 
985  for (i = 0; i < catlist->n_members; i++)
986  {
987  HeapTuple proctup = &catlist->members[i]->tuple;
988  Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
989  Oid *proargtypes = procform->proargtypes.values;
990  int pronargs = procform->pronargs;
991  int effective_nargs;
992  int pathpos = 0;
993  bool variadic;
994  bool use_defaults;
995  Oid va_elem_type;
996  int *argnumbers = NULL;
997  FuncCandidateList newResult;
998 
999  if (OidIsValid(namespaceId))
1000  {
1001  /* Consider only procs in specified namespace */
1002  if (procform->pronamespace != namespaceId)
1003  continue;
1004  }
1005  else
1006  {
1007  /*
1008  * Consider only procs that are in the search path and are not in
1009  * the temp namespace.
1010  */
1011  ListCell *nsp;
1012 
1013  foreach(nsp, activeSearchPath)
1014  {
1015  if (procform->pronamespace == lfirst_oid(nsp) &&
1016  procform->pronamespace != myTempNamespace)
1017  break;
1018  pathpos++;
1019  }
1020  if (nsp == NULL)
1021  continue; /* proc is not in search path */
1022  }
1023 
1024  /*
1025  * If we are asked to match to OUT arguments, then use the
1026  * proallargtypes array (which includes those); otherwise use
1027  * proargtypes (which doesn't). Of course, if proallargtypes is null,
1028  * we always use proargtypes.
1029  */
1030  if (include_out_arguments)
1031  {
1032  Datum proallargtypes;
1033  bool isNull;
1034 
1035  proallargtypes = SysCacheGetAttr(PROCNAMEARGSNSP, proctup,
1036  Anum_pg_proc_proallargtypes,
1037  &isNull);
1038  if (!isNull)
1039  {
1040  ArrayType *arr = DatumGetArrayTypeP(proallargtypes);
1041 
1042  pronargs = ARR_DIMS(arr)[0];
1043  if (ARR_NDIM(arr) != 1 ||
1044  pronargs < 0 ||
1045  ARR_HASNULL(arr) ||
1046  ARR_ELEMTYPE(arr) != OIDOID)
1047  elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
1048  Assert(pronargs >= procform->pronargs);
1049  proargtypes = (Oid *) ARR_DATA_PTR(arr);
1050  }
1051  }
1052 
1053  if (argnames != NIL)
1054  {
1055  /*
1056  * Call uses named or mixed notation
1057  *
1058  * Named or mixed notation can match a variadic function only if
1059  * expand_variadic is off; otherwise there is no way to match the
1060  * presumed-nameless parameters expanded from the variadic array.
1061  */
1062  if (OidIsValid(procform->provariadic) && expand_variadic)
1063  continue;
1064  va_elem_type = InvalidOid;
1065  variadic = false;
1066 
1067  /*
1068  * Check argument count.
1069  */
1070  Assert(nargs >= 0); /* -1 not supported with argnames */
1071 
1072  if (pronargs > nargs && expand_defaults)
1073  {
1074  /* Ignore if not enough default expressions */
1075  if (nargs + procform->pronargdefaults < pronargs)
1076  continue;
1077  use_defaults = true;
1078  }
1079  else
1080  use_defaults = false;
1081 
1082  /* Ignore if it doesn't match requested argument count */
1083  if (pronargs != nargs && !use_defaults)
1084  continue;
1085 
1086  /* Check for argument name match, generate positional mapping */
1087  if (!MatchNamedCall(proctup, nargs, argnames,
1088  include_out_arguments, pronargs,
1089  &argnumbers))
1090  continue;
1091 
1092  /* Named argument matching is always "special" */
1093  any_special = true;
1094  }
1095  else
1096  {
1097  /*
1098  * Call uses positional notation
1099  *
1100  * Check if function is variadic, and get variadic element type if
1101  * so. If expand_variadic is false, we should just ignore
1102  * variadic-ness.
1103  */
1104  if (pronargs <= nargs && expand_variadic)
1105  {
1106  va_elem_type = procform->provariadic;
1107  variadic = OidIsValid(va_elem_type);
1108  any_special |= variadic;
1109  }
1110  else
1111  {
1112  va_elem_type = InvalidOid;
1113  variadic = false;
1114  }
1115 
1116  /*
1117  * Check if function can match by using parameter defaults.
1118  */
1119  if (pronargs > nargs && expand_defaults)
1120  {
1121  /* Ignore if not enough default expressions */
1122  if (nargs + procform->pronargdefaults < pronargs)
1123  continue;
1124  use_defaults = true;
1125  any_special = true;
1126  }
1127  else
1128  use_defaults = false;
1129 
1130  /* Ignore if it doesn't match requested argument count */
1131  if (nargs >= 0 && pronargs != nargs && !variadic && !use_defaults)
1132  continue;
1133  }
1134 
1135  /*
1136  * We must compute the effective argument list so that we can easily
1137  * compare it to earlier results. We waste a palloc cycle if it gets
1138  * masked by an earlier result, but really that's a pretty infrequent
1139  * case so it's not worth worrying about.
1140  */
1141  effective_nargs = Max(pronargs, nargs);
1142  newResult = (FuncCandidateList)
1144  effective_nargs * sizeof(Oid));
1145  newResult->pathpos = pathpos;
1146  newResult->oid = procform->oid;
1147  newResult->nominalnargs = pronargs;
1148  newResult->nargs = effective_nargs;
1149  newResult->argnumbers = argnumbers;
1150  if (argnumbers)
1151  {
1152  /* Re-order the argument types into call's logical order */
1153  int i;
1154 
1155  for (i = 0; i < pronargs; i++)
1156  newResult->args[i] = proargtypes[argnumbers[i]];
1157  }
1158  else
1159  {
1160  /* Simple positional case, just copy proargtypes as-is */
1161  memcpy(newResult->args, proargtypes, pronargs * sizeof(Oid));
1162  }
1163  if (variadic)
1164  {
1165  int i;
1166 
1167  newResult->nvargs = effective_nargs - pronargs + 1;
1168  /* Expand variadic argument into N copies of element type */
1169  for (i = pronargs - 1; i < effective_nargs; i++)
1170  newResult->args[i] = va_elem_type;
1171  }
1172  else
1173  newResult->nvargs = 0;
1174  newResult->ndargs = use_defaults ? pronargs - nargs : 0;
1175 
1176  /*
1177  * Does it have the same arguments as something we already accepted?
1178  * If so, decide what to do to avoid returning duplicate argument
1179  * lists. We can skip this check for the single-namespace case if no
1180  * special (named, variadic or defaults) match has been made, since
1181  * then the unique index on pg_proc guarantees all the matches have
1182  * different argument lists.
1183  */
1184  if (resultList != NULL &&
1185  (any_special || !OidIsValid(namespaceId)))
1186  {
1187  /*
1188  * If we have an ordered list from SearchSysCacheList (the normal
1189  * case), then any conflicting proc must immediately adjoin this
1190  * one in the list, so we only need to look at the newest result
1191  * item. If we have an unordered list, we have to scan the whole
1192  * result list. Also, if either the current candidate or any
1193  * previous candidate is a special match, we can't assume that
1194  * conflicts are adjacent.
1195  *
1196  * We ignore defaulted arguments in deciding what is a match.
1197  */
1198  FuncCandidateList prevResult;
1199 
1200  if (catlist->ordered && !any_special)
1201  {
1202  /* ndargs must be 0 if !any_special */
1203  if (effective_nargs == resultList->nargs &&
1204  memcmp(newResult->args,
1205  resultList->args,
1206  effective_nargs * sizeof(Oid)) == 0)
1207  prevResult = resultList;
1208  else
1209  prevResult = NULL;
1210  }
1211  else
1212  {
1213  int cmp_nargs = newResult->nargs - newResult->ndargs;
1214 
1215  for (prevResult = resultList;
1216  prevResult;
1217  prevResult = prevResult->next)
1218  {
1219  if (cmp_nargs == prevResult->nargs - prevResult->ndargs &&
1220  memcmp(newResult->args,
1221  prevResult->args,
1222  cmp_nargs * sizeof(Oid)) == 0)
1223  break;
1224  }
1225  }
1226 
1227  if (prevResult)
1228  {
1229  /*
1230  * We have a match with a previous result. Decide which one
1231  * to keep, or mark it ambiguous if we can't decide. The
1232  * logic here is preference > 0 means prefer the old result,
1233  * preference < 0 means prefer the new, preference = 0 means
1234  * ambiguous.
1235  */
1236  int preference;
1237 
1238  if (pathpos != prevResult->pathpos)
1239  {
1240  /*
1241  * Prefer the one that's earlier in the search path.
1242  */
1243  preference = pathpos - prevResult->pathpos;
1244  }
1245  else if (variadic && prevResult->nvargs == 0)
1246  {
1247  /*
1248  * With variadic functions we could have, for example,
1249  * both foo(numeric) and foo(variadic numeric[]) in the
1250  * same namespace; if so we prefer the non-variadic match
1251  * on efficiency grounds.
1252  */
1253  preference = 1;
1254  }
1255  else if (!variadic && prevResult->nvargs > 0)
1256  {
1257  preference = -1;
1258  }
1259  else
1260  {
1261  /*----------
1262  * We can't decide. This can happen with, for example,
1263  * both foo(numeric, variadic numeric[]) and
1264  * foo(variadic numeric[]) in the same namespace, or
1265  * both foo(int) and foo (int, int default something)
1266  * in the same namespace, or both foo(a int, b text)
1267  * and foo(b text, a int) in the same namespace.
1268  *----------
1269  */
1270  preference = 0;
1271  }
1272 
1273  if (preference > 0)
1274  {
1275  /* keep previous result */
1276  pfree(newResult);
1277  continue;
1278  }
1279  else if (preference < 0)
1280  {
1281  /* remove previous result from the list */
1282  if (prevResult == resultList)
1283  resultList = prevResult->next;
1284  else
1285  {
1286  FuncCandidateList prevPrevResult;
1287 
1288  for (prevPrevResult = resultList;
1289  prevPrevResult;
1290  prevPrevResult = prevPrevResult->next)
1291  {
1292  if (prevResult == prevPrevResult->next)
1293  {
1294  prevPrevResult->next = prevResult->next;
1295  break;
1296  }
1297  }
1298  Assert(prevPrevResult); /* assert we found it */
1299  }
1300  pfree(prevResult);
1301  /* fall through to add newResult to list */
1302  }
1303  else
1304  {
1305  /* mark old result as ambiguous, discard new */
1306  prevResult->oid = InvalidOid;
1307  pfree(newResult);
1308  continue;
1309  }
1310  }
1311  }
1312 
1313  /*
1314  * Okay to add it to result list
1315  */
1316  newResult->next = resultList;
1317  resultList = newResult;
1318  }
1319 
1320  ReleaseSysCacheList(catlist);
1321 
1322  return resultList;
1323 }
#define NIL
Definition: pg_list.h:65
int n_members
Definition: catcache.h:176
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
static Oid myTempNamespace
Definition: namespace.c:188
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
int16 pronargs
Definition: pg_proc.h:81
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:38
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ERROR
Definition: elog.h:46
struct _FuncCandidateList * FuncCandidateList
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
#define CStringGetDatum(X)
Definition: postgres.h:622
#define ARR_HASNULL(a)
Definition: array.h:284
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:211
struct _FuncCandidateList * next
Definition: namespace.h:30
static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, bool include_out_arguments, int pronargs, int **argnumbers)
Definition: namespace.c:1347
#define ReleaseSysCacheList(x)
Definition: syscache.h:218
uintptr_t Datum
Definition: postgres.h:411
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1388
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
#define InvalidOid
Definition: postgres_ext.h:36
#define Max(x, y)
Definition: c.h:980
#define Assert(condition)
Definition: c.h:804
#define ARR_NDIM(a)
Definition: array.h:283
static List * activeSearchPath
Definition: namespace.c:138
bool ordered
Definition: catcache.h:174
void * palloc(Size size)
Definition: mcxt.c:1062
#define elog(elevel,...)
Definition: elog.h:232
int i
HeapTupleData tuple
Definition: catcache.h:121
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define offsetof(type, field)
Definition: c.h:727
#define lfirst_oid(lc)
Definition: pg_list.h:171
#define DatumGetArrayTypeP(X)
Definition: array.h:254

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1458 of file namespace.c.

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

Referenced by format_procedure_extended(), and pg_function_is_visible().

1459 {
1460  HeapTuple proctup;
1461  Form_pg_proc procform;
1462  Oid pronamespace;
1463  bool visible;
1464 
1465  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1466  if (!HeapTupleIsValid(proctup))
1467  elog(ERROR, "cache lookup failed for function %u", funcid);
1468  procform = (Form_pg_proc) GETSTRUCT(proctup);
1469 
1471 
1472  /*
1473  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1474  * the system namespace are surely in the path and so we needn't even do
1475  * list_member_oid() for them.
1476  */
1477  pronamespace = procform->pronamespace;
1478  if (pronamespace != PG_CATALOG_NAMESPACE &&
1479  !list_member_oid(activeSearchPath, pronamespace))
1480  visible = false;
1481  else
1482  {
1483  /*
1484  * If it is in the path, it might still not be visible; it could be
1485  * hidden by another proc of the same name and arguments earlier in
1486  * the path. So we must do a slow check to see if this is the same
1487  * proc that would be found by FuncnameGetCandidates.
1488  */
1489  char *proname = NameStr(procform->proname);
1490  int nargs = procform->pronargs;
1491  FuncCandidateList clist;
1492 
1493  visible = false;
1494 
1495  clist = FuncnameGetCandidates(list_make1(makeString(proname)),
1496  nargs, NIL, false, false, false, false);
1497 
1498  for (; clist; clist = clist->next)
1499  {
1500  if (memcmp(clist->args, procform->proargtypes.values,
1501  nargs * sizeof(Oid)) == 0)
1502  {
1503  /* Found the expected entry; is it the right proc? */
1504  visible = (clist->oid == funcid);
1505  break;
1506  }
1507  }
1508  }
1509 
1510  ReleaseSysCache(proctup);
1511 
1512  return visible;
1513 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:65
NameData proname
Definition: pg_proc.h:35
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define list_make1(x1)
Definition: pg_list.h:206
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:38
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
struct _FuncCandidateList * next
Definition: namespace.h:30
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
Definition: namespace.c:950
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681

◆ get_collation_oid()

Oid get_collation_oid ( List name,
bool  missing_ok 
)

Definition at line 3646 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(), LookupCollation(), regcollationin(), and to_regcollation().

3647 {
3648  char *schemaname;
3649  char *collation_name;
3650  int32 dbencoding = GetDatabaseEncoding();
3651  Oid namespaceId;
3652  Oid colloid;
3653  ListCell *l;
3654 
3655  /* deconstruct the name list */
3656  DeconstructQualifiedName(name, &schemaname, &collation_name);
3657 
3658  if (schemaname)
3659  {
3660  /* use exact schema given */
3661  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3662  if (missing_ok && !OidIsValid(namespaceId))
3663  return InvalidOid;
3664 
3665  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3666  if (OidIsValid(colloid))
3667  return colloid;
3668  }
3669  else
3670  {
3671  /* search for it in search path */
3673 
3674  foreach(l, activeSearchPath)
3675  {
3676  namespaceId = lfirst_oid(l);
3677 
3678  if (namespaceId == myTempNamespace)
3679  continue; /* do not look in temp namespace */
3680 
3681  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3682  if (OidIsValid(colloid))
3683  return colloid;
3684  }
3685  }
3686 
3687  /* Not found in path */
3688  if (!missing_ok)
3689  ereport(ERROR,
3690  (errcode(ERRCODE_UNDEFINED_OBJECT),
3691  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
3693  return InvalidOid;
3694 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
signed int int32
Definition: c.h:429
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:2008
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
int GetDatabaseEncoding(void)
Definition: mbutils.c:1210
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1216
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_conversion_oid()

Oid get_conversion_oid ( List name,
bool  missing_ok 
)

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

3701 {
3702  char *schemaname;
3703  char *conversion_name;
3704  Oid namespaceId;
3705  Oid conoid = InvalidOid;
3706  ListCell *l;
3707 
3708  /* deconstruct the name list */
3709  DeconstructQualifiedName(name, &schemaname, &conversion_name);
3710 
3711  if (schemaname)
3712  {
3713  /* use exact schema given */
3714  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3715  if (missing_ok && !OidIsValid(namespaceId))
3716  conoid = InvalidOid;
3717  else
3718  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3719  PointerGetDatum(conversion_name),
3720  ObjectIdGetDatum(namespaceId));
3721  }
3722  else
3723  {
3724  /* search for it in search path */
3726 
3727  foreach(l, activeSearchPath)
3728  {
3729  namespaceId = lfirst_oid(l);
3730 
3731  if (namespaceId == myTempNamespace)
3732  continue; /* do not look in temp namespace */
3733 
3734  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
3735  PointerGetDatum(conversion_name),
3736  ObjectIdGetDatum(namespaceId));
3737  if (OidIsValid(conoid))
3738  return conoid;
3739  }
3740  }
3741 
3742  /* Not found in path */
3743  if (!OidIsValid(conoid) && !missing_ok)
3744  ereport(ERROR,
3745  (errcode(ERRCODE_UNDEFINED_OBJECT),
3746  errmsg("conversion \"%s\" does not exist",
3747  NameListToString(name))));
3748  return conoid;
3749 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

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

3089 {
3090  Oid oid;
3091 
3092  oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid,
3093  CStringGetDatum(nspname));
3094  if (!OidIsValid(oid) && !missing_ok)
3095  ereport(ERROR,
3096  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3097  errmsg("schema \"%s\" does not exist", nspname)));
3098 
3099  return oid;
3100 }
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:193
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
#define CStringGetDatum(X)
Definition: postgres.h:622
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2223 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 AlterStatistics(), and get_object_address().

2224 {
2225  char *schemaname;
2226  char *stats_name;
2227  Oid namespaceId;
2228  Oid stats_oid = InvalidOid;
2229  ListCell *l;
2230 
2231  /* deconstruct the name list */
2232  DeconstructQualifiedName(names, &schemaname, &stats_name);
2233 
2234  if (schemaname)
2235  {
2236  /* use exact schema given */
2237  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2238  if (missing_ok && !OidIsValid(namespaceId))
2239  stats_oid = InvalidOid;
2240  else
2241  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2242  PointerGetDatum(stats_name),
2243  ObjectIdGetDatum(namespaceId));
2244  }
2245  else
2246  {
2247  /* search for it in search path */
2249 
2250  foreach(l, activeSearchPath)
2251  {
2252  namespaceId = lfirst_oid(l);
2253 
2254  if (namespaceId == myTempNamespace)
2255  continue; /* do not look in temp namespace */
2256  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2257  PointerGetDatum(stats_name),
2258  ObjectIdGetDatum(namespaceId));
2259  if (OidIsValid(stats_oid))
2260  break;
2261  }
2262  }
2263 
2264  if (!OidIsValid(stats_oid) && !missing_ok)
2265  ereport(ERROR,
2266  (errcode(ERRCODE_UNDEFINED_OBJECT),
2267  errmsg("statistics object \"%s\" does not exist",
2268  NameListToString(names))));
2269 
2270  return stats_oid;
2271 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

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

2725 {
2726  char *schemaname;
2727  char *config_name;
2728  Oid namespaceId;
2729  Oid cfgoid = InvalidOid;
2730  ListCell *l;
2731 
2732  /* deconstruct the name list */
2733  DeconstructQualifiedName(names, &schemaname, &config_name);
2734 
2735  if (schemaname)
2736  {
2737  /* use exact schema given */
2738  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2739  if (missing_ok && !OidIsValid(namespaceId))
2740  cfgoid = InvalidOid;
2741  else
2742  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2743  PointerGetDatum(config_name),
2744  ObjectIdGetDatum(namespaceId));
2745  }
2746  else
2747  {
2748  /* search for it in search path */
2750 
2751  foreach(l, activeSearchPath)
2752  {
2753  namespaceId = lfirst_oid(l);
2754 
2755  if (namespaceId == myTempNamespace)
2756  continue; /* do not look in temp namespace */
2757 
2758  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
2759  PointerGetDatum(config_name),
2760  ObjectIdGetDatum(namespaceId));
2761  if (OidIsValid(cfgoid))
2762  break;
2763  }
2764  }
2765 
2766  if (!OidIsValid(cfgoid) && !missing_ok)
2767  ereport(ERROR,
2768  (errcode(ERRCODE_UNDEFINED_OBJECT),
2769  errmsg("text search configuration \"%s\" does not exist",
2770  NameListToString(names))));
2771 
2772  return cfgoid;
2773 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2471 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(), and thesaurus_init().

2472 {
2473  char *schemaname;
2474  char *dict_name;
2475  Oid namespaceId;
2476  Oid dictoid = InvalidOid;
2477  ListCell *l;
2478 
2479  /* deconstruct the name list */
2480  DeconstructQualifiedName(names, &schemaname, &dict_name);
2481 
2482  if (schemaname)
2483  {
2484  /* use exact schema given */
2485  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2486  if (missing_ok && !OidIsValid(namespaceId))
2487  dictoid = InvalidOid;
2488  else
2489  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2490  PointerGetDatum(dict_name),
2491  ObjectIdGetDatum(namespaceId));
2492  }
2493  else
2494  {
2495  /* search for it in search path */
2497 
2498  foreach(l, activeSearchPath)
2499  {
2500  namespaceId = lfirst_oid(l);
2501 
2502  if (namespaceId == myTempNamespace)
2503  continue; /* do not look in temp namespace */
2504 
2505  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2506  PointerGetDatum(dict_name),
2507  ObjectIdGetDatum(namespaceId));
2508  if (OidIsValid(dictoid))
2509  break;
2510  }
2511  }
2512 
2513  if (!OidIsValid(dictoid) && !missing_ok)
2514  ereport(ERROR,
2515  (errcode(ERRCODE_UNDEFINED_OBJECT),
2516  errmsg("text search dictionary \"%s\" does not exist",
2517  NameListToString(names))));
2518 
2519  return dictoid;
2520 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

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

2346 {
2347  char *schemaname;
2348  char *parser_name;
2349  Oid namespaceId;
2350  Oid prsoid = InvalidOid;
2351  ListCell *l;
2352 
2353  /* deconstruct the name list */
2354  DeconstructQualifiedName(names, &schemaname, &parser_name);
2355 
2356  if (schemaname)
2357  {
2358  /* use exact schema given */
2359  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2360  if (missing_ok && !OidIsValid(namespaceId))
2361  prsoid = InvalidOid;
2362  else
2363  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2364  PointerGetDatum(parser_name),
2365  ObjectIdGetDatum(namespaceId));
2366  }
2367  else
2368  {
2369  /* search for it in search path */
2371 
2372  foreach(l, activeSearchPath)
2373  {
2374  namespaceId = lfirst_oid(l);
2375 
2376  if (namespaceId == myTempNamespace)
2377  continue; /* do not look in temp namespace */
2378 
2379  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2380  PointerGetDatum(parser_name),
2381  ObjectIdGetDatum(namespaceId));
2382  if (OidIsValid(prsoid))
2383  break;
2384  }
2385  }
2386 
2387  if (!OidIsValid(prsoid) && !missing_ok)
2388  ereport(ERROR,
2389  (errcode(ERRCODE_UNDEFINED_OBJECT),
2390  errmsg("text search parser \"%s\" does not exist",
2391  NameListToString(names))));
2392 
2393  return prsoid;
2394 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

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

2599 {
2600  char *schemaname;
2601  char *template_name;
2602  Oid namespaceId;
2603  Oid tmploid = InvalidOid;
2604  ListCell *l;
2605 
2606  /* deconstruct the name list */
2607  DeconstructQualifiedName(names, &schemaname, &template_name);
2608 
2609  if (schemaname)
2610  {
2611  /* use exact schema given */
2612  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2613  if (missing_ok && !OidIsValid(namespaceId))
2614  tmploid = InvalidOid;
2615  else
2616  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2617  PointerGetDatum(template_name),
2618  ObjectIdGetDatum(namespaceId));
2619  }
2620  else
2621  {
2622  /* search for it in search path */
2624 
2625  foreach(l, activeSearchPath)
2626  {
2627  namespaceId = lfirst_oid(l);
2628 
2629  if (namespaceId == myTempNamespace)
2630  continue; /* do not look in temp namespace */
2631 
2632  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
2633  PointerGetDatum(template_name),
2634  ObjectIdGetDatum(namespaceId));
2635  if (OidIsValid(tmploid))
2636  break;
2637  }
2638  }
2639 
2640  if (!OidIsValid(tmploid) && !missing_ok)
2641  ereport(ERROR,
2642  (errcode(ERRCODE_UNDEFINED_OBJECT),
2643  errmsg("text search template \"%s\" does not exist",
2644  NameListToString(names))));
2645 
2646  return tmploid;
2647 }
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:195
static List * activeSearchPath
Definition: namespace.c:138
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ GetOverrideSearchPath()

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context)

Definition at line 3405 of file namespace.c.

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

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

3406 {
3407  OverrideSearchPath *result;
3408  List *schemas;
3409  MemoryContext oldcxt;
3410 
3412 
3413  oldcxt = MemoryContextSwitchTo(context);
3414 
3415  result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
3416  schemas = list_copy(activeSearchPath);
3417  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3418  {
3419  if (linitial_oid(schemas) == myTempNamespace)
3420  result->addTemp = true;
3421  else
3422  {
3423  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3424  result->addCatalog = true;
3425  }
3426  schemas = list_delete_first(schemas);
3427  }
3428  result->schemas = schemas;
3429  result->generation = activePathGeneration;
3430 
3431  MemoryContextSwitchTo(oldcxt);
3432 
3433  return result;
3434 }
static Oid myTempNamespace
Definition: namespace.c:188
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
List * list_copy(const List *oldlist)
Definition: list.c:1418
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
void * palloc0(Size size)
Definition: mcxt.c:1093
#define Assert(condition)
Definition: c.h:804
#define linitial_oid(l)
Definition: pg_list.h:176
static List * activeSearchPath
Definition: namespace.c:138
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:875

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3319 of file namespace.c.

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

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

3320 {
3321  int result;
3322  char *nspname;
3323 
3324  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3325  nspname = get_namespace_name(namespaceId);
3326  if (!nspname)
3327  return InvalidBackendId; /* no such namespace? */
3328  if (strncmp(nspname, "pg_temp_", 8) == 0)
3329  result = atoi(nspname + 8);
3330  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3331  result = atoi(nspname + 14);
3332  else
3333  result = InvalidBackendId;
3334  pfree(nspname);
3335  return result;
3336 }
void pfree(void *pointer)
Definition: mcxt.c:1169
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3316
#define InvalidBackendId
Definition: backendid.h:23

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3358 of file namespace.c.

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

3359 {
3360  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3361  *tempNamespaceId = myTempNamespace;
3362  *tempToastNamespaceId = myTempToastNamespace;
3363 }
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3344 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

3345 {
3347  return myTempToastNamespace;
3348 }
static Oid myTempToastNamespace
Definition: namespace.c:190
#define OidIsValid(objectId)
Definition: c.h:710
#define Assert(condition)
Definition: c.h:804

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4369 of file namespace.c.

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

Referenced by InitPostgres().

4370 {
4372  {
4373  /*
4374  * In bootstrap mode, the search path must be 'pg_catalog' so that
4375  * tables are created in the proper namespace; ignore the GUC setting.
4376  */
4377  MemoryContext oldcxt;
4378 
4380  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4381  MemoryContextSwitchTo(oldcxt);
4382  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4383  baseTempCreationPending = false;
4384  baseSearchPathValid = true;
4389  activePathGeneration++; /* pro forma */
4390  }
4391  else
4392  {
4393  /*
4394  * In normal mode, arrange for a callback on any syscache invalidation
4395  * of pg_namespace rows.
4396  */
4399  (Datum) 0);
4400  /* Force search path to be recomputed on next use */
4401  baseSearchPathValid = false;
4402  }
4403 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid GetUserId(void)
Definition: miscinit.c:478
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static Oid namespaceUser
Definition: namespace.c:157
static Oid activeCreationNamespace
Definition: namespace.c:141
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4410
static bool activeTempCreationPending
Definition: namespace.c:144
MemoryContext TopMemoryContext
Definition: mcxt.c:48
static Oid baseCreationNamespace
Definition: namespace.c:153
static List * baseSearchPath
Definition: namespace.c:151
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1435
uintptr_t Datum
Definition: postgres.h:411
#define list_make1_oid(x1)
Definition: pg_list.h:236
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406
static List * activeSearchPath
Definition: namespace.c:138

◆ InitTempTableNamespace()

static void InitTempTableNamespace ( void  )
static

Definition at line 3988 of file namespace.c.

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

Referenced by AccessTempTableNamespace().

3989 {
3990  char namespaceName[NAMEDATALEN];
3991  Oid namespaceId;
3992  Oid toastspaceId;
3993 
3995 
3996  /*
3997  * First, do permission check to see if we are authorized to make temp
3998  * tables. We use a nonstandard error message here since "databasename:
3999  * permission denied" might be a tad cryptic.
4000  *
4001  * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
4002  * that's necessary since current user ID could change during the session.
4003  * But there's no need to make the namespace in the first place until a
4004  * temp table creation request is made by someone with appropriate rights.
4005  */
4008  ereport(ERROR,
4009  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4010  errmsg("permission denied to create temporary tables in database \"%s\"",
4012 
4013  /*
4014  * Do not allow a Hot Standby session to make temp tables. Aside from
4015  * problems with modifying the system catalogs, there is a naming
4016  * conflict: pg_temp_N belongs to the session with BackendId N on the
4017  * primary, not to a hot standby session with the same BackendId. We
4018  * should not be able to get here anyway due to XactReadOnly checks, but
4019  * let's just make real sure. Note that this also backstops various
4020  * operations that allow XactReadOnly transactions to modify temp tables;
4021  * they'd need RecoveryInProgress checks if not for this.
4022  */
4023  if (RecoveryInProgress())
4024  ereport(ERROR,
4025  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
4026  errmsg("cannot create temporary tables during recovery")));
4027 
4028  /* Parallel workers can't create temporary tables, either. */
4029  if (IsParallelWorker())
4030  ereport(ERROR,
4031  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
4032  errmsg("cannot create temporary tables during a parallel operation")));
4033 
4034  snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
4035 
4036  namespaceId = get_namespace_oid(namespaceName, true);
4037  if (!OidIsValid(namespaceId))
4038  {
4039  /*
4040  * First use of this temp namespace in this database; create it. The
4041  * temp namespaces are always owned by the superuser. We leave their
4042  * permissions at default --- i.e., no access except to superuser ---
4043  * to ensure that unprivileged users can't peek at other backends'
4044  * temp tables. This works because the places that access the temp
4045  * namespace for my own backend skip permissions checks on it.
4046  */
4047  namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
4048  true);
4049  /* Advance command counter to make namespace visible */
4051  }
4052  else
4053  {
4054  /*
4055  * If the namespace already exists, clean it out (in case the former
4056  * owner crashed without doing so).
4057  */
4058  RemoveTempRelations(namespaceId);
4059  }
4060 
4061  /*
4062  * If the corresponding toast-table namespace doesn't exist yet, create
4063  * it. (We assume there is no need to clean it out if it does exist, since
4064  * dropping a parent table should make its toast table go away.)
4065  */
4066  snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
4067  MyBackendId);
4068 
4069  toastspaceId = get_namespace_oid(namespaceName, true);
4070  if (!OidIsValid(toastspaceId))
4071  {
4072  toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
4073  true);
4074  /* Advance command counter to make namespace visible */
4076  }
4077 
4078  /*
4079  * Okay, we've prepared the temp namespace ... but it's not committed yet,
4080  * so all our work could be undone by transaction rollback. Set flag for
4081  * AtEOXact_Namespace to know what to do.
4082  */
4083  myTempNamespace = namespaceId;
4084  myTempToastNamespace = toastspaceId;
4085 
4086  /*
4087  * Mark MyProc as owning this namespace which other processes can use to
4088  * decide if a temporary namespace is in use or not. We assume that
4089  * assignment of namespaceId is an atomic operation. Even if it is not,
4090  * the temporary relation which resulted in the creation of this temporary
4091  * namespace is still locked until the current transaction commits, and
4092  * its pg_namespace row is not visible yet. However it does not matter:
4093  * this flag makes the namespace as being in use, so no objects created on
4094  * it would be removed concurrently.
4095  */
4096  MyProc->tempNamespaceId = namespaceId;
4097 
4098  /* It should not be done already. */
4101 
4102  baseSearchPathValid = false; /* need to rebuild list */
4103 }
static bool baseSearchPathValid
Definition: namespace.c:160
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
BackendId MyBackendId
Definition: globals.c:84
#define AssertState(condition)
Definition: c.h:807
Oid GetUserId(void)
Definition: miscinit.c:478
Oid tempNamespaceId
Definition: proc.h:157
PGPROC * MyProc
Definition: proc.c:68
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:8226
#define OidIsValid(objectId)
Definition: c.h:710
#define NAMEDATALEN
#define ERROR
Definition: elog.h:46
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2113
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:192
#define IsParallelWorker()
Definition: parallel.h:61
void CommandCounterIncrement(void)
Definition: xact.c:1021
Oid MyDatabaseId
Definition: globals.c:88
#define ereport(elevel,...)
Definition: elog.h:157
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4706
#define Assert(condition)
Definition: c.h:804
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4262
#define InvalidSubTransactionId
Definition: c.h:593
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define ACL_CREATE_TEMP
Definition: parsenodes.h:93
#define snprintf
Definition: port.h:216
Oid NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
Definition: pg_namespace.c:43

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3240 of file namespace.c.

References get_namespace_name(), and pfree().

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

3241 {
3242  bool result;
3243  char *nspname;
3244 
3245  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3246  nspname = get_namespace_name(namespaceId);
3247  if (!nspname)
3248  return false; /* no such namespace? */
3249  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3250  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3251  pfree(nspname);
3252  return result;
3253 }
void pfree(void *pointer)
Definition: mcxt.c:1169
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3316

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3263 of file namespace.c.

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

3264 {
3265  /* If it's my own temp namespace, say "false" */
3266  if (isTempOrTempToastNamespace(namespaceId))
3267  return false;
3268  /* Else, if it's any temp namespace, say "true" */
3269  return isAnyTempNamespace(namespaceId);
3270 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3226
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3240

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3202 of file namespace.c.

References myTempNamespace, and OidIsValid.

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

3203 {
3204  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3205  return true;
3206  return false;
3207 }
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:710

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3226 of file namespace.c.

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

3227 {
3228  if (OidIsValid(myTempNamespace) &&
3229  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3230  return true;
3231  return false;
3232 }
static Oid myTempToastNamespace
Definition: namespace.c:190
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:710

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3214 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

3215 {
3216  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3217  return true;
3218  return false;
3219 }
static Oid myTempToastNamespace
Definition: namespace.c:190
#define OidIsValid(objectId)
Definition: c.h:710

◆ lookup_collation()

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

Definition at line 2008 of file namespace.c.

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

Referenced by CollationGetCollid(), and get_collation_oid().

2009 {
2010  Oid collid;
2011  HeapTuple colltup;
2012  Form_pg_collation collform;
2013 
2014  /* Check for encoding-specific entry (exact match) */
2015  collid = GetSysCacheOid3(COLLNAMEENCNSP, Anum_pg_collation_oid,
2016  PointerGetDatum(collname),
2018  ObjectIdGetDatum(collnamespace));
2019  if (OidIsValid(collid))
2020  return collid;
2021 
2022  /*
2023  * Check for any-encoding entry. This takes a bit more work: while libc
2024  * collations with collencoding = -1 do work with all encodings, ICU
2025  * collations only work with certain encodings, so we have to check that
2026  * aspect before deciding it's a match.
2027  */
2028  colltup = SearchSysCache3(COLLNAMEENCNSP,
2029  PointerGetDatum(collname),
2030  Int32GetDatum(-1),
2031  ObjectIdGetDatum(collnamespace));
2032  if (!HeapTupleIsValid(colltup))
2033  return InvalidOid;
2034  collform = (Form_pg_collation) GETSTRUCT(colltup);
2035  if (collform->collprovider == COLLPROVIDER_ICU)
2036  {
2038  collid = collform->oid;
2039  else
2040  collid = InvalidOid;
2041  }
2042  else
2043  {
2044  collid = collform->oid;
2045  }
2046  ReleaseSysCache(colltup);
2047  return collid;
2048 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
#define PointerGetDatum(X)
Definition: postgres.h:600
bool is_encoding_supported_by_icu(int encoding)
Definition: encnames.c:459
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:197
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Definition: syscache.c:1149
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int32 encoding
Definition: pg_database.h:41
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:56
#define Int32GetDatum(X)
Definition: postgres.h:523

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 2981 of file namespace.c.

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

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

2982 {
2983  Oid namespaceId;
2984  AclResult aclresult;
2985 
2986  /* check for pg_temp alias */
2987  if (strcmp(nspname, "pg_temp") == 0)
2988  {
2989  /* Initialize temp namespace */
2990  AccessTempTableNamespace(false);
2991  return myTempNamespace;
2992  }
2993 
2994  namespaceId = get_namespace_oid(nspname, false);
2995 
2996  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
2997  if (aclresult != ACLCHECK_OK)
2998  aclcheck_error(aclresult, OBJECT_SCHEMA,
2999  nspname);
3000 
3001  return namespaceId;
3002 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3960
Oid GetUserId(void)
Definition: miscinit.c:478
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4756
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3308
#define ACL_CREATE
Definition: parsenodes.h:92
AclResult
Definition: acl.h:177

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2938 of file namespace.c.

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

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

2939 {
2940  Oid namespaceId;
2941  AclResult aclresult;
2942 
2943  /* check for pg_temp alias */
2944  if (strcmp(nspname, "pg_temp") == 0)
2945  {
2947  return myTempNamespace;
2948 
2949  /*
2950  * Since this is used only for looking up existing objects, there is
2951  * no point in trying to initialize the temp namespace here; and doing
2952  * so might create problems for some callers --- just fall through.
2953  */
2954  }
2955 
2956  namespaceId = get_namespace_oid(nspname, missing_ok);
2957  if (missing_ok && !OidIsValid(namespaceId))
2958  return InvalidOid;
2959 
2960  aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
2961  if (aclresult != ACLCHECK_OK)
2962  aclcheck_error(aclresult, OBJECT_SCHEMA,
2963  nspname);
2964  /* Schema search hook for this lookup */
2965  InvokeNamespaceSearchHook(namespaceId, true);
2966 
2967  return namespaceId;
2968 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
Oid GetUserId(void)
Definition: miscinit.c:478
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4756
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:186
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3308
#define ACL_USAGE
Definition: parsenodes.h:90
AclResult
Definition: acl.h:177
#define InvalidOid
Definition: postgres_ext.h:36

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 2908 of file namespace.c.

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

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

2909 {
2910  /* check for pg_temp alias */
2911  if (strcmp(nspname, "pg_temp") == 0)
2912  {
2914  {
2916  return myTempNamespace;
2917  }
2918 
2919  /*
2920  * Since this is used only for looking up existing objects, there is
2921  * no point in trying to initialize the temp namespace here; and doing
2922  * so might create problems for some callers. Just report "not found".
2923  */
2924  return InvalidOid;
2925  }
2926 
2927  return get_namespace_oid(nspname, true);
2928 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
static Oid myTempNamespace
Definition: namespace.c:188
#define OidIsValid(objectId)
Definition: c.h:710
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:186
#define InvalidOid
Definition: postgres_ext.h:36

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( List names)

Definition at line 3107 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_internal(), bt_page_stats_internal(), 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().

3108 {
3109  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3110 
3111  switch (list_length(names))
3112  {
3113  case 1:
3114  rel->relname = strVal(linitial(names));
3115  break;
3116  case 2:
3117  rel->schemaname = strVal(linitial(names));
3118  rel->relname = strVal(lsecond(names));
3119  break;
3120  case 3:
3121  rel->catalogname = strVal(linitial(names));
3122  rel->schemaname = strVal(lsecond(names));
3123  rel->relname = strVal(lthird(names));
3124  break;
3125  default:
3126  ereport(ERROR,
3127  (errcode(ERRCODE_SYNTAX_ERROR),
3128  errmsg("improper relation name (too many dotted names): %s",
3129  NameListToString(names))));
3130  break;
3131  }
3132 
3133  return rel;
3134 }
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:698
#define lsecond(l)
Definition: pg_list.h:179
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:46
char * NameListToString(List *names)
Definition: namespace.c:3147
#define ereport(elevel,...)
Definition: elog.h:157
static int list_length(const List *l)
Definition: pg_list.h:149
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define lthird(l)
Definition: pg_list.h:184
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:422
char * catalogname
Definition: primnodes.h:66

◆ MatchNamedCall()

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

Definition at line 1347 of file namespace.c.

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

Referenced by FuncnameGetCandidates().

1350 {
1351  Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
1352  int numposargs = nargs - list_length(argnames);
1353  int pronallargs;
1354  Oid *p_argtypes;
1355  char **p_argnames;
1356  char *p_argmodes;
1357  bool arggiven[FUNC_MAX_ARGS];
1358  bool isnull;
1359  int ap; /* call args position */
1360  int pp; /* proargs position */
1361  ListCell *lc;
1362 
1363  Assert(argnames != NIL);
1364  Assert(numposargs >= 0);
1365  Assert(nargs <= pronargs);
1366 
1367  /* Ignore this function if its proargnames is null */
1368  (void) SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proargnames,
1369  &isnull);
1370  if (isnull)
1371  return false;
1372 
1373  /* OK, let's extract the argument names and types */
1374  pronallargs = get_func_arg_info(proctup,
1375  &p_argtypes, &p_argnames, &p_argmodes);
1376  Assert(p_argnames != NULL);
1377 
1378  Assert(include_out_arguments ? (pronargs == pronallargs) : (pronargs <= pronallargs));
1379 
1380  /* initialize state for matching */
1381  *argnumbers = (int *) palloc(pronargs * sizeof(int));
1382  memset(arggiven, false, pronargs * sizeof(bool));
1383 
1384  /* there are numposargs positional args before the named args */
1385  for (ap = 0; ap < numposargs; ap++)
1386  {
1387  (*argnumbers)[ap] = ap;
1388  arggiven[ap] = true;
1389  }
1390 
1391  /* now examine the named args */
1392  foreach(lc, argnames)
1393  {
1394  char *argname = (char *) lfirst(lc);
1395  bool found;
1396  int i;
1397 
1398  pp = 0;
1399  found = false;
1400  for (i = 0; i < pronallargs; i++)
1401  {
1402  /* consider only input params, except with include_out_arguments */
1403  if (!include_out_arguments &&
1404  p_argmodes &&
1405  (p_argmodes[i] != FUNC_PARAM_IN &&
1406  p_argmodes[i] != FUNC_PARAM_INOUT &&
1407  p_argmodes[i] != FUNC_PARAM_VARIADIC))
1408  continue;
1409  if (p_argnames[i] && strcmp(p_argnames[i], argname) == 0)
1410  {
1411  /* fail if argname matches a positional argument */
1412  if (arggiven[pp])
1413  return false;
1414  arggiven[pp] = true;
1415  (*argnumbers)[ap] = pp;
1416  found = true;
1417  break;
1418  }
1419  /* increase pp only for considered parameters */
1420  pp++;
1421  }
1422  /* if name isn't in proargnames, fail */
1423  if (!found)
1424  return false;
1425  ap++;
1426  }
1427 
1428  Assert(ap == nargs); /* processed all actual parameters */
1429 
1430  /* Check for default arguments */
1431  if (nargs < pronargs)
1432  {
1433  int first_arg_with_default = pronargs - procform->pronargdefaults;
1434 
1435  for (pp = numposargs; pp < pronargs; pp++)
1436  {
1437  if (arggiven[pp])
1438  continue;
1439  /* fail if arg not given and no default available */
1440  if (pp < first_arg_with_default)
1441  return false;
1442  (*argnumbers)[ap++] = pp;
1443  }
1444  }
1445 
1446  Assert(ap == pronargs); /* processed all function parameters */
1447 
1448  return true;
1449 }
#define NIL
Definition: pg_list.h:65
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
Definition: funcapi.c:1268
int16 pronargs
Definition: pg_proc.h:81
unsigned int Oid
Definition: postgres_ext.h:31
#define FUNC_MAX_ARGS
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1388
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
static int list_length(const List *l)
Definition: pg_list.h:149
void * palloc(Size size)
Definition: mcxt.c:1062
int i

◆ NameListToQuotedString()

char* NameListToQuotedString ( List names)

Definition at line 3181 of file namespace.c.

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

3182 {
3184  ListCell *l;
3185 
3186  initStringInfo(&string);
3187 
3188  foreach(l, names)
3189  {
3190  if (l != list_head(names))
3191  appendStringInfoChar(&string, '.');
3193  }
3194 
3195  return string.data;
3196 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11332
#define strVal(v)
Definition: value.h:54
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define lfirst(lc)
Definition: pg_list.h:169

◆ NameListToString()

char* NameListToString ( List names)

Definition at line 3147 of file namespace.c.

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

Referenced by AggregateCreate(), AlterCollation(), AlterFunction(), AlterStatistics(), AlterTSConfiguration(), AlterTSDictionary(), check_object_ownership(), CreateConversionCommand(), CreateEventTrigger(), CreateProceduralLanguage(), CreateTransform(), CreateTriggerFiringOn(), DeconstructQualifiedName(), defGetString(), DefineOperator(), DefineType(), does_not_exist_skipping(), dropOperators(), dropProcedures(), ExpandColumnRefStar(), findRangeSubOpclass(), findTypeAnalyzeFunction(), findTypeInputFunction(), findTypeOutputFunction(), findTypeReceiveFunction(), findTypeSendFunction(), findTypeSubscriptingFunction(), 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(), interpret_func_support(), lookup_fdw_handler_func(), LookupFuncName(), LookupFuncWithArgs(), LookupTypeNameExtended(), 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().

3148 {
3150  ListCell *l;
3151 
3152  initStringInfo(&string);
3153 
3154  foreach(l, names)
3155  {
3156  Node *name = (Node *) lfirst(l);
3157 
3158  if (l != list_head(names))
3159  appendStringInfoChar(&string, '.');
3160 
3161  if (IsA(name, String))
3162  appendStringInfoString(&string, strVal(name));
3163  else if (IsA(name, A_Star))
3164  appendStringInfoChar(&string, '*');
3165  else
3166  elog(ERROR, "unexpected node type in name list: %d",
3167  (int) nodeTag(name));
3168  }
3169 
3170  return string.data;
3171 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:590
Definition: nodes.h:539
#define strVal(v)
Definition: value.h:54
#define ERROR
Definition: elog.h:46
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
char string[11]
Definition: preproc-type.c:46
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define lfirst(lc)
Definition: pg_list.h:169
const char * name
Definition: encode.c:515
#define nodeTag(nodeptr)
Definition: nodes.h:544
#define elog(elevel,...)
Definition: elog.h:232

◆ NamespaceCallback()

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

Definition at line 4410 of file namespace.c.

References baseSearchPathValid.

Referenced by InitializeSearchPath().

4411 {
4412  /* Force search path to be recomputed on next use */
4413  baseSearchPathValid = false;
4414 }
static bool baseSearchPathValid
Definition: namespace.c:160

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 1878 of file namespace.c.

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

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

1879 {
1880  HeapTuple opctup;
1881  Form_pg_opclass opcform;
1882  Oid opcnamespace;
1883  bool visible;
1884 
1885  opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
1886  if (!HeapTupleIsValid(opctup))
1887  elog(ERROR, "cache lookup failed for opclass %u", opcid);
1888  opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1889 
1891 
1892  /*
1893  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1894  * the system namespace are surely in the path and so we needn't even do
1895  * list_member_oid() for them.
1896  */
1897  opcnamespace = opcform->opcnamespace;
1898  if (opcnamespace != PG_CATALOG_NAMESPACE &&
1899  !list_member_oid(activeSearchPath, opcnamespace))
1900  visible = false;
1901  else
1902  {
1903  /*
1904  * If it is in the path, it might still not be visible; it could be
1905  * hidden by another opclass of the same name earlier in the path. So
1906  * we must do a slow check to see if this opclass would be found by
1907  * OpclassnameGetOpcid.
1908  */
1909  char *opcname = NameStr(opcform->opcname);
1910 
1911  visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1912  }
1913 
1914  ReleaseSysCache(opctup);
1915 
1916  return visible;
1917 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
unsigned int Oid
Definition: postgres_ext.h:31
Oid OpclassnameGetOpcid(Oid amid, const char *opcname)
Definition: namespace.c:1845
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1845 of file namespace.c.

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

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

1846 {
1847  Oid opcid;
1848  ListCell *l;
1849 
1851 
1852  foreach(l, activeSearchPath)
1853  {
1854  Oid namespaceId = lfirst_oid(l);
1855 
1856  if (namespaceId == myTempNamespace)
1857  continue; /* do not look in temp namespace */
1858 
1859  opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
1860  ObjectIdGetDatum(amid),
1861  PointerGetDatum(opcname),
1862  ObjectIdGetDatum(namespaceId));
1863  if (OidIsValid(opcid))
1864  return opcid;
1865  }
1866 
1867  /* Not found in path */
1868  return InvalidOid;
1869 }
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:197
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 1792 of file namespace.c.

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

Referenced by format_operator_extended(), and pg_operator_is_visible().

1793 {
1794  HeapTuple oprtup;
1795  Form_pg_operator oprform;
1796  Oid oprnamespace;
1797  bool visible;
1798 
1800  if (!HeapTupleIsValid(oprtup))
1801  elog(ERROR, "cache lookup failed for operator %u", oprid);
1802  oprform = (Form_pg_operator) GETSTRUCT(oprtup);
1803 
1805 
1806  /*
1807  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1808  * the system namespace are surely in the path and so we needn't even do
1809  * list_member_oid() for them.
1810  */
1811  oprnamespace = oprform->oprnamespace;
1812  if (oprnamespace != PG_CATALOG_NAMESPACE &&
1813  !list_member_oid(activeSearchPath, oprnamespace))
1814  visible = false;
1815  else
1816  {
1817  /*
1818  * If it is in the path, it might still not be visible; it could be
1819  * hidden by another operator of the same name and arguments earlier
1820  * in the path. So we must do a slow check to see if this is the same
1821  * operator that would be found by OpernameGetOprid.
1822  */
1823  char *oprname = NameStr(oprform->oprname);
1824 
1825  visible = (OpernameGetOprid(list_make1(makeString(oprname)),
1826  oprform->oprleft, oprform->oprright)
1827  == oprid);
1828  }
1829 
1830  ReleaseSysCache(oprtup);
1831 
1832  return visible;
1833 }
Value * makeString(char *str)
Definition: value.c:53
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
Oid oprid(Operator op)
Definition: parse_oper.c:250
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define list_make1(x1)
Definition: pg_list.h:206
Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
Definition: namespace.c:1528
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681

◆ OpernameGetCandidates()

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

Definition at line 1631 of file namespace.c.

References _FuncCandidateList::argnumbers, _FuncCandidateList::args, Assert, CStringGetDatum, DeconstructQualifiedName(), GETSTRUCT, i, InvalidOid, lfirst_oid, LookupExplicitNamespace(), catclist::members, myTempNamespace, catclist::n_members, _FuncCandidateList::nargs, _FuncCandidateList::ndargs, _FuncCandidateList::next, _FuncCandidateList::nominalnargs, _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(), and to_regoper().

1632 {
1633  FuncCandidateList resultList = NULL;
1634  char *resultSpace = NULL;
1635  int nextResult = 0;
1636  char *schemaname;
1637  char *opername;
1638  Oid namespaceId;
1639  CatCList *catlist;
1640  int i;
1641 
1642  /* deconstruct the name list */
1643  DeconstructQualifiedName(names, &schemaname, &opername);
1644 
1645  if (schemaname)
1646  {
1647  /* use exact schema given */
1648  namespaceId = LookupExplicitNamespace(schemaname, missing_schema_ok);
1649  if (missing_schema_ok && !OidIsValid(namespaceId))
1650  return NULL;
1651  }
1652  else
1653  {
1654  /* flag to indicate we need namespace search */
1655  namespaceId = InvalidOid;
1657  }
1658 
1659  /* Search syscache by name only */
1660  catlist = SearchSysCacheList1(OPERNAMENSP, CStringGetDatum(opername));
1661 
1662  /*
1663  * In typical scenarios, most if not all of the operators found by the
1664  * catcache search will end up getting returned; and there can be quite a
1665  * few, for common operator names such as '=' or '+'. To reduce the time
1666  * spent in palloc, we allocate the result space as an array large enough
1667  * to hold all the operators. The original coding of this routine did a
1668  * separate palloc for each operator, but profiling revealed that the
1669  * pallocs used an unreasonably large fraction of parsing time.
1670  */
1671 #define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
1672  2 * sizeof(Oid))
1673 
1674  if (catlist->n_members > 0)
1675  resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
1676 
1677  for (i = 0; i < catlist->n_members; i++)
1678  {
1679  HeapTuple opertup = &catlist->members[i]->tuple;
1680  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1681  int pathpos = 0;
1682  FuncCandidateList newResult;
1683 
1684  /* Ignore operators of wrong kind, if specific kind requested */
1685  if (oprkind && operform->oprkind != oprkind)
1686  continue;
1687 
1688  if (OidIsValid(namespaceId))
1689  {
1690  /* Consider only opers in specified namespace */
1691  if (operform->oprnamespace != namespaceId)
1692  continue;
1693  /* No need to check args, they must all be different */
1694  }
1695  else
1696  {
1697  /*
1698  * Consider only opers that are in the search path and are not in
1699  * the temp namespace.
1700  */
1701  ListCell *nsp;
1702 
1703  foreach(nsp, activeSearchPath)
1704  {
1705  if (operform->oprnamespace == lfirst_oid(nsp) &&
1706  operform->oprnamespace != myTempNamespace)
1707  break;
1708  pathpos++;
1709  }
1710  if (nsp == NULL)
1711  continue; /* oper is not in search path */
1712 
1713  /*
1714  * Okay, it's in the search path, but does it have the same
1715  * arguments as something we already accepted? If so, keep only
1716  * the one that appears earlier in the search path.
1717  *
1718  * If we have an ordered list from SearchSysCacheList (the normal
1719  * case), then any conflicting oper must immediately adjoin this
1720  * one in the list, so we only need to look at the newest result
1721  * item. If we have an unordered list, we have to scan the whole
1722  * result list.
1723  */
1724  if (resultList)
1725  {
1726  FuncCandidateList prevResult;
1727 
1728  if (catlist->ordered)
1729  {
1730  if (operform->oprleft == resultList->args[0] &&
1731  operform->oprright == resultList->args[1])
1732  prevResult = resultList;
1733  else
1734  prevResult = NULL;
1735  }
1736  else
1737  {
1738  for (prevResult = resultList;
1739  prevResult;
1740  prevResult = prevResult->next)
1741  {
1742  if (operform->oprleft == prevResult->args[0] &&
1743  operform->oprright == prevResult->args[1])
1744  break;
1745  }
1746  }
1747  if (prevResult)
1748  {
1749  /* We have a match with a previous result */
1750  Assert(pathpos != prevResult->pathpos);
1751  if (pathpos > prevResult->pathpos)
1752  continue; /* keep previous result */
1753  /* replace previous result */
1754  prevResult->pathpos = pathpos;
1755  prevResult->oid = operform->oid;
1756  continue; /* args are same, of course */
1757  }
1758  }
1759  }
1760 
1761  /*
1762  * Okay to add it to result list
1763  */
1764  newResult = (FuncCandidateList) (resultSpace + nextResult);
1765  nextResult += SPACE_PER_OP;
1766 
1767  newResult->pathpos = pathpos;
1768  newResult->oid = operform->oid;
1769  newResult->nominalnargs = 2;
1770  newResult->nargs = 2;
1771  newResult->nvargs = 0;
1772  newResult->ndargs = 0;
1773  newResult->argnumbers = NULL;
1774  newResult->args[0] = operform->oprleft;
1775  newResult->args[1] = operform->oprright;
1776  newResult->next = resultList;
1777  resultList = newResult;
1778  }
1779 
1780  ReleaseSysCacheList(catlist);
1781 
1782  return resultList;
1783 }
int n_members
Definition: catcache.h:176
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
static Oid myTempNamespace
Definition: namespace.c:188
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:38
struct _FuncCandidateList * FuncCandidateList
#define CStringGetDatum(X)
Definition: postgres.h:622
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:211
#define SPACE_PER_OP
struct _FuncCandidateList * next
Definition: namespace.h:30
#define ReleaseSysCacheList(x)
Definition: syscache.h:218
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:804
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
static List * activeSearchPath
Definition: namespace.c:138
bool ordered
Definition: catcache.h:174
void * palloc(Size size)
Definition: mcxt.c:1062
int i
HeapTupleData tuple
Definition: catcache.h:121
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OpernameGetOprid()

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

Definition at line 1528 of file namespace.c.

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

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

1529 {
1530  char *schemaname;
1531  char *opername;
1532  CatCList *catlist;
1533  ListCell *l;
1534 
1535  /* deconstruct the name list */
1536  DeconstructQualifiedName(names, &schemaname, &opername);
1537 
1538  if (schemaname)
1539  {
1540  /* search only in exact schema given */
1541  Oid namespaceId;
1542 
1543  namespaceId = LookupExplicitNamespace(schemaname, true);
1544  if (OidIsValid(namespaceId))
1545  {
1546  HeapTuple opertup;
1547 
1548  opertup = SearchSysCache4(OPERNAMENSP,
1549  CStringGetDatum(opername),
1550  ObjectIdGetDatum(oprleft),
1551  ObjectIdGetDatum(oprright),
1552  ObjectIdGetDatum(namespaceId));
1553  if (HeapTupleIsValid(opertup))
1554  {
1555  Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup);
1556  Oid result = operclass->oid;
1557 
1558  ReleaseSysCache(opertup);
1559  return result;
1560  }
1561  }
1562 
1563  return InvalidOid;
1564  }
1565 
1566  /* Search syscache by name and argument types */
1567  catlist = SearchSysCacheList3(OPERNAMENSP,
1568  CStringGetDatum(opername),
1569  ObjectIdGetDatum(oprleft),
1570  ObjectIdGetDatum(oprright));
1571 
1572  if (catlist->n_members == 0)
1573  {
1574  /* no hope, fall out early */
1575  ReleaseSysCacheList(catlist);
1576  return InvalidOid;
1577  }
1578 
1579  /*
1580  * We have to find the list member that is first in the search path, if
1581  * there's more than one. This doubly-nested loop looks ugly, but in
1582  * practice there should usually be few catlist members.
1583  */
1585 
1586  foreach(l, activeSearchPath)
1587  {
1588  Oid namespaceId = lfirst_oid(l);
1589  int i;
1590 
1591  if (namespaceId == myTempNamespace)
1592  continue; /* do not look in temp namespace */
1593 
1594  for (i = 0; i < catlist->n_members; i++)
1595  {
1596  HeapTuple opertup = &catlist->members[i]->tuple;
1597  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1598 
1599  if (operform->oprnamespace == namespaceId)
1600  {
1601  Oid result = operform->oid;
1602 
1603  ReleaseSysCacheList(catlist);
1604  return result;
1605  }
1606  }
1607  }
1608 
1609  ReleaseSysCacheList(catlist);
1610  return InvalidOid;
1611 }
int n_members
Definition: catcache.h:176
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:2938
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
static Oid myTempNamespace
Definition: namespace.c:188
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define CStringGetDatum(X)
Definition: postgres.h:622
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:1160
#define ReleaseSysCacheList(x)
Definition: syscache.h:218
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
static List * activeSearchPath
Definition: namespace.c:138
#define SearchSysCacheList3(cacheId, key1, key2, key3)
Definition: syscache.h:215
int i
HeapTupleData tuple
Definition: catcache.h:121
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 1961 of file namespace.c.

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

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

1962 {
1963  HeapTuple opftup;
1964  Form_pg_opfamily opfform;
1965  Oid opfnamespace;
1966  bool visible;
1967 
1968  opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
1969  if (!HeapTupleIsValid(opftup))
1970  elog(ERROR, "cache lookup failed for opfamily %u", opfid);
1971  opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
1972 
1974 
1975  /*
1976  * Quick check: if it ain't in the path at all, it ain't visible. Items in
1977  * the system namespace are surely in the path and so we needn't even do
1978  * list_member_oid() for them.
1979  */
1980  opfnamespace = opfform->opfnamespace;
1981  if (opfnamespace != PG_CATALOG_NAMESPACE &&
1982  !list_member_oid(activeSearchPath, opfnamespace))
1983  visible = false;
1984  else
1985  {
1986  /*
1987  * If it is in the path, it might still not be visible; it could be
1988  * hidden by another opfamily of the same name earlier in the path. So
1989  * we must do a slow check to see if this opfamily would be found by
1990  * OpfamilynameGetOpfid.
1991  */
1992  char *opfname = NameStr(opfform->opfname);
1993 
1994  visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
1995  }
1996 
1997  ReleaseSysCache(opftup);
1998 
1999  return visible;
2000 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
unsigned int Oid
Definition: postgres_ext.h:31
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
Oid OpfamilynameGetOpfid(Oid amid, const char *opfname)
Definition: namespace.c:1928
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static List * activeSearchPath
Definition: namespace.c:138
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1928 of file namespace.c.

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

1929 {
1930  Oid opfid;
1931  ListCell *l;
1932 
1934 
1935  foreach(l, activeSearchPath)
1936  {
1937  Oid namespaceId = lfirst_oid(l);
1938 
1939  if (namespaceId == myTempNamespace)
1940  continue; /* do not look in temp namespace */
1941 
1942  opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
1943  ObjectIdGetDatum(amid),
1944  PointerGetDatum(opfname),
1945  ObjectIdGetDatum(namespaceId));
1946  if (OidIsValid(opfid))
1947  return opfid;
1948  }
1949 
1950  /* Not found in path */
1951  return InvalidOid;
1952 }
#define PointerGetDatum(X)
Definition: postgres.h:600
static Oid myTempNamespace
Definition: namespace.c:188
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:197
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ OverrideSearchPathMatchesCurrent()

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path)

Definition at line 3464 of file namespace.c.

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

Referenced by CachedPlanAllowsSimpleValidityCheck(), CachedPlanIsSimplyValid(), and RevalidateCachedQuery().

3465 {
3466  ListCell *lc,
3467  *lcp;
3468 
3470 
3471  /* Quick out if already known equal to active path. */
3472  if (path->generation == activePathGeneration)
3473  return true;
3474 
3475  /* We scan down the activeSearchPath to see if it matches the input. */
3477 
3478  /* If path->addTemp, first item should be my temp namespace. */
3479  if (path->addTemp)
3480  {
3481  if (lc && lfirst_oid(lc) == myTempNamespace)
3482  lc = lnext(activeSearchPath, lc);
3483  else
3484  return false;
3485  }
3486  /* If path->addCatalog, next item should be pg_catalog. */
3487  if (path->addCatalog)
3488  {
3489  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3490  lc = lnext(activeSearchPath, lc);
3491  else
3492  return false;
3493  }
3494  /* We should now be looking at the activeCreationNamespace. */
3495  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3496  return false;
3497  /* The remainder of activeSearchPath should match path->schemas. */
3498  foreach(lcp, path->schemas)
3499  {
3500  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3501  lc = lnext(activeSearchPath, lc);
3502  else
3503  return false;
3504  }
3505  if (lc)
3506  return false;
3507 
3508  /*
3509  * Update path->generation so that future tests will return quickly, so
3510  * long as the active search path doesn't change.
3511  */
3513 
3514  return true;
3515 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:322
static Oid myTempNamespace
Definition: namespace.c:188
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
#define InvalidOid
Definition: postgres_ext.h:36
static List * activeSearchPath
Definition: namespace.c:138
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ pg_collation_is_visible()

Datum pg_collation_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4571 of file namespace.c.

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

4572 {
4573  Oid oid = PG_GETARG_OID(0);
4574 
4576  PG_RETURN_NULL();
4577 
4579 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
bool CollationIsVisible(Oid collid)
Definition: namespace.c:2093
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_conversion_is_visible()

Datum pg_conversion_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4582 of file namespace.c.

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

4583 {
4584  Oid oid = PG_GETARG_OID(0);
4585 
4587  PG_RETURN_NULL();
4588 
4590 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool ConversionIsVisible(Oid conid)
Definition: namespace.c:2176
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_function_is_visible()

Datum pg_function_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4527 of file namespace.c.

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

4528 {
4529  Oid oid = PG_GETARG_OID(0);
4530 
4532  PG_RETURN_NULL();
4533 
4535 }
bool FunctionIsVisible(Oid funcid)
Definition: namespace.c:1458
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_is_other_temp_schema()

Datum pg_is_other_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4654 of file namespace.c.

References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.

4655 {
4656  Oid oid = PG_GETARG_OID(0);
4657 
4659 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool isOtherTempNamespace(Oid namespaceId)
Definition: namespace.c:3263

◆ pg_my_temp_schema()

Datum pg_my_temp_schema ( PG_FUNCTION_ARGS  )

Definition at line 4648 of file namespace.c.

References myTempNamespace, and PG_RETURN_OID.

4649 {
4651 }
static Oid myTempNamespace
Definition: namespace.c:188
#define PG_RETURN_OID(x)
Definition: fmgr.h:360

◆ pg_opclass_is_visible()

Datum pg_opclass_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4549 of file namespace.c.

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

4550 {
4551  Oid oid = PG_GETARG_OID(0);
4552 
4554  PG_RETURN_NULL();
4555 
4557 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool OpclassIsVisible(Oid opcid)
Definition: namespace.c:1878
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_operator_is_visible()

Datum pg_operator_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4538 of file namespace.c.

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

4539 {
4540  Oid oid = PG_GETARG_OID(0);
4541 
4543  PG_RETURN_NULL();
4544 
4546 }
bool OperatorIsVisible(Oid oprid)
Definition: namespace.c:1792
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_opfamily_is_visible()

Datum pg_opfamily_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4560 of file namespace.c.

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

4561 {
4562  Oid oid = PG_GETARG_OID(0);
4563 
4565  PG_RETURN_NULL();
4566 
4568 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
bool OpfamilyIsVisible(Oid opfid)
Definition: namespace.c:1961
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_statistics_obj_is_visible()

Datum pg_statistics_obj_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4593 of file namespace.c.

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

4594 {
4595  Oid oid = PG_GETARG_OID(0);
4596 
4598  PG_RETURN_NULL();
4599 
4601 }
bool StatisticsObjIsVisible(Oid relid)
Definition: namespace.c:2280
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_table_is_visible()

Datum pg_table_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4505 of file namespace.c.

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

4506 {
4507  Oid oid = PG_GETARG_OID(0);
4508 
4510  PG_RETURN_NULL();
4511 
4513 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool RelationIsVisible(Oid relid)
Definition: namespace.c:709
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_ts_config_is_visible()

Datum pg_ts_config_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4637 of file namespace.c.

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

4638 {
4639  Oid oid = PG_GETARG_OID(0);
4640 
4642  PG_RETURN_NULL();
4643 
4645 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
bool TSConfigIsVisible(Oid cfgid)
Definition: namespace.c:2782
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_ts_dict_is_visible()

Datum pg_ts_dict_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4615 of file namespace.c.

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

4616 {
4617  Oid oid = PG_GETARG_OID(0);
4618 
4620  PG_RETURN_NULL();
4621 
4623 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
bool TSDictionaryIsVisible(Oid dictId)
Definition: namespace.c:2529
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_ts_parser_is_visible()

Datum pg_ts_parser_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4604 of file namespace.c.

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

4605 {
4606  Oid oid = PG_GETARG_OID(0);
4607 
4609  PG_RETURN_NULL();
4610 
4612 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool TSParserIsVisible(Oid prsId)
Definition: namespace.c:2403
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_ts_template_is_visible()

Datum pg_ts_template_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4626 of file namespace.c.

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

4627 {
4628  Oid oid = PG_GETARG_OID(0);
4629 
4631  PG_RETURN_NULL();
4632 
4634 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool TSTemplateIsVisible(Oid tmplId)
Definition: namespace.c:2656
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_type_is_visible()

Datum pg_type_is_visible ( PG_FUNCTION_ARGS  )

Definition at line 4516 of file namespace.c.

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

4517 {
4518  Oid oid = PG_GETARG_OID(0);
4519 
4521  PG_RETURN_NULL();
4522 
4524 }
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool TypeIsVisible(Oid typid)
Definition: namespace.c:817
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ PopOverrideSearchPath()

void PopOverrideSearchPath ( void  )

Definition at line 3602 of file namespace.c.

References activeCreationNamespace, activePathGeneration, 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().

3603 {
3604  OverrideStackEntry *entry;
3605 
3606  /* Sanity checks. */
3607  if (overrideStack == NIL)
3608  elog(ERROR, "bogus PopOverrideSearchPath call");
3610  if (entry->nestLevel != GetCurrentTransactionNestLevel())
3611  elog(ERROR, "bogus PopOverrideSearchPath call");
3612 
3613  /* Pop the stack and free storage. */
3615  list_free(entry->searchPath);
3616  pfree(entry);
3617 
3618  /* Activate the next level down. */
3619  if (overrideStack)
3620  {
3622  activeSearchPath = entry->searchPath;
3624  activeTempCreationPending = false; /* XXX is this OK? */
3625  }
3626  else
3627  {
3628  /* If not baseSearchPathValid, this is useless but harmless */
3632  }
3633 
3634  /* As above, the generation always increments. */
3636 }
#define NIL
Definition: pg_list.h:65
static List * overrideStack
Definition: namespace.c:171
static Oid activeCreationNamespace
Definition: namespace.c:141
void pfree(void *pointer)
Definition: mcxt.c:1169
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:46
static bool baseTempCreationPending
Definition: namespace.c:155
static uint64 activePathGeneration
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:144
static Oid baseCreationNamespace
Definition: namespace.c:153
static List * baseSearchPath
Definition: namespace.c:151
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
static List * activeSearchPath
Definition: namespace.c:138
void list_free(List *list)
Definition: list.c:1391
#define elog(elevel,...)
Definition: elog.h:232
List * list_delete_first(List *list)
Definition: list.c:875

◆ PushOverrideSearchPath()

void PushOverrideSearchPath ( OverrideSearchPath newpath)

Definition at line 3535 of file namespace.c.

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

Referenced by CreateSchemaCommand().

3536 {
3537  OverrideStackEntry *entry;
3538  List *oidlist;
3539  Oid firstNS;
3540  MemoryContext oldcxt;
3541 
3542  /*
3543  * Copy the list for safekeeping, and insert implicitly-searched
3544  * namespaces as needed. This code should track recomputeNamespacePath.
3545  */
3547 
3548  oidlist = list_copy(newpath->schemas);
3549 
3550  /*
3551  * Remember the first member of the explicit list.
3552  */
3553  if (oidlist == NIL)
3554  firstNS = InvalidOid;
3555  else
3556  firstNS = linitial_oid(oidlist);
3557 
3558  /*
3559  * Add any implicitly-searched namespaces to the list. Note these go on
3560  * the front, not the back; also notice that we do not check USAGE
3561  * permissions for these.
3562  */
3563  if (newpath->addCatalog)
3564  oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
3565 
3566  if (newpath->addTemp && OidIsValid(myTempNamespace))
3567  oidlist = lcons_oid(myTempNamespace, oidlist);
3568 
3569  /*
3570  * Build the new stack entry, then insert it at the head of the list.
3571  */
3572  entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
3573  entry->searchPath = oidlist;
3574  entry->creationNamespace = firstNS;
3576 
3577  overrideStack = lcons(entry, overrideStack);
3578 
3579  /* And make it active. */
3580  activeSearchPath = entry->searchPath;
3582  activeTempCreationPending = false; /* XXX is this OK? */
3583 
3584  /*
3585  * We always increment activePathGeneration when pushing/popping an
3586  * override path. In current usage, these actions always change the
3587  * effective path state, so there's no value in checking to see if it
3588  * didn't change.
3589  */
3591 
3592  MemoryContextSwitchTo(oldcxt);
3593 }
#define NIL
Definition: pg_list.h:65
static Oid myTempNamespace
Definition: namespace.c:188
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static List * overrideStack
Definition: namespace.c:171
List * list_copy(const List *oldlist)
Definition: list.c:1418
List * lcons_oid(Oid datum, List *list)
Definition: list.c:504
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static Oid activeCreationNamespace
Definition: namespace.c:141
static uint64 activePathGeneration
Definition: namespace.c:147
static bool activeTempCreationPending
Definition: namespace.c:144
MemoryContext TopMemoryContext
Definition: mcxt.c:48
#define InvalidOid
Definition: postgres_ext.h:36
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
List * lcons(void *datum, List *list)
Definition: list.c:468
#define linitial_oid(l)
Definition: pg_list.h:176
static List * activeSearchPath
Definition: namespace.c:138
void * palloc(Size size)
Definition: mcxt.c:1062
Definition: pg_list.h:50

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 3040 of file namespace.c.

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

3041 {
3042  char *schemaname;
3043  Oid namespaceId;
3044 
3045  /* deconstruct the name list */
3046  DeconstructQualifiedName(names, &schemaname, objname_p);
3047 
3048  if (schemaname)
3049  {
3050  /* check for pg_temp alias */
3051  if (strcmp(schemaname, "pg_temp") == 0)
3052  {
3053  /* Initialize temp namespace */
3054  AccessTempTableNamespace(false);
3055  return myTempNamespace;
3056  }
3057  /* use exact schema given */
3058  namespaceId = get_namespace_oid(schemaname, false);
3059  /* we do not check for USAGE rights here! */
3060  }
3061  else
3062  {
3063  /* use the default creation namespace */
3066  {
3067  /* Need to initialize temp namespace */
3069  return myTempNamespace;
3070  }
3071  namespaceId = activeCreationNamespace;
3072  if (!OidIsValid(namespaceId))
3073  ereport(ERROR,
3074  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3075  errmsg("no schema has been selected to create in")));
3076  }
3077 
3078  return namespaceId;
3079 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3960
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:2854
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
static Oid activeCreationNamespace
Definition: namespace.c:141
#define ERROR
Definition: elog.h:46
static bool activeTempCreationPending
Definition: namespace.c:144
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 642 of file namespace.c.

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

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

643 {
644  switch (newRelation->relpersistence)
645  {
646  case RELPERSISTENCE_TEMP:
647  if (!isTempOrTempToastNamespace(nspid))
648  {
649  if (isAnyTempNamespace(nspid))
650  ereport(ERROR,
651  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
652  errmsg("cannot create relations in temporary schemas of other sessions")));
653  else
654  ereport(ERROR,
655  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
656  errmsg("cannot create temporary relation in non-temporary schema")));
657  }
658  break;
659  case RELPERSISTENCE_PERMANENT:
660  if (isTempOrTempToastNamespace(nspid))
661  newRelation->relpersistence = RELPERSISTENCE_TEMP;
662  else if (isAnyTempNamespace(nspid))
663  ereport(ERROR,
664  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
665  errmsg("cannot create relations in temporary schemas of other sessions")));
666  break;
667  default:
668  if (isAnyTempNamespace(nspid))
669  ereport(ERROR,
670  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
671  errmsg("only temporary relations may be created in temporary schemas")));
672  }
673 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3226
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:909
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3240

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 535 of file namespace.c.

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

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

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 450 of file namespace.c.

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

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

451 {
452  Oid namespaceId;
453 
454  /*
455  * We check the catalog name and then ignore it.
456  */
457  if (newRelation->catalogname)
458  {
459  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
460  ereport(ERROR,
461  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
462  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
463  newRelation->catalogname, newRelation->schemaname,
464  newRelation->relname)));
465  }
466 
467  if (newRelation->schemaname)
468  {
469  /* check for pg_temp alias */
470  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
471  {
472  /* Initialize temp namespace */
474  return myTempNamespace;
475  }
476  /* use exact schema given */
477  namespaceId = get_namespace_oid(newRelation->schemaname, false);
478  /* we do not check for USAGE rights here! */
479  }
480  else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
481  {
482  /* Initialize temp namespace */
484  return myTempNamespace;
485  }
486  else
487  {
488  /* use the default creation namespace */
491  {
492  /* Need to initialize temp namespace */
494  return myTempNamespace;
495  }
496  namespaceId = activeCreationNamespace;
497  if (!OidIsValid(namespaceId))
498  ereport(ERROR,
499  (errcode(ERRCODE_UNDEFINED_SCHEMA),
500  errmsg("no schema has been selected to create in")));
501  }
502 
503  /* Note: callers will check for CREATE rights when appropriate */
504 
505  return namespaceId;
506 }
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3088
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:3960
static Oid myTempNamespace
Definition: namespace.c:188
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
static void recomputeNamespacePath(void)
Definition: namespace.c:3782
char * schemaname
Definition: primnodes.h:67
char * relname
Definition: primnodes.h:68
static Oid activeCreationNamespace
Definition: namespace.c:141
#define ERROR
Definition: elog.h:46
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2113
static bool activeTempCreationPending
Definition: namespace.c:144
Oid MyDatabaseId
Definition: globals.c:88
#define ereport(elevel,...)
Definition: elog.h:157
char relpersistence
Definition: primnodes.h:71
int errmsg(const char *fmt,...)
Definition: elog.c:909
char * catalogname
Definition: primnodes.h:66

◆ RangeVarGetRelidExtended()

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