PostgreSQL Source Code  git master
namespace.h File Reference
#include "nodes/primnodes.h"
#include "storage/lock.h"
Include dependency graph for namespace.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  _FuncCandidateList
 
struct  SearchPathMatcher
 

Macros

#define RangeVarGetRelid(relation, lockmode, missing_ok)
 

Typedefs

typedef struct _FuncCandidateListFuncCandidateList
 
typedef enum TempNamespaceStatus TempNamespaceStatus
 
typedef struct SearchPathMatcher SearchPathMatcher
 
typedef enum RVROption RVROption
 
typedef void(* RangeVarGetRelidCallback) (const RangeVar *relation, Oid relId, Oid oldRelId, void *callback_arg)
 

Enumerations

enum  TempNamespaceStatus { TEMP_NAMESPACE_NOT_TEMP , TEMP_NAMESPACE_IDLE , TEMP_NAMESPACE_IN_USE }
 
enum  RVROption { RVR_MISSING_OK = 1 << 0 , RVR_NOWAIT = 1 << 1 , RVR_SKIP_LOCKED = 1 << 2 }
 

Functions

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)
 
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 stxid)
 
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 (const List *names, char **nspname_p, char **objname_p)
 
Oid LookupNamespaceNoError (const char *nspname)
 
Oid LookupExplicitNamespace (const char *nspname, bool missing_ok)
 
Oid get_namespace_oid (const char *nspname, bool missing_ok)
 
Oid LookupCreationNamespace (const char *nspname)
 
void CheckSetNamespace (Oid oldNspOid, Oid nspOid)
 
Oid QualifiedNameGetCreationNamespace (const List *names, char **objname_p)
 
RangeVarmakeRangeVarFromNameList (const List *names)
 
char * NameListToString (const List *names)
 
char * NameListToQuotedString (const 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)
 
void ResetTempTableNamespace (void)
 
SearchPathMatcherGetSearchPathMatcher (MemoryContext context)
 
SearchPathMatcherCopySearchPathMatcher (SearchPathMatcher *path)
 
bool SearchPathMatchesCurrentEnvironment (SearchPathMatcher *path)
 
Oid get_collation_oid (List *collname, bool missing_ok)
 
Oid get_conversion_oid (List *conname, bool missing_ok)
 
Oid FindDefaultConversionProc (int32 for_encoding, int32 to_encoding)
 
void InitializeSearchPath (void)
 
void AtEOXact_Namespace (bool isCommit, bool parallel)
 
void AtEOSubXact_Namespace (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
Listfetch_search_path (bool includeImplicit)
 
int fetch_search_path_array (Oid *sarray, int sarray_len)
 

Variables

PGDLLIMPORT char * namespace_search_path
 

Macro Definition Documentation

◆ RangeVarGetRelid

#define RangeVarGetRelid (   relation,
  lockmode,
  missing_ok 
)
Value:
RangeVarGetRelidExtended(relation, lockmode, \
(missing_ok) ? RVR_MISSING_OK : 0, NULL, NULL)
@ RVR_MISSING_OK
Definition: namespace.h:71
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Definition: namespace.c:426

Definition at line 79 of file namespace.h.

Typedef Documentation

◆ FuncCandidateList

◆ RangeVarGetRelidCallback

typedef void(* RangeVarGetRelidCallback) (const RangeVar *relation, Oid relId, Oid oldRelId, void *callback_arg)

Definition at line 76 of file namespace.h.

◆ RVROption

typedef enum RVROption RVROption

◆ SearchPathMatcher

◆ TempNamespaceStatus

Enumeration Type Documentation

◆ RVROption

enum RVROption
Enumerator
RVR_MISSING_OK 
RVR_NOWAIT 
RVR_SKIP_LOCKED 

Definition at line 69 of file namespace.h.

70 {
71  RVR_MISSING_OK = 1 << 0, /* don't error if relation doesn't exist */
72  RVR_NOWAIT = 1 << 1, /* error if relation cannot be locked */
73  RVR_SKIP_LOCKED = 1 << 2, /* skip if relation cannot be locked */
74 } RVROption;
RVROption
Definition: namespace.h:70
@ RVR_SKIP_LOCKED
Definition: namespace.h:73
@ RVR_NOWAIT
Definition: namespace.h:72

◆ TempNamespaceStatus

Enumerator
TEMP_NAMESPACE_NOT_TEMP 
TEMP_NAMESPACE_IDLE 
TEMP_NAMESPACE_IN_USE 

Definition at line 44 of file namespace.h.

45 {
46  TEMP_NAMESPACE_NOT_TEMP, /* nonexistent, or non-temp namespace */
47  TEMP_NAMESPACE_IDLE, /* exists, belongs to no active session */
48  TEMP_NAMESPACE_IN_USE, /* belongs to some active session */
TempNamespaceStatus
Definition: namespace.h:45
@ TEMP_NAMESPACE_IN_USE
Definition: namespace.h:48
@ TEMP_NAMESPACE_NOT_TEMP
Definition: namespace.h:46
@ TEMP_NAMESPACE_IDLE
Definition: namespace.h:47

Function Documentation

◆ AtEOSubXact_Namespace()

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

Definition at line 4543 of file namespace.c.

4545 {
4546 
4547  if (myTempNamespaceSubID == mySubid)
4548  {
4549  if (isCommit)
4550  myTempNamespaceSubID = parentSubid;
4551  else
4552  {
4554  /* TEMP namespace creation failed, so reset state */
4557  baseSearchPathValid = false; /* need to rebuild list */
4558  searchPathCacheValid = false;
4559 
4560  /*
4561  * Reset the temporary namespace flag in MyProc. We assume that
4562  * this operation is atomic.
4563  *
4564  * Because this subtransaction is aborting, the pg_namespace row
4565  * is not visible to anyone else anyway, but that doesn't matter:
4566  * it's not a problem if objects contained in this namespace are
4567  * removed concurrently.
4568  */
4570  }
4571  }
4572 }
#define InvalidSubTransactionId
Definition: c.h:647
static bool searchPathCacheValid
Definition: namespace.c:164
static bool baseSearchPathValid
Definition: namespace.c:158
static SubTransactionId myTempNamespaceSubID
Definition: namespace.c:205
static Oid myTempToastNamespace
Definition: namespace.c:203
static Oid myTempNamespace
Definition: namespace.c:201
#define InvalidOid
Definition: postgres_ext.h:36
PGPROC * MyProc
Definition: proc.c:67
Oid tempNamespaceId
Definition: proc.h:201

References baseSearchPathValid, InvalidOid, InvalidSubTransactionId, MyProc, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, searchPathCacheValid, and PGPROC::tempNamespaceId.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Namespace()

void AtEOXact_Namespace ( bool  isCommit,
bool  parallel 
)

Definition at line 4497 of file namespace.c.

4498 {
4499  /*
4500  * If we abort the transaction in which a temp namespace was selected,
4501  * we'll have to do any creation or cleanout work over again. So, just
4502  * forget the namespace entirely until next time. On the other hand, if
4503  * we commit then register an exit callback to clean out the temp tables
4504  * at backend shutdown. (We only want to register the callback once per
4505  * session, so this is a good place to do it.)
4506  */
4507  if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
4508  {
4509  if (isCommit)
4511  else
4512  {
4515  baseSearchPathValid = false; /* need to rebuild list */
4516  searchPathCacheValid = false;
4517 
4518  /*
4519  * Reset the temporary namespace flag in MyProc. We assume that
4520  * this operation is atomic.
4521  *
4522  * Because this transaction is aborting, the pg_namespace row is
4523  * not visible to anyone else anyway, but that doesn't matter:
4524  * it's not a problem if objects contained in this namespace are
4525  * removed concurrently.
4526  */
4528  }
4530  }
4531 
4532 }
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:337
static void RemoveTempRelationsCallback(int code, Datum arg)
Definition: namespace.c:4609

References baseSearchPathValid, before_shmem_exit(), InvalidOid, InvalidSubTransactionId, MyProc, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, RemoveTempRelationsCallback(), searchPathCacheValid, and PGPROC::tempNamespaceId.

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

◆ CheckSetNamespace()

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid 
)

Definition at line 3444 of file namespace.c.

3445 {
3446  /* disallow renaming into or out of temp schemas */
3447  if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
3448  ereport(ERROR,
3449  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3450  errmsg("cannot move objects into or out of temporary schemas")));
3451 
3452  /* same for TOAST schema */
3453  if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
3454  ereport(ERROR,
3455  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3456  errmsg("cannot move objects into or out of TOAST schema")));
3457 }
int errcode(int sqlerrcode)
Definition: elog.c:860
int errmsg(const char *fmt,...)
Definition: elog.c:1075
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
bool isAnyTempNamespace(Oid namespaceId)
Definition: namespace.c:3672

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

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

◆ checkTempNamespaceStatus()

TempNamespaceStatus checkTempNamespaceStatus ( Oid  namespaceId)

Definition at line 3714 of file namespace.c.

3715 {
3716  PGPROC *proc;
3717  int backendId;
3718 
3720 
3721  backendId = GetTempNamespaceBackendId(namespaceId);
3722 
3723  /* No such namespace, or its name shows it's not temp? */
3724  if (backendId == InvalidBackendId)
3725  return TEMP_NAMESPACE_NOT_TEMP;
3726 
3727  /* Is the backend alive? */
3728  proc = BackendIdGetProc(backendId);
3729  if (proc == NULL)
3730  return TEMP_NAMESPACE_IDLE;
3731 
3732  /* Is the backend connected to the same database we are looking at? */
3733  if (proc->databaseId != MyDatabaseId)
3734  return TEMP_NAMESPACE_IDLE;
3735 
3736  /* Does the backend own the temporary namespace? */
3737  if (proc->tempNamespaceId != namespaceId)
3738  return TEMP_NAMESPACE_IDLE;
3739 
3740  /* Yup, so namespace is busy */
3741  return TEMP_NAMESPACE_IN_USE;
3742 }
#define InvalidBackendId
Definition: backendid.h:23
#define OidIsValid(objectId)
Definition: c.h:764
Oid MyDatabaseId
Definition: globals.c:90
Assert(fmt[strlen(fmt) - 1] !='\n')
int GetTempNamespaceBackendId(Oid namespaceId)
Definition: namespace.c:3751
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:385
Definition: proc.h:162
Oid databaseId
Definition: proc.h:198

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().

◆ CollationGetCollid()

Oid CollationGetCollid ( const char *  collname)

Definition at line 2358 of file namespace.c.

2359 {
2360  int32 dbencoding = GetDatabaseEncoding();
2361  ListCell *l;
2362 
2364 
2365  foreach(l, activeSearchPath)
2366  {
2367  Oid namespaceId = lfirst_oid(l);
2368  Oid collid;
2369 
2370  if (namespaceId == myTempNamespace)
2371  continue; /* do not look in temp namespace */
2372 
2373  collid = lookup_collation(collname, namespaceId, dbencoding);
2374  if (OidIsValid(collid))
2375  return collid;
2376  }
2377 
2378  /* Not found in path */
2379  return InvalidOid;
2380 }
signed int int32
Definition: c.h:483
Oid collid
int GetDatabaseEncoding(void)
Definition: mbutils.c:1268
static Oid lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
Definition: namespace.c:2307
static List * activeSearchPath
Definition: namespace.c:136
static void recomputeNamespacePath(void)
Definition: namespace.c:4284
#define lfirst_oid(lc)
Definition: pg_list.h:174
unsigned int Oid
Definition: postgres_ext.h:31

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

Referenced by CollationIsVisibleExt().

◆ CollationIsVisible()

bool CollationIsVisible ( Oid  collid)

Definition at line 2392 of file namespace.c.

2393 {
2394  return CollationIsVisibleExt(collid, NULL);
2395 }
static bool CollationIsVisibleExt(Oid collid, bool *is_missing)
Definition: namespace.c:2404

References CollationIsVisibleExt(), and collid.

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

◆ ConversionGetConid()

Oid ConversionGetConid ( const char *  conname)

Definition at line 2462 of file namespace.c.

2463 {
2464  Oid conid;
2465  ListCell *l;
2466 
2468 
2469  foreach(l, activeSearchPath)
2470  {
2471  Oid namespaceId = lfirst_oid(l);
2472 
2473  if (namespaceId == myTempNamespace)
2474  continue; /* do not look in temp namespace */
2475 
2476  conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
2477  PointerGetDatum(conname),
2478  ObjectIdGetDatum(namespaceId));
2479  if (OidIsValid(conid))
2480  return conid;
2481  }
2482 
2483  /* Not found in path */
2484  return InvalidOid;
2485 }
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition: syscache.h:106

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

Referenced by ConversionIsVisibleExt().

◆ ConversionIsVisible()

bool ConversionIsVisible ( Oid  conid)

Definition at line 2494 of file namespace.c.

2495 {
2496  return ConversionIsVisibleExt(conid, NULL);
2497 }
static bool ConversionIsVisibleExt(Oid conid, bool *is_missing)
Definition: namespace.c:2506

References ConversionIsVisibleExt().

Referenced by getObjectDescription().

◆ CopySearchPathMatcher()

SearchPathMatcher* CopySearchPathMatcher ( SearchPathMatcher path)

Definition at line 3874 of file namespace.c.

3875 {
3876  SearchPathMatcher *result;
3877 
3878  result = (SearchPathMatcher *) palloc(sizeof(SearchPathMatcher));
3879  result->schemas = list_copy(path->schemas);
3880  result->addCatalog = path->addCatalog;
3881  result->addTemp = path->addTemp;
3882  result->generation = path->generation;
3883 
3884  return result;
3885 }
List * list_copy(const List *oldlist)
Definition: list.c:1573
void * palloc(Size size)
Definition: mcxt.c:1201
uint64 generation
Definition: namespace.h:63

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

Referenced by CopyCachedPlan().

◆ DeconstructQualifiedName()

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

Definition at line 3286 of file namespace.c.

3289 {
3290  char *catalogname;
3291  char *schemaname = NULL;
3292  char *objname = NULL;
3293 
3294  switch (list_length(names))
3295  {
3296  case 1:
3297  objname = strVal(linitial(names));
3298  break;
3299  case 2:
3300  schemaname = strVal(linitial(names));
3301  objname = strVal(lsecond(names));
3302  break;
3303  case 3:
3304  catalogname = strVal(linitial(names));
3305  schemaname = strVal(lsecond(names));
3306  objname = strVal(lthird(names));
3307 
3308  /*
3309  * We check the catalog name and then ignore it.
3310  */
3311  if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
3312  ereport(ERROR,
3313  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3314  errmsg("cross-database references are not implemented: %s",
3315  NameListToString(names))));
3316  break;
3317  default:
3318  ereport(ERROR,
3319  (errcode(ERRCODE_SYNTAX_ERROR),
3320  errmsg("improper qualified name (too many dotted names): %s",
3321  NameListToString(names))));
3322  break;
3323  }
3324 
3325  *nspname_p = schemaname;
3326  *objname_p = objname;
3327 }
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3089
char * NameListToString(const List *names)
Definition: namespace.c:3579
static int list_length(const List *l)
Definition: pg_list.h:152
#define lthird(l)
Definition: pg_list.h:188
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
#define strVal(v)
Definition: value.h:82

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().

◆ fetch_search_path()

List* fetch_search_path ( bool  includeImplicit)

Definition at line 4792 of file namespace.c.

4793 {
4794  List *result;
4795 
4797 
4798  /*
4799  * If the temp namespace should be first, force it to exist. This is so
4800  * that callers can trust the result to reflect the actual default
4801  * creation namespace. It's a bit bogus to do this here, since
4802  * current_schema() is supposedly a stable function without side-effects,
4803  * but the alternatives seem worse.
4804  */
4806  {
4809  }
4810 
4811  result = list_copy(activeSearchPath);
4812  if (!includeImplicit)
4813  {
4814  while (result && linitial_oid(result) != activeCreationNamespace)
4815  result = list_delete_first(result);
4816  }
4817 
4818  return result;
4819 }
List * list_delete_first(List *list)
Definition: list.c:943
static Oid activeCreationNamespace
Definition: namespace.c:139
static bool activeTempCreationPending
Definition: namespace.c:142
static void AccessTempTableNamespace(bool force)
Definition: namespace.c:4347
#define linitial_oid(l)
Definition: pg_list.h:180
Definition: pg_list.h:54

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

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

◆ fetch_search_path_array()

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 4832 of file namespace.c.

4833 {
4834  int count = 0;
4835  ListCell *l;
4836 
4838 
4839  foreach(l, activeSearchPath)
4840  {
4841  Oid namespaceId = lfirst_oid(l);
4842 
4843  if (namespaceId == myTempNamespace)
4844  continue; /* do not include temp namespace */
4845 
4846  if (count < sarray_len)
4847  sarray[count] = namespaceId;
4848  count++;
4849  }
4850 
4851  return count;
4852 }

References activeSearchPath, lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

◆ FindDefaultConversionProc()

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 4065 of file namespace.c.

4066 {
4067  Oid proc;
4068  ListCell *l;
4069 
4071 
4072  foreach(l, activeSearchPath)
4073  {
4074  Oid namespaceId = lfirst_oid(l);
4075 
4076  if (namespaceId == myTempNamespace)
4077  continue; /* do not look in temp namespace */
4078 
4079  proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
4080  if (OidIsValid(proc))
4081  return proc;
4082  }
4083 
4084  /* Not found in path */
4085  return InvalidOid;
4086 }
Oid FindDefaultConversion(Oid name_space, int32 for_encoding, int32 to_encoding)

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

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

◆ 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 1177 of file namespace.c.

1180 {
1181  FuncCandidateList resultList = NULL;
1182  bool any_special = false;
1183  char *schemaname;
1184  char *funcname;
1185  Oid namespaceId;
1186  CatCList *catlist;
1187  int i;
1188 
1189  /* check for caller error */
1190  Assert(nargs >= 0 || !(expand_variadic | expand_defaults));
1191 
1192  /* deconstruct the name list */
1193  DeconstructQualifiedName(names, &schemaname, &funcname);
1194 
1195  if (schemaname)
1196  {
1197  /* use exact schema given */
1198  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
1199  if (!OidIsValid(namespaceId))
1200  return NULL;
1201  }
1202  else
1203  {
1204  /* flag to indicate we need namespace search */
1205  namespaceId = InvalidOid;
1207  }
1208 
1209  /* Search syscache by name only */
1210  catlist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(funcname));
1211 
1212  for (i = 0; i < catlist->n_members; i++)
1213  {
1214  HeapTuple proctup = &catlist->members[i]->tuple;
1215  Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
1216  Oid *proargtypes = procform->proargtypes.values;
1217  int pronargs = procform->pronargs;
1218  int effective_nargs;
1219  int pathpos = 0;
1220  bool variadic;
1221  bool use_defaults;
1222  Oid va_elem_type;
1223  int *argnumbers = NULL;
1224  FuncCandidateList newResult;
1225 
1226  if (OidIsValid(namespaceId))
1227  {
1228  /* Consider only procs in specified namespace */
1229  if (procform->pronamespace != namespaceId)
1230  continue;
1231  }
1232  else
1233  {
1234  /*
1235  * Consider only procs that are in the search path and are not in
1236  * the temp namespace.
1237  */
1238  ListCell *nsp;
1239 
1240  foreach(nsp, activeSearchPath)
1241  {
1242  if (procform->pronamespace == lfirst_oid(nsp) &&
1243  procform->pronamespace != myTempNamespace)
1244  break;
1245  pathpos++;
1246  }
1247  if (nsp == NULL)
1248  continue; /* proc is not in search path */
1249  }
1250 
1251  /*
1252  * If we are asked to match to OUT arguments, then use the
1253  * proallargtypes array (which includes those); otherwise use
1254  * proargtypes (which doesn't). Of course, if proallargtypes is null,
1255  * we always use proargtypes.
1256  */
1257  if (include_out_arguments)
1258  {
1259  Datum proallargtypes;
1260  bool isNull;
1261 
1262  proallargtypes = SysCacheGetAttr(PROCNAMEARGSNSP, proctup,
1263  Anum_pg_proc_proallargtypes,
1264  &isNull);
1265  if (!isNull)
1266  {
1267  ArrayType *arr = DatumGetArrayTypeP(proallargtypes);
1268 
1269  pronargs = ARR_DIMS(arr)[0];
1270  if (ARR_NDIM(arr) != 1 ||
1271  pronargs < 0 ||
1272  ARR_HASNULL(arr) ||
1273  ARR_ELEMTYPE(arr) != OIDOID)
1274  elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
1275  Assert(pronargs >= procform->pronargs);
1276  proargtypes = (Oid *) ARR_DATA_PTR(arr);
1277  }
1278  }
1279 
1280  if (argnames != NIL)
1281  {
1282  /*
1283  * Call uses named or mixed notation
1284  *
1285  * Named or mixed notation can match a variadic function only if
1286  * expand_variadic is off; otherwise there is no way to match the
1287  * presumed-nameless parameters expanded from the variadic array.
1288  */
1289  if (OidIsValid(procform->provariadic) && expand_variadic)
1290  continue;
1291  va_elem_type = InvalidOid;
1292  variadic = false;
1293 
1294  /*
1295  * Check argument count.
1296  */
1297  Assert(nargs >= 0); /* -1 not supported with argnames */
1298 
1299  if (pronargs > nargs && expand_defaults)
1300  {
1301  /* Ignore if not enough default expressions */
1302  if (nargs + procform->pronargdefaults < pronargs)
1303  continue;
1304  use_defaults = true;
1305  }
1306  else
1307  use_defaults = false;
1308 
1309  /* Ignore if it doesn't match requested argument count */
1310  if (pronargs != nargs && !use_defaults)
1311  continue;
1312 
1313  /* Check for argument name match, generate positional mapping */
1314  if (!MatchNamedCall(proctup, nargs, argnames,
1315  include_out_arguments, pronargs,
1316  &argnumbers))
1317  continue;
1318 
1319  /* Named argument matching is always "special" */
1320  any_special = true;
1321  }
1322  else
1323  {
1324  /*
1325  * Call uses positional notation
1326  *
1327  * Check if function is variadic, and get variadic element type if
1328  * so. If expand_variadic is false, we should just ignore
1329  * variadic-ness.
1330  */
1331  if (pronargs <= nargs && expand_variadic)
1332  {
1333  va_elem_type = procform->provariadic;
1334  variadic = OidIsValid(va_elem_type);
1335  any_special |= variadic;
1336  }
1337  else
1338  {
1339  va_elem_type = InvalidOid;
1340  variadic = false;
1341  }
1342 
1343  /*
1344  * Check if function can match by using parameter defaults.
1345  */
1346  if (pronargs > nargs && expand_defaults)
1347  {
1348  /* Ignore if not enough default expressions */
1349  if (nargs + procform->pronargdefaults < pronargs)
1350  continue;
1351  use_defaults = true;
1352  any_special = true;
1353  }
1354  else
1355  use_defaults = false;
1356 
1357  /* Ignore if it doesn't match requested argument count */
1358  if (nargs >= 0 && pronargs != nargs && !variadic && !use_defaults)
1359  continue;
1360  }
1361 
1362  /*
1363  * We must compute the effective argument list so that we can easily
1364  * compare it to earlier results. We waste a palloc cycle if it gets
1365  * masked by an earlier result, but really that's a pretty infrequent
1366  * case so it's not worth worrying about.
1367  */
1368  effective_nargs = Max(pronargs, nargs);
1369  newResult = (FuncCandidateList)
1370  palloc(offsetof(struct _FuncCandidateList, args) +
1371  effective_nargs * sizeof(Oid));
1372  newResult->pathpos = pathpos;
1373  newResult->oid = procform->oid;
1374  newResult->nominalnargs = pronargs;
1375  newResult->nargs = effective_nargs;
1376  newResult->argnumbers = argnumbers;
1377  if (argnumbers)
1378  {
1379  /* Re-order the argument types into call's logical order */
1380  for (int j = 0; j < pronargs; j++)
1381  newResult->args[j] = proargtypes[argnumbers[j]];
1382  }
1383  else
1384  {
1385  /* Simple positional case, just copy proargtypes as-is */
1386  memcpy(newResult->args, proargtypes, pronargs * sizeof(Oid));
1387  }
1388  if (variadic)
1389  {
1390  newResult->nvargs = effective_nargs - pronargs + 1;
1391  /* Expand variadic argument into N copies of element type */
1392  for (int j = pronargs - 1; j < effective_nargs; j++)
1393  newResult->args[j] = va_elem_type;
1394  }
1395  else
1396  newResult->nvargs = 0;
1397  newResult->ndargs = use_defaults ? pronargs - nargs : 0;
1398 
1399  /*
1400  * Does it have the same arguments as something we already accepted?
1401  * If so, decide what to do to avoid returning duplicate argument
1402  * lists. We can skip this check for the single-namespace case if no
1403  * special (named, variadic or defaults) match has been made, since
1404  * then the unique index on pg_proc guarantees all the matches have
1405  * different argument lists.
1406  */
1407  if (resultList != NULL &&
1408  (any_special || !OidIsValid(namespaceId)))
1409  {
1410  /*
1411  * If we have an ordered list from SearchSysCacheList (the normal
1412  * case), then any conflicting proc must immediately adjoin this
1413  * one in the list, so we only need to look at the newest result
1414  * item. If we have an unordered list, we have to scan the whole
1415  * result list. Also, if either the current candidate or any
1416  * previous candidate is a special match, we can't assume that
1417  * conflicts are adjacent.
1418  *
1419  * We ignore defaulted arguments in deciding what is a match.
1420  */
1421  FuncCandidateList prevResult;
1422 
1423  if (catlist->ordered && !any_special)
1424  {
1425  /* ndargs must be 0 if !any_special */
1426  if (effective_nargs == resultList->nargs &&
1427  memcmp(newResult->args,
1428  resultList->args,
1429  effective_nargs * sizeof(Oid)) == 0)
1430  prevResult = resultList;
1431  else
1432  prevResult = NULL;
1433  }
1434  else
1435  {
1436  int cmp_nargs = newResult->nargs - newResult->ndargs;
1437 
1438  for (prevResult = resultList;
1439  prevResult;
1440  prevResult = prevResult->next)
1441  {
1442  if (cmp_nargs == prevResult->nargs - prevResult->ndargs &&
1443  memcmp(newResult->args,
1444  prevResult->args,
1445  cmp_nargs * sizeof(Oid)) == 0)
1446  break;
1447  }
1448  }
1449 
1450  if (prevResult)
1451  {
1452  /*
1453  * We have a match with a previous result. Decide which one
1454  * to keep, or mark it ambiguous if we can't decide. The
1455  * logic here is preference > 0 means prefer the old result,
1456  * preference < 0 means prefer the new, preference = 0 means
1457  * ambiguous.
1458  */
1459  int preference;
1460 
1461  if (pathpos != prevResult->pathpos)
1462  {
1463  /*
1464  * Prefer the one that's earlier in the search path.
1465  */
1466  preference = pathpos - prevResult->pathpos;
1467  }
1468  else if (variadic && prevResult->nvargs == 0)
1469  {
1470  /*
1471  * With variadic functions we could have, for example,
1472  * both foo(numeric) and foo(variadic numeric[]) in the
1473  * same namespace; if so we prefer the non-variadic match
1474  * on efficiency grounds.
1475  */
1476  preference = 1;
1477  }
1478  else if (!variadic && prevResult->nvargs > 0)
1479  {
1480  preference = -1;
1481  }
1482  else
1483  {
1484  /*----------
1485  * We can't decide. This can happen with, for example,
1486  * both foo(numeric, variadic numeric[]) and
1487  * foo(variadic numeric[]) in the same namespace, or
1488  * both foo(int) and foo (int, int default something)
1489  * in the same namespace, or both foo(a int, b text)
1490  * and foo(b text, a int) in the same namespace.
1491  *----------
1492  */
1493  preference = 0;
1494  }
1495 
1496  if (preference > 0)
1497  {
1498  /* keep previous result */
1499  pfree(newResult);
1500  continue;
1501  }
1502  else if (preference < 0)
1503  {
1504  /* remove previous result from the list */
1505  if (prevResult == resultList)
1506  resultList = prevResult->next;
1507  else
1508  {
1509  FuncCandidateList prevPrevResult;
1510 
1511  for (prevPrevResult = resultList;
1512  prevPrevResult;
1513  prevPrevResult = prevPrevResult->next)
1514  {
1515  if (prevResult == prevPrevResult->next)
1516  {
1517  prevPrevResult->next = prevResult->next;
1518  break;
1519  }
1520  }
1521  Assert(prevPrevResult); /* assert we found it */
1522  }
1523  pfree(prevResult);
1524  /* fall through to add newResult to list */
1525  }
1526  else
1527  {
1528  /* mark old result as ambiguous, discard new */
1529  prevResult->oid = InvalidOid;
1530  pfree(newResult);
1531  continue;
1532  }
1533  }
1534  }
1535 
1536  /*
1537  * Okay to add it to result list
1538  */
1539  newResult->next = resultList;
1540  resultList = newResult;
1541  }
1542 
1543  ReleaseSysCacheList(catlist);
1544 
1545  return resultList;
1546 }
#define ARR_NDIM(a)
Definition: array.h:290
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define ARR_DIMS(a)
Definition: array.h:294
#define ARR_HASNULL(a)
Definition: array.h:291
#define Max(x, y)
Definition: c.h:987
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
#define funcname
Definition: indent_codes.h:69
int j
Definition: isn.c:74
int i
Definition: isn.c:73
void pfree(void *pointer)
Definition: mcxt.c:1431
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition: namespace.c:3370
void DeconstructQualifiedName(const List *names, char **nspname_p, char **objname_p)
Definition: namespace.c:3286
static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, bool include_out_arguments, int pronargs, int **argnumbers)
Definition: namespace.c:1570
struct _FuncCandidateList * FuncCandidateList
#define NIL
Definition: pg_list.h:68
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
int16 pronargs
Definition: pg_proc.h:81
uintptr_t Datum
Definition: postgres.h:64
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
struct _FuncCandidateList * next
Definition: namespace.h:30
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:38
bool ordered
Definition: catcache.h:174
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
int n_members
Definition: catcache.h:176
HeapTupleData tuple
Definition: catcache.h:121
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:480
#define ReleaseSysCacheList(x)
Definition: syscache.h:129
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:122

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

Referenced by func_get_detail(), FunctionIsVisibleExt(), LookupFuncNameInternal(), regprocedurein(), regprocin(), and regprocout().

◆ FunctionIsVisible()

bool FunctionIsVisible ( Oid  funcid)

Definition at line 1681 of file namespace.c.

1682 {
1683  return FunctionIsVisibleExt(funcid, NULL);
1684 }
static bool FunctionIsVisibleExt(Oid funcid, bool *is_missing)
Definition: namespace.c:1693

References FunctionIsVisibleExt().

Referenced by format_procedure_extended().

◆ get_collation_oid()

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3956 of file namespace.c.

3957 {
3958  char *schemaname;
3959  char *collation_name;
3960  int32 dbencoding = GetDatabaseEncoding();
3961  Oid namespaceId;
3962  Oid colloid;
3963  ListCell *l;
3964 
3965  /* deconstruct the name list */
3966  DeconstructQualifiedName(collname, &schemaname, &collation_name);
3967 
3968  if (schemaname)
3969  {
3970  /* use exact schema given */
3971  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3972  if (missing_ok && !OidIsValid(namespaceId))
3973  return InvalidOid;
3974 
3975  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3976  if (OidIsValid(colloid))
3977  return colloid;
3978  }
3979  else
3980  {
3981  /* search for it in search path */
3983 
3984  foreach(l, activeSearchPath)
3985  {
3986  namespaceId = lfirst_oid(l);
3987 
3988  if (namespaceId == myTempNamespace)
3989  continue; /* do not look in temp namespace */
3990 
3991  colloid = lookup_collation(collation_name, namespaceId, dbencoding);
3992  if (OidIsValid(colloid))
3993  return colloid;
3994  }
3995  }
3996 
3997  /* Not found in path */
3998  if (!missing_ok)
3999  ereport(ERROR,
4000  (errcode(ERRCODE_UNDEFINED_OBJECT),
4001  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
4002  NameListToString(collname), GetDatabaseEncodingName())));
4003  return InvalidOid;
4004 }
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1274

References activeSearchPath, 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(), and regcollationin().

◆ get_conversion_oid()

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 4010 of file namespace.c.

4011 {
4012  char *schemaname;
4013  char *conversion_name;
4014  Oid namespaceId;
4015  Oid conoid = InvalidOid;
4016  ListCell *l;
4017 
4018  /* deconstruct the name list */
4019  DeconstructQualifiedName(conname, &schemaname, &conversion_name);
4020 
4021  if (schemaname)
4022  {
4023  /* use exact schema given */
4024  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
4025  if (missing_ok && !OidIsValid(namespaceId))
4026  conoid = InvalidOid;
4027  else
4028  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
4029  PointerGetDatum(conversion_name),
4030  ObjectIdGetDatum(namespaceId));
4031  }
4032  else
4033  {
4034  /* search for it in search path */
4036 
4037  foreach(l, activeSearchPath)
4038  {
4039  namespaceId = lfirst_oid(l);
4040 
4041  if (namespaceId == myTempNamespace)
4042  continue; /* do not look in temp namespace */
4043 
4044  conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
4045  PointerGetDatum(conversion_name),
4046  ObjectIdGetDatum(namespaceId));
4047  if (OidIsValid(conoid))
4048  return conoid;
4049  }
4050  }
4051 
4052  /* Not found in path */
4053  if (!OidIsValid(conoid) && !missing_ok)
4054  ereport(ERROR,
4055  (errcode(ERRCODE_UNDEFINED_OBJECT),
4056  errmsg("conversion \"%s\" does not exist",
4057  NameListToString(conname))));
4058  return conoid;
4059 }

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by get_object_address().

◆ get_namespace_oid()

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)

◆ get_statistics_object_oid()

Oid get_statistics_object_oid ( List names,
bool  missing_ok 
)

Definition at line 2560 of file namespace.c.

2561 {
2562  char *schemaname;
2563  char *stats_name;
2564  Oid namespaceId;
2565  Oid stats_oid = InvalidOid;
2566  ListCell *l;
2567 
2568  /* deconstruct the name list */
2569  DeconstructQualifiedName(names, &schemaname, &stats_name);
2570 
2571  if (schemaname)
2572  {
2573  /* use exact schema given */
2574  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2575  if (missing_ok && !OidIsValid(namespaceId))
2576  stats_oid = InvalidOid;
2577  else
2578  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2579  PointerGetDatum(stats_name),
2580  ObjectIdGetDatum(namespaceId));
2581  }
2582  else
2583  {
2584  /* search for it in search path */
2586 
2587  foreach(l, activeSearchPath)
2588  {
2589  namespaceId = lfirst_oid(l);
2590 
2591  if (namespaceId == myTempNamespace)
2592  continue; /* do not look in temp namespace */
2593  stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
2594  PointerGetDatum(stats_name),
2595  ObjectIdGetDatum(namespaceId));
2596  if (OidIsValid(stats_oid))
2597  break;
2598  }
2599  }
2600 
2601  if (!OidIsValid(stats_oid) && !missing_ok)
2602  ereport(ERROR,
2603  (errcode(ERRCODE_UNDEFINED_OBJECT),
2604  errmsg("statistics object \"%s\" does not exist",
2605  NameListToString(names))));
2606 
2607  return stats_oid;
2608 }

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by AlterStatistics(), and get_object_address().

◆ get_ts_config_oid()

Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 3137 of file namespace.c.

3138 {
3139  char *schemaname;
3140  char *config_name;
3141  Oid namespaceId;
3142  Oid cfgoid = InvalidOid;
3143  ListCell *l;
3144 
3145  /* deconstruct the name list */
3146  DeconstructQualifiedName(names, &schemaname, &config_name);
3147 
3148  if (schemaname)
3149  {
3150  /* use exact schema given */
3151  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3152  if (missing_ok && !OidIsValid(namespaceId))
3153  cfgoid = InvalidOid;
3154  else
3155  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
3156  PointerGetDatum(config_name),
3157  ObjectIdGetDatum(namespaceId));
3158  }
3159  else
3160  {
3161  /* search for it in search path */
3163 
3164  foreach(l, activeSearchPath)
3165  {
3166  namespaceId = lfirst_oid(l);
3167 
3168  if (namespaceId == myTempNamespace)
3169  continue; /* do not look in temp namespace */
3170 
3171  cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
3172  PointerGetDatum(config_name),
3173  ObjectIdGetDatum(namespaceId));
3174  if (OidIsValid(cfgoid))
3175  break;
3176  }
3177  }
3178 
3179  if (!OidIsValid(cfgoid) && !missing_ok)
3180  ereport(ERROR,
3181  (errcode(ERRCODE_UNDEFINED_OBJECT),
3182  errmsg("text search configuration \"%s\" does not exist",
3183  NameListToString(names))));
3184 
3185  return cfgoid;
3186 }

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by check_default_text_search_config(), DefineTSConfiguration(), get_object_address(), GetTSConfigTuple(), getTSCurrentConfig(), regconfigin(), and tsvector_update_trigger().

◆ get_ts_dict_oid()

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2846 of file namespace.c.

2847 {
2848  char *schemaname;
2849  char *dict_name;
2850  Oid namespaceId;
2851  Oid dictoid = InvalidOid;
2852  ListCell *l;
2853 
2854  /* deconstruct the name list */
2855  DeconstructQualifiedName(names, &schemaname, &dict_name);
2856 
2857  if (schemaname)
2858  {
2859  /* use exact schema given */
2860  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2861  if (missing_ok && !OidIsValid(namespaceId))
2862  dictoid = InvalidOid;
2863  else
2864  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2865  PointerGetDatum(dict_name),
2866  ObjectIdGetDatum(namespaceId));
2867  }
2868  else
2869  {
2870  /* search for it in search path */
2872 
2873  foreach(l, activeSearchPath)
2874  {
2875  namespaceId = lfirst_oid(l);
2876 
2877  if (namespaceId == myTempNamespace)
2878  continue; /* do not look in temp namespace */
2879 
2880  dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
2881  PointerGetDatum(dict_name),
2882  ObjectIdGetDatum(namespaceId));
2883  if (OidIsValid(dictoid))
2884  break;
2885  }
2886  }
2887 
2888  if (!OidIsValid(dictoid) && !missing_ok)
2889  ereport(ERROR,
2890  (errcode(ERRCODE_UNDEFINED_OBJECT),
2891  errmsg("text search dictionary \"%s\" does not exist",
2892  NameListToString(names))));
2893 
2894  return dictoid;
2895 }

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by AlterTSDictionary(), get_object_address(), MakeConfigurationMapping(), regdictionaryin(), and thesaurus_init().

◆ get_ts_parser_oid()

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2701 of file namespace.c.

2702 {
2703  char *schemaname;
2704  char *parser_name;
2705  Oid namespaceId;
2706  Oid prsoid = InvalidOid;
2707  ListCell *l;
2708 
2709  /* deconstruct the name list */
2710  DeconstructQualifiedName(names, &schemaname, &parser_name);
2711 
2712  if (schemaname)
2713  {
2714  /* use exact schema given */
2715  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
2716  if (missing_ok && !OidIsValid(namespaceId))
2717  prsoid = InvalidOid;
2718  else
2719  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2720  PointerGetDatum(parser_name),
2721  ObjectIdGetDatum(namespaceId));
2722  }
2723  else
2724  {
2725  /* search for it in search path */
2727 
2728  foreach(l, activeSearchPath)
2729  {
2730  namespaceId = lfirst_oid(l);
2731 
2732  if (namespaceId == myTempNamespace)
2733  continue; /* do not look in temp namespace */
2734 
2735  prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
2736  PointerGetDatum(parser_name),
2737  ObjectIdGetDatum(namespaceId));
2738  if (OidIsValid(prsoid))
2739  break;
2740  }
2741  }
2742 
2743  if (!OidIsValid(prsoid) && !missing_ok)
2744  ereport(ERROR,
2745  (errcode(ERRCODE_UNDEFINED_OBJECT),
2746  errmsg("text search parser \"%s\" does not exist",
2747  NameListToString(names))));
2748 
2749  return prsoid;
2750 }

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by DefineTSConfiguration(), get_object_address(), ts_parse_byname(), and ts_token_type_byname().

◆ get_ts_template_oid()

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2992 of file namespace.c.

2993 {
2994  char *schemaname;
2995  char *template_name;
2996  Oid namespaceId;
2997  Oid tmploid = InvalidOid;
2998  ListCell *l;
2999 
3000  /* deconstruct the name list */
3001  DeconstructQualifiedName(names, &schemaname, &template_name);
3002 
3003  if (schemaname)
3004  {
3005  /* use exact schema given */
3006  namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
3007  if (missing_ok && !OidIsValid(namespaceId))
3008  tmploid = InvalidOid;
3009  else
3010  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
3011  PointerGetDatum(template_name),
3012  ObjectIdGetDatum(namespaceId));
3013  }
3014  else
3015  {
3016  /* search for it in search path */
3018 
3019  foreach(l, activeSearchPath)
3020  {
3021  namespaceId = lfirst_oid(l);
3022 
3023  if (namespaceId == myTempNamespace)
3024  continue; /* do not look in temp namespace */
3025 
3026  tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
3027  PointerGetDatum(template_name),
3028  ObjectIdGetDatum(namespaceId));
3029  if (OidIsValid(tmploid))
3030  break;
3031  }
3032  }
3033 
3034  if (!OidIsValid(tmploid) && !missing_ok)
3035  ereport(ERROR,
3036  (errcode(ERRCODE_UNDEFINED_OBJECT),
3037  errmsg("text search template \"%s\" does not exist",
3038  NameListToString(names))));
3039 
3040  return tmploid;
3041 }

References activeSearchPath, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, InvalidOid, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), and recomputeNamespacePath().

Referenced by DefineTSDictionary(), and get_object_address().

◆ GetSearchPathMatcher()

SearchPathMatcher* GetSearchPathMatcher ( MemoryContext  context)

Definition at line 3837 of file namespace.c.

3838 {
3839  SearchPathMatcher *result;
3840  List *schemas;
3841  MemoryContext oldcxt;
3842 
3844 
3845  oldcxt = MemoryContextSwitchTo(context);
3846 
3847  result = (SearchPathMatcher *) palloc0(sizeof(SearchPathMatcher));
3848  schemas = list_copy(activeSearchPath);
3849  while (schemas && linitial_oid(schemas) != activeCreationNamespace)
3850  {
3851  if (linitial_oid(schemas) == myTempNamespace)
3852  result->addTemp = true;
3853  else
3854  {
3855  Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
3856  result->addCatalog = true;
3857  }
3858  schemas = list_delete_first(schemas);
3859  }
3860  result->schemas = schemas;
3861  result->generation = activePathGeneration;
3862 
3863  MemoryContextSwitchTo(oldcxt);
3864 
3865  return result;
3866 }
void * palloc0(Size size)
Definition: mcxt.c:1232
static uint64 activePathGeneration
Definition: namespace.c:145
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124

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

Referenced by CompleteCachedPlan(), and RevalidateCachedQuery().

◆ GetTempNamespaceBackendId()

int GetTempNamespaceBackendId ( Oid  namespaceId)

Definition at line 3751 of file namespace.c.

3752 {
3753  int result;
3754  char *nspname;
3755 
3756  /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3757  nspname = get_namespace_name(namespaceId);
3758  if (!nspname)
3759  return InvalidBackendId; /* no such namespace? */
3760  if (strncmp(nspname, "pg_temp_", 8) == 0)
3761  result = atoi(nspname + 8);
3762  else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
3763  result = atoi(nspname + 14);
3764  else
3765  result = InvalidBackendId;
3766  pfree(nspname);
3767  return result;
3768 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3321

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

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

◆ GetTempNamespaceState()

void GetTempNamespaceState ( Oid tempNamespaceId,
Oid tempToastNamespaceId 
)

Definition at line 3790 of file namespace.c.

3791 {
3792  /* Return namespace OIDs, or 0 if session has not created temp namespace */
3793  *tempNamespaceId = myTempNamespace;
3794  *tempToastNamespaceId = myTempToastNamespace;
3795 }

References myTempNamespace, and myTempToastNamespace.

Referenced by InitializeParallelDSM().

◆ GetTempToastNamespace()

Oid GetTempToastNamespace ( void  )

Definition at line 3776 of file namespace.c.

3777 {
3779  return myTempToastNamespace;
3780 }

References Assert(), myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

◆ InitializeSearchPath()

void InitializeSearchPath ( void  )

Definition at line 4718 of file namespace.c.

4719 {
4721  {
4722  /*
4723  * In bootstrap mode, the search path must be 'pg_catalog' so that
4724  * tables are created in the proper namespace; ignore the GUC setting.
4725  */
4726  MemoryContext oldcxt;
4727 
4729  baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
4730  MemoryContextSwitchTo(oldcxt);
4731  baseCreationNamespace = PG_CATALOG_NAMESPACE;
4732  baseTempCreationPending = false;
4733  baseSearchPathValid = true;
4738  activePathGeneration++; /* pro forma */
4739  }
4740  else
4741  {
4742  /* Make the context we'll keep search path cache hashtable in */
4744  "search_path processing cache",
4746 
4747  /*
4748  * In normal mode, arrange for a callback on any syscache invalidation
4749  * of pg_namespace or pg_authid rows. (Changing a role name may affect
4750  * the meaning of the special string $user.)
4751  */
4752  CacheRegisterSyscacheCallback(NAMESPACEOID,
4754  (Datum) 0);
4757  (Datum) 0);
4758  /* Force search path to be recomputed on next use */
4759  baseSearchPathValid = false;
4760  searchPathCacheValid = false;
4761  }
4762 }
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1517
MemoryContext TopMemoryContext
Definition: mcxt.c:141
#define AllocSetContextCreate
Definition: memutils.h:128
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:152
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:415
Oid GetUserId(void)
Definition: miscinit.c:511
static bool baseTempCreationPending
Definition: namespace.c:153
static Oid baseCreationNamespace
Definition: namespace.c:151
static MemoryContext SearchPathCacheContext
Definition: namespace.c:165
static Oid namespaceUser
Definition: namespace.c:155
static List * baseSearchPath
Definition: namespace.c:149
static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: namespace.c:4769
#define list_make1_oid(x1)
Definition: pg_list.h:242

References activeCreationNamespace, activePathGeneration, activeSearchPath, activeTempCreationPending, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, baseCreationNamespace, baseSearchPath, baseSearchPathValid, baseTempCreationPending, CacheRegisterSyscacheCallback(), GetUserId(), IsBootstrapProcessingMode, list_make1_oid, MemoryContextSwitchTo(), NamespaceCallback(), namespaceUser, SearchPathCacheContext, searchPathCacheValid, and TopMemoryContext.

Referenced by InitPostgres().

◆ isAnyTempNamespace()

bool isAnyTempNamespace ( Oid  namespaceId)

Definition at line 3672 of file namespace.c.

3673 {
3674  bool result;
3675  char *nspname;
3676 
3677  /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
3678  nspname = get_namespace_name(namespaceId);
3679  if (!nspname)
3680  return false; /* no such namespace? */
3681  result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
3682  (strncmp(nspname, "pg_toast_temp_", 14) == 0);
3683  pfree(nspname);
3684  return result;
3685 }

References get_namespace_name(), and pfree().

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

◆ isOtherTempNamespace()

bool isOtherTempNamespace ( Oid  namespaceId)

Definition at line 3695 of file namespace.c.

3696 {
3697  /* If it's my own temp namespace, say "false" */
3698  if (isTempOrTempToastNamespace(namespaceId))
3699  return false;
3700  /* Else, if it's any temp namespace, say "true" */
3701  return isAnyTempNamespace(namespaceId);
3702 }
bool isTempOrTempToastNamespace(Oid namespaceId)
Definition: namespace.c:3658

References isAnyTempNamespace(), and isTempOrTempToastNamespace().

Referenced by pg_is_other_temp_schema().

◆ isTempNamespace()

bool isTempNamespace ( Oid  namespaceId)

Definition at line 3634 of file namespace.c.

3635 {
3636  if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
3637  return true;
3638  return false;
3639 }

References myTempNamespace, and OidIsValid.

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

◆ isTempOrTempToastNamespace()

bool isTempOrTempToastNamespace ( Oid  namespaceId)

Definition at line 3658 of file namespace.c.

3659 {
3660  if (OidIsValid(myTempNamespace) &&
3661  (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
3662  return true;
3663  return false;
3664 }

References myTempNamespace, myTempToastNamespace, and OidIsValid.

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

◆ isTempToastNamespace()

bool isTempToastNamespace ( Oid  namespaceId)

Definition at line 3646 of file namespace.c.

3647 {
3648  if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
3649  return true;
3650  return false;
3651 }

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

◆ LookupCreationNamespace()

Oid LookupCreationNamespace ( const char *  nspname)

Definition at line 3413 of file namespace.c.

3414 {
3415  Oid namespaceId;
3416  AclResult aclresult;
3417 
3418  /* check for pg_temp alias */
3419  if (strcmp(nspname, "pg_temp") == 0)
3420  {
3421  /* Initialize temp namespace */
3422  AccessTempTableNamespace(false);
3423  return myTempNamespace;
3424  }
3425 
3426  namespaceId = get_namespace_oid(nspname, false);
3427 
3428  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
3429  if (aclresult != ACLCHECK_OK)
3430  aclcheck_error(aclresult, OBJECT_SCHEMA,
3431  nspname);
3432 
3433  return namespaceId;
3434 }
AclResult
Definition: acl.h:181
@ ACLCHECK_OK
Definition: acl.h:182
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2701
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3878
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition: namespace.c:3520
@ OBJECT_SCHEMA
Definition: parsenodes.h:2132
#define ACL_CREATE
Definition: parsenodes.h:85

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

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

◆ LookupExplicitNamespace()

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 3370 of file namespace.c.

3371 {
3372  Oid namespaceId;
3373  AclResult aclresult;
3374 
3375  /* check for pg_temp alias */
3376  if (strcmp(nspname, "pg_temp") == 0)
3377  {
3379  return myTempNamespace;
3380 
3381  /*
3382  * Since this is used only for looking up existing objects, there is
3383  * no point in trying to initialize the temp namespace here; and doing
3384  * so might create problems for some callers --- just fall through.
3385  */
3386  }
3387 
3388  namespaceId = get_namespace_oid(nspname, missing_ok);
3389  if (missing_ok && !OidIsValid(namespaceId))
3390  return InvalidOid;
3391 
3392  aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_USAGE);
3393  if (aclresult != ACLCHECK_OK)
3394  aclcheck_error(aclresult, OBJECT_SCHEMA,
3395  nspname);
3396  /* Schema search hook for this lookup */
3397  InvokeNamespaceSearchHook(namespaceId, true);
3398 
3399  return namespaceId;
3400 }
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation)
Definition: objectaccess.h:208
#define ACL_USAGE
Definition: parsenodes.h:84

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

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().

◆ LookupNamespaceNoError()

Oid LookupNamespaceNoError ( const char *  nspname)

Definition at line 3340 of file namespace.c.

3341 {
3342  /* check for pg_temp alias */
3343  if (strcmp(nspname, "pg_temp") == 0)
3344  {
3346  {
3348  return myTempNamespace;
3349  }
3350 
3351  /*
3352  * Since this is used only for looking up existing objects, there is
3353  * no point in trying to initialize the temp namespace here; and doing
3354  * so might create problems for some callers. Just report "not found".
3355  */
3356  return InvalidOid;
3357  }
3358 
3359  return get_namespace_oid(nspname, true);
3360 }

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

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

◆ makeRangeVarFromNameList()

RangeVar* makeRangeVarFromNameList ( const List names)

Definition at line 3539 of file namespace.c.

3540 {
3541  RangeVar *rel = makeRangeVar(NULL, NULL, -1);
3542 
3543  switch (list_length(names))
3544  {
3545  case 1:
3546  rel->relname = strVal(linitial(names));
3547  break;
3548  case 2:
3549  rel->schemaname = strVal(linitial(names));
3550  rel->relname = strVal(lsecond(names));
3551  break;
3552  case 3:
3553  rel->catalogname = strVal(linitial(names));
3554  rel->schemaname = strVal(lsecond(names));
3555  rel->relname = strVal(lthird(names));
3556  break;
3557  default:
3558  ereport(ERROR,
3559  (errcode(ERRCODE_SYNTAX_ERROR),
3560  errmsg("improper relation name (too many dotted names): %s",
3561  NameListToString(names))));
3562  break;
3563  }
3564 
3565  return rel;
3566 }
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition: makefuncs.c:425
char * relname
Definition: primnodes.h:82
char * catalogname
Definition: primnodes.h:76
char * schemaname
Definition: primnodes.h:79

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_multi_page_stats(), 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(), and text_regclass().

◆ NameListToQuotedString()

char* NameListToQuotedString ( const List names)

Definition at line 3613 of file namespace.c.

3614 {
3616  ListCell *l;
3617 
3618  initStringInfo(&string);
3619 
3620  foreach(l, names)
3621  {
3622  if (l != list_head(names))
3623  appendStringInfoChar(&string, '.');
3625  }
3626 
3627  return string.data;
3628 }
#define lfirst(lc)
Definition: pg_list.h:172
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
char string[11]
Definition: preproc-type.c:52
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11975
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

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

◆ NameListToString()

char* NameListToString ( const List names)

Definition at line 3579 of file namespace.c.

3580 {
3582  ListCell *l;
3583 
3584  initStringInfo(&string);
3585 
3586  foreach(l, names)
3587  {
3588  Node *name = (Node *) lfirst(l);
3589 
3590  if (l != list_head(names))
3591  appendStringInfoChar(&string, '.');
3592 
3593  if (IsA(name, String))
3594  appendStringInfoString(&string, strVal(name));
3595  else if (IsA(name, A_Star))
3596  appendStringInfoChar(&string, '*');
3597  else
3598  elog(ERROR, "unexpected node type in name list: %d",
3599  (int) nodeTag(name));
3600  }
3601 
3602  return string.data;
3603 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define nodeTag(nodeptr)
Definition: nodes.h:133
Definition: nodes.h:129
Definition: value.h:64
const char * name

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(), regclassin(), regcollationin(), regconfigin(), regdictionaryin(), RemoveObjects(), ResolveOpClass(), storeOperators(), storeProcedures(), transformColumnRef(), transformRangeTableSample(), ValidateJoinEstimator(), ValidateOperatorReference(), and ValidateRestrictionEstimator().

◆ OpclassIsVisible()

bool OpclassIsVisible ( Oid  opcid)

Definition at line 2139 of file namespace.c.

2140 {
2141  return OpclassIsVisibleExt(opcid, NULL);
2142 }
static bool OpclassIsVisibleExt(Oid opcid, bool *is_missing)
Definition: namespace.c:2151

References OpclassIsVisibleExt().

Referenced by get_opclass_name(), and getObjectDescription().

◆ OpclassnameGetOpcid()

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 2106 of file namespace.c.

2107 {
2108  Oid opcid;
2109  ListCell *l;
2110 
2112 
2113  foreach(l, activeSearchPath)
2114  {
2115  Oid namespaceId = lfirst_oid(l);
2116 
2117  if (namespaceId == myTempNamespace)
2118  continue; /* do not look in temp namespace */
2119 
2120  opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
2121  ObjectIdGetDatum(amid),
2122  PointerGetDatum(opcname),
2123  ObjectIdGetDatum(namespaceId));
2124  if (OidIsValid(opcid))
2125  return opcid;
2126  }
2127 
2128  /* Not found in path */
2129  return InvalidOid;
2130 }
#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3)
Definition: syscache.h:108

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

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

◆ OperatorIsVisible()

bool OperatorIsVisible ( Oid  oprid)

Definition at line 2034 of file namespace.c.

2035 {
2036  return OperatorIsVisibleExt(oprid, NULL);
2037 }
static bool OperatorIsVisibleExt(Oid oprid, bool *is_missing)
Definition: namespace.c:2046
Oid oprid(Operator op)
Definition: parse_oper.c:238

References OperatorIsVisibleExt(), and oprid().

Referenced by format_operator_extended().

◆ OpernameGetCandidates()

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

Definition at line 1873 of file namespace.c.

1874 {
1875  FuncCandidateList resultList = NULL;
1876  char *resultSpace = NULL;
1877  int nextResult = 0;
1878  char *schemaname;
1879  char *opername;
1880  Oid namespaceId;
1881  CatCList *catlist;
1882  int i;
1883 
1884  /* deconstruct the name list */
1885  DeconstructQualifiedName(names, &schemaname, &opername);
1886 
1887  if (schemaname)
1888  {
1889  /* use exact schema given */
1890  namespaceId = LookupExplicitNamespace(schemaname, missing_schema_ok);
1891  if (missing_schema_ok && !OidIsValid(namespaceId))
1892  return NULL;
1893  }
1894  else
1895  {
1896  /* flag to indicate we need namespace search */
1897  namespaceId = InvalidOid;
1899  }
1900 
1901  /* Search syscache by name only */
1902  catlist = SearchSysCacheList1(OPERNAMENSP, CStringGetDatum(opername));
1903 
1904  /*
1905  * In typical scenarios, most if not all of the operators found by the
1906  * catcache search will end up getting returned; and there can be quite a
1907  * few, for common operator names such as '=' or '+'. To reduce the time
1908  * spent in palloc, we allocate the result space as an array large enough
1909  * to hold all the operators. The original coding of this routine did a
1910  * separate palloc for each operator, but profiling revealed that the
1911  * pallocs used an unreasonably large fraction of parsing time.
1912  */
1913 #define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
1914  2 * sizeof(Oid))
1915 
1916  if (catlist->n_members > 0)
1917  resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
1918 
1919  for (i = 0; i < catlist->n_members; i++)
1920  {
1921  HeapTuple opertup = &catlist->members[i]->tuple;
1922  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1923  int pathpos = 0;
1924  FuncCandidateList newResult;
1925 
1926  /* Ignore operators of wrong kind, if specific kind requested */
1927  if (oprkind && operform->oprkind != oprkind)
1928  continue;
1929 
1930  if (OidIsValid(namespaceId))
1931  {
1932  /* Consider only opers in specified namespace */
1933  if (operform->oprnamespace != namespaceId)
1934  continue;
1935  /* No need to check args, they must all be different */
1936  }
1937  else
1938  {
1939  /*
1940  * Consider only opers that are in the search path and are not in
1941  * the temp namespace.
1942  */
1943  ListCell *nsp;
1944 
1945  foreach(nsp, activeSearchPath)
1946  {
1947  if (operform->oprnamespace == lfirst_oid(nsp) &&
1948  operform->oprnamespace != myTempNamespace)
1949  break;
1950  pathpos++;
1951  }
1952  if (nsp == NULL)
1953  continue; /* oper is not in search path */
1954 
1955  /*
1956  * Okay, it's in the search path, but does it have the same
1957  * arguments as something we already accepted? If so, keep only
1958  * the one that appears earlier in the search path.
1959  *
1960  * If we have an ordered list from SearchSysCacheList (the normal
1961  * case), then any conflicting oper must immediately adjoin this
1962  * one in the list, so we only need to look at the newest result
1963  * item. If we have an unordered list, we have to scan the whole
1964  * result list.
1965  */
1966  if (resultList)
1967  {
1968  FuncCandidateList prevResult;
1969 
1970  if (catlist->ordered)
1971  {
1972  if (operform->oprleft == resultList->args[0] &&
1973  operform->oprright == resultList->args[1])
1974  prevResult = resultList;
1975  else
1976  prevResult = NULL;
1977  }
1978  else
1979  {
1980  for (prevResult = resultList;
1981  prevResult;
1982  prevResult = prevResult->next)
1983  {
1984  if (operform->oprleft == prevResult->args[0] &&
1985  operform->oprright == prevResult->args[1])
1986  break;
1987  }
1988  }
1989  if (prevResult)
1990  {
1991  /* We have a match with a previous result */
1992  Assert(pathpos != prevResult->pathpos);
1993  if (pathpos > prevResult->pathpos)
1994  continue; /* keep previous result */
1995  /* replace previous result */
1996  prevResult->pathpos = pathpos;
1997  prevResult->oid = operform->oid;
1998  continue; /* args are same, of course */
1999  }
2000  }
2001  }
2002 
2003  /*
2004  * Okay to add it to result list
2005  */
2006  newResult = (FuncCandidateList) (resultSpace + nextResult);
2007  nextResult += SPACE_PER_OP;
2008 
2009  newResult->pathpos = pathpos;
2010  newResult->oid = operform->oid;
2011  newResult->nominalnargs = 2;
2012  newResult->nargs = 2;
2013  newResult->nvargs = 0;
2014  newResult->ndargs = 0;
2015  newResult->argnumbers = NULL;
2016  newResult->args[0] = operform->oprleft;
2017  newResult->args[1] = operform->oprright;
2018  newResult->next = resultList;
2019  resultList = newResult;
2020  }
2021 
2022  ReleaseSysCacheList(catlist);
2023 
2024  return resultList;
2025 }
#define SPACE_PER_OP
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83

References activeSearchPath, _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, catclist::ordered, palloc(), _FuncCandidateList::pathpos, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, SPACE_PER_OP, and catctup::tuple.

Referenced by left_oper(), oper(), regoperin(), and regoperout().

◆ OpernameGetOprid()

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

Definition at line 1770 of file namespace.c.

1771 {
1772  char *schemaname;
1773  char *opername;
1774  CatCList *catlist;
1775  ListCell *l;
1776 
1777  /* deconstruct the name list */
1778  DeconstructQualifiedName(names, &schemaname, &opername);
1779 
1780  if (schemaname)
1781  {
1782  /* search only in exact schema given */
1783  Oid namespaceId;
1784 
1785  namespaceId = LookupExplicitNamespace(schemaname, true);
1786  if (OidIsValid(namespaceId))
1787  {
1788  HeapTuple opertup;
1789 
1790  opertup = SearchSysCache4(OPERNAMENSP,
1791  CStringGetDatum(opername),
1792  ObjectIdGetDatum(oprleft),
1793  ObjectIdGetDatum(oprright),
1794  ObjectIdGetDatum(namespaceId));
1795  if (HeapTupleIsValid(opertup))
1796  {
1797  Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup);
1798  Oid result = operclass->oid;
1799 
1800  ReleaseSysCache(opertup);
1801  return result;
1802  }
1803  }
1804 
1805  return InvalidOid;
1806  }
1807 
1808  /* Search syscache by name and argument types */
1809  catlist = SearchSysCacheList3(OPERNAMENSP,
1810  CStringGetDatum(opername),
1811  ObjectIdGetDatum(oprleft),
1812  ObjectIdGetDatum(oprright));
1813 
1814  if (catlist->n_members == 0)
1815  {
1816  /* no hope, fall out early */
1817  ReleaseSysCacheList(catlist);
1818  return InvalidOid;
1819  }
1820 
1821  /*
1822  * We have to find the list member that is first in the search path, if
1823  * there's more than one. This doubly-nested loop looks ugly, but in
1824  * practice there should usually be few catlist members.
1825  */
1827 
1828  foreach(l, activeSearchPath)
1829  {
1830  Oid namespaceId = lfirst_oid(l);
1831  int i;
1832 
1833  if (namespaceId == myTempNamespace)
1834  continue; /* do not look in temp namespace */
1835 
1836  for (i = 0; i < catlist->n_members; i++)
1837  {
1838  HeapTuple opertup = &catlist->members[i]->tuple;
1839  Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
1840 
1841  if (operform->oprnamespace == namespaceId)
1842  {
1843  Oid result = operform->oid;
1844 
1845  ReleaseSysCacheList(catlist);
1846  return result;
1847  }
1848  }
1849  }
1850 
1851  ReleaseSysCacheList(catlist);
1852  return InvalidOid;
1853 }
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:267
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:252
#define SearchSysCacheList3(cacheId, key1, key2, key3)
Definition: syscache.h:126

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

Referenced by binary_oper_exact(), left_oper(), LookupOperName(), OperatorIsVisibleExt(), and regoperatorin().

◆ OpfamilyIsVisible()

bool OpfamilyIsVisible ( Oid  opfid)

Definition at line 2241 of file namespace.c.

2242 {
2243  return OpfamilyIsVisibleExt(opfid, NULL);
2244 }
static bool OpfamilyIsVisibleExt(Oid opfid, bool *is_missing)
Definition: namespace.c:2253

References OpfamilyIsVisibleExt().

Referenced by getOpFamilyDescription().

◆ OpfamilynameGetOpfid()

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 2208 of file namespace.c.

2209 {
2210  Oid opfid;
2211  ListCell *l;
2212 
2214 
2215  foreach(l, activeSearchPath)
2216  {
2217  Oid namespaceId = lfirst_oid(l);
2218 
2219  if (namespaceId == myTempNamespace)
2220  continue; /* do not look in temp namespace */
2221 
2222  opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
2223  ObjectIdGetDatum(amid),
2224  PointerGetDatum(opfname),
2225  ObjectIdGetDatum(namespaceId));
2226  if (OidIsValid(opfid))
2227  return opfid;
2228  }
2229 
2230  /* Not found in path */
2231  return InvalidOid;
2232 }

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

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisibleExt().

◆ QualifiedNameGetCreationNamespace()

Oid QualifiedNameGetCreationNamespace ( const List names,
char **  objname_p 
)

Definition at line 3472 of file namespace.c.

3473 {
3474  char *schemaname;
3475  Oid namespaceId;
3476 
3477  /* deconstruct the name list */
3478  DeconstructQualifiedName(names, &schemaname, objname_p);
3479 
3480  if (schemaname)
3481  {
3482  /* check for pg_temp alias */
3483  if (strcmp(schemaname, "pg_temp") == 0)
3484  {
3485  /* Initialize temp namespace */
3486  AccessTempTableNamespace(false);
3487  return myTempNamespace;
3488  }
3489  /* use exact schema given */
3490  namespaceId = get_namespace_oid(schemaname, false);
3491  /* we do not check for USAGE rights here! */
3492  }
3493  else
3494  {
3495  /* use the default creation namespace */
3498  {
3499  /* Need to initialize temp namespace */
3501  return myTempNamespace;
3502  }
3503  namespaceId = activeCreationNamespace;
3504  if (!OidIsValid(namespaceId))
3505  ereport(ERROR,
3506  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3507  errmsg("no schema has been selected to create in")));
3508  }
3509 
3510  return namespaceId;
3511 }

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().

◆ RangeVarAdjustRelationPersistence()

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 831 of file namespace.c.

832 {
833  switch (newRelation->relpersistence)
834  {
835  case RELPERSISTENCE_TEMP:
837  {
839  ereport(ERROR,
840  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
841  errmsg("cannot create relations in temporary schemas of other sessions")));
842  else
843  ereport(ERROR,
844  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
845  errmsg("cannot create temporary relation in non-temporary schema")));
846  }
847  break;
848  case RELPERSISTENCE_PERMANENT:
850  newRelation->relpersistence = RELPERSISTENCE_TEMP;
851  else if (isAnyTempNamespace(nspid))
852  ereport(ERROR,
853  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
854  errmsg("cannot create relations in temporary schemas of other sessions")));
855  break;
856  default:
858  ereport(ERROR,
859  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
860  errmsg("only temporary relations may be created in temporary schemas")));
861  }
862 }
int nspid
char relpersistence
Definition: primnodes.h:88

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

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

◆ RangeVarGetAndCheckCreationNamespace()

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

Definition at line 724 of file namespace.c.

727 {
728  uint64 inval_count;
729  Oid relid;
730  Oid oldrelid = InvalidOid;
731  Oid nspid;
732  Oid oldnspid = InvalidOid;
733  bool retry = false;
734 
735  /*
736  * We check the catalog name and then ignore it.
737  */
738  if (relation->catalogname)
739  {
740  if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
741  ereport(ERROR,
742  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
743  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
744  relation->catalogname, relation->schemaname,
745  relation->relname)));
746  }
747 
748  /*
749  * As in RangeVarGetRelidExtended(), we guard against concurrent DDL
750  * operations by tracking whether any invalidation messages are processed
751  * while we're doing the name lookups and acquiring locks. See comments
752  * in that function for a more detailed explanation of this logic.
753  */
754  for (;;)
755  {
756  AclResult aclresult;
757 
758  inval_count = SharedInvalidMessageCounter;
759 
760  /* Look up creation namespace and check for existing relation. */
763  if (existing_relation_id != NULL)
764  relid = get_relname_relid(relation->relname, nspid);
765  else
766  relid = InvalidOid;
767 
768  /*
769  * In bootstrap processing mode, we don't bother with permissions or
770  * locking. Permissions might not be working yet, and locking is
771  * unnecessary.
772  */
774  break;
775 
776  /* Check namespace permissions. */
777  aclresult = object_aclcheck(NamespaceRelationId, nspid, GetUserId(), ACL_CREATE);
778  if (aclresult != ACLCHECK_OK)
779  aclcheck_error(aclresult, OBJECT_SCHEMA,
781 
782  if (retry)
783  {
784  /* If nothing changed, we're done. */
785  if (relid == oldrelid && nspid == oldnspid)
786  break;
787  /* If creation namespace has changed, give up old lock. */
788  if (nspid != oldnspid)
789  UnlockDatabaseObject(NamespaceRelationId, oldnspid, 0,
791  /* If name points to something different, give up old lock. */
792  if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock)
793  UnlockRelationOid(oldrelid, lockmode);
794  }
795 
796  /* Lock namespace. */
797  if (nspid != oldnspid)
798  LockDatabaseObject(NamespaceRelationId, nspid, 0, AccessShareLock);
799 
800  /* Lock relation, if required if and we have permission. */
801  if (lockmode != NoLock && OidIsValid(relid))
802  {
803  if (!object_ownercheck(RelationRelationId, relid, GetUserId()))
805  relation->relname);
806  if (relid != oldrelid)
807  LockRelationOid(relid, lockmode);
808  }
809 
810  /* If no invalidation message were processed, we're done! */
811  if (inval_count == SharedInvalidMessageCounter)
812  break;
813 
814  /* Something may have changed, so recheck our work. */
815  retry = true;
816  oldrelid = relid;
817  oldnspid = nspid;
818  }
819 
821  if (existing_relation_id != NULL)
822  *existing_relation_id = relid;
823  return nspid;
824 }
@ ACLCHECK_NOT_OWNER
Definition: acl.h:184
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:4132
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:228
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1005
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:109
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1026
#define NoLock
Definition: lockdefs.h:34
#define AccessShareLock
Definition: lockdefs.h:36
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1980
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1862
void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
Definition: namespace.c:831
Oid RangeVarGetCreationNamespace(const RangeVar *newRelation)
Definition: namespace.c:639
ObjectType get_relkind_objtype(char relkind)
uint64 SharedInvalidMessageCounter
Definition: sinval.c:26

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, nspid, object_aclcheck(), object_ownercheck(), OBJECT_SCHEMA, OidIsValid, RangeVarAdjustRelationPersistence(), RangeVarGetCreationNamespace(), RangeVar::relname, RangeVar::schemaname, SharedInvalidMessageCounter, UnlockDatabaseObject(), and UnlockRelationOid().

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

◆ RangeVarGetCreationNamespace()

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation)

Definition at line 639 of file namespace.c.

640 {
641  Oid namespaceId;
642 
643  /*
644  * We check the catalog name and then ignore it.
645  */
646  if (newRelation->catalogname)
647  {
648  if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
649  ereport(ERROR,
650  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
651  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
652  newRelation->catalogname, newRelation->schemaname,
653  newRelation->relname)));
654  }
655 
656  if (newRelation->schemaname)
657  {
658  /* check for pg_temp alias */
659  if (strcmp(newRelation->schemaname, "pg_temp") == 0)
660  {
661  /* Initialize temp namespace */
663  return myTempNamespace;
664  }
665  /* use exact schema given */
666  namespaceId = get_namespace_oid(newRelation->schemaname, false);
667  /* we do not check for USAGE rights here! */
668  }
669  else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
670  {
671  /* Initialize temp namespace */
673  return myTempNamespace;
674  }
675  else
676  {
677  /* use the default creation namespace */
680  {
681  /* Need to initialize temp namespace */
683  return myTempNamespace;
684  }
685  namespaceId = activeCreationNamespace;
686  if (!OidIsValid(namespaceId))
687  ereport(ERROR,
688  (errcode(ERRCODE_UNDEFINED_SCHEMA),
689  errmsg("no schema has been selected to create in")));
690  }
691 
692  /* Note: callers will check for CREATE rights when appropriate */
693 
694  return namespaceId;
695 }

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().

◆ RangeVarGetRelidExtended()

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

Definition at line 426 of file namespace.c.

429 {
430  uint64 inval_count;
431  Oid relId;
432  Oid oldRelId = InvalidOid;
433  bool retry = false;
434  bool missing_ok = (flags & RVR_MISSING_OK) != 0;
435 
436  /* verify that flags do no conflict */
437  Assert(!((flags & RVR_NOWAIT) && (flags & RVR_SKIP_LOCKED)));
438 
439  /*
440  * We check the catalog name and then ignore it.
441  */
442  if (relation->catalogname)
443  {
444  if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
445  ereport(ERROR,
446  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
447  errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
448  relation->catalogname, relation->schemaname,
449  relation->relname)));
450  }
451 
452  /*
453  * DDL operations can change the results of a name lookup. Since all such
454  * operations will generate invalidation messages, we keep track of
455  * whether any such messages show up while we're performing the operation,
456  * and retry until either (1) no more invalidation messages show up or (2)
457  * the answer doesn't change.
458  *
459  * But if lockmode = NoLock, then we assume that either the caller is OK
460  * with the answer changing under them, or that they already hold some
461  * appropriate lock, and therefore return the first answer we get without
462  * checking for invalidation messages. Also, if the requested lock is
463  * already held, LockRelationOid will not AcceptInvalidationMessages, so
464  * we may fail to notice a change. We could protect against that case by
465  * calling AcceptInvalidationMessages() before beginning this loop, but
466  * that would add a significant amount overhead, so for now we don't.
467  */
468  for (;;)
469  {
470  /*
471  * Remember this value, so that, after looking up the relation name
472  * and locking its OID, we can check whether any invalidation messages
473  * have been processed that might require a do-over.
474  */
475  inval_count = SharedInvalidMessageCounter;
476 
477  /*
478  * Some non-default relpersistence value may have been specified. The
479  * parser never generates such a RangeVar in simple DML, but it can
480  * happen in contexts such as "CREATE TEMP TABLE foo (f1 int PRIMARY
481  * KEY)". Such a command will generate an added CREATE INDEX
482  * operation, which must be careful to find the temp table, even when
483  * pg_temp is not first in the search path.
484  */
485  if (relation->relpersistence == RELPERSISTENCE_TEMP)
486  {
488  relId = InvalidOid; /* this probably can't happen? */
489  else
490  {
491  if (relation->schemaname)
492  {
493  Oid namespaceId;
494 
495  namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
496 
497  /*
498  * For missing_ok, allow a non-existent schema name to
499  * return InvalidOid.
500  */
501  if (namespaceId != myTempNamespace)
502  ereport(ERROR,
503  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
504  errmsg("temporary tables cannot specify a schema name")));
505  }
506 
507  relId = get_relname_relid(relation->relname, myTempNamespace);
508  }
509  }
510  else if (relation->schemaname)
511  {
512  Oid namespaceId;
513 
514  /* use exact schema given */
515  namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
516  if (missing_ok && !OidIsValid(namespaceId))
517  relId = InvalidOid;
518  else
519  relId = get_relname_relid(relation->relname, namespaceId);
520  }
521  else
522  {
523  /* search the namespace path */
524  relId = RelnameGetRelid(relation->relname);
525  }
526 
527  /*
528  * Invoke caller-supplied callback, if any.
529  *
530  * This callback is a good place to check permissions: we haven't
531  * taken the table lock yet (and it's really best to check permissions
532  * before locking anything!), but we've gotten far enough to know what
533  * OID we think we should lock. Of course, concurrent DDL might
534  * change things while we're waiting for the lock, but in that case
535  * the callback will be invoked again for the new OID.
536  */
537  if (callback)
538  callback(relation, relId, oldRelId, callback_arg);
539 
540  /*
541  * If no lock requested, we assume the caller knows what they're
542  * doing. They should have already acquired a heavyweight lock on
543  * this relation earlier in the processing of this same statement, so
544  * it wouldn't be appropriate to AcceptInvalidationMessages() here, as
545  * that might pull the rug out from under them.
546  */
547  if (lockmode == NoLock)
548  break;
549 
550  /*
551  * If, upon retry, we get back the same OID we did last time, then the
552  * invalidation messages we processed did not change the final answer.
553  * So we're done.
554  *
555  * If we got a different OID, we've locked the relation that used to
556  * have this name rather than the one that does now. So release the
557  * lock.
558  */
559  if (retry)
560  {
561  if (relId == oldRelId)
562  break;
563  if (OidIsValid(oldRelId))
564  UnlockRelationOid(oldRelId, lockmode);
565  }
566 
567  /*
568  * Lock relation. This will also accept any pending invalidation
569  * messages. If we got back InvalidOid, indicating not found, then
570  * there's nothing to lock, but we accept invalidation messages
571  * anyway, to flush any negative catcache entries that may be
572  * lingering.
573  */
574  if (!OidIsValid(relId))
576  else if (!(flags & (RVR_NOWAIT | RVR_SKIP_LOCKED)))
577  LockRelationOid(relId, lockmode);
578  else if (!ConditionalLockRelationOid(relId, lockmode))
579  {
580  int elevel = (flags & RVR_SKIP_LOCKED) ? DEBUG1 : ERROR;
581 
582  if (relation->schemaname)
583  ereport(elevel,
584  (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
585  errmsg("could not obtain lock on relation \"%s.%s\"",
586  relation->schemaname, relation->relname)));
587  else
588  ereport(elevel,
589  (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
590  errmsg("could not obtain lock on relation \"%s\"",
591  relation->relname)));
592 
593  return InvalidOid;
594  }
595 
596  /*
597  * If no invalidation message were processed, we're done!
598  */
599  if (inval_count == SharedInvalidMessageCounter)
600  break;
601 
602  /*
603  * Something may have changed. Let's repeat the name lookup, to make
604  * sure this name still references the same relation it did
605  * previously.
606  */
607  retry = true;
608  oldRelId = relId;
609  }
610 
611  if (!OidIsValid(relId))
612  {
613  int elevel = missing_ok ? DEBUG1 : ERROR;
614 
615  if (relation->schemaname)
616  ereport(elevel,
618  errmsg("relation \"%s.%s\" does not exist",
619  relation->schemaname, relation->relname)));
620  else
621  ereport(elevel,
623  errmsg("relation \"%s\" does not exist",
624  relation->relname)));
625  }
626  return relId;
627 }
#define DEBUG1
Definition: elog.h:30
void AcceptInvalidationMessages(void)
Definition: inval.c:807
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:152
Oid RelnameGetRelid(const char *relname)
Definition: namespace.c:870
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:78
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46

References AcceptInvalidationMessages(), Assert(), callback(), RangeVar::catalogname, ConditionalLockRelationOid(), DEBUG1, ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, get_database_name(), get_relname_relid(), InvalidOid, LockRelationOid(), LookupExplicitNamespace(), MyDatabaseId, myTempNamespace, NoLock, OidIsValid, RangeVar::relname, RelnameGetRelid(), RangeVar::relpersistence, RVR_MISSING_OK, RVR_NOWAIT, RVR_SKIP_LOCKED, RangeVar::schemaname, SharedInvalidMessageCounter, and UnlockRelationOid().

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

◆ RelationIsVisible()

bool RelationIsVisible ( Oid  relid)

Definition at line 898 of file namespace.c.

899 {
900  return RelationIsVisibleExt(relid, NULL);
901 }
static bool RelationIsVisibleExt(Oid relid, bool *is_missing)
Definition: namespace.c:910

References RelationIsVisibleExt().

Referenced by generate_relation_name(), getRelationDescription(), and regclassout().

◆ RelnameGetRelid()

Oid RelnameGetRelid ( const char *  relname)

Definition at line 870 of file namespace.c.

871 {
872  Oid relid;
873  ListCell *l;
874 
876 
877  foreach(l, activeSearchPath)
878  {
879  Oid namespaceId = lfirst_oid(l);
880 
881  relid = get_relname_relid(relname, namespaceId);
882  if (OidIsValid(relid))
883  return relid;
884  }
885 
886  /* Not found in path */
887  return InvalidOid;
888 }
NameData relname
Definition: pg_class.h:38

References activeSearchPath, get_relname_relid(), InvalidOid, lfirst_oid, OidIsValid, recomputeNamespacePath(), and relname.

Referenced by plpgsql_parse_cwordtype(), plpgsql_parse_wordrowtype(), and RangeVarGetRelidExtended().

◆ ResetTempTableNamespace()

void ResetTempTableNamespace ( void  )

Definition at line 4629 of file namespace.c.

4630 {
4633 }
static void RemoveTempRelations(Oid tempNamespaceId)
Definition: namespace.c:4583

References myTempNamespace, OidIsValid, and RemoveTempRelations().

Referenced by DiscardAll(), and DiscardCommand().

◆ SearchPathMatchesCurrentEnvironment()

bool SearchPathMatchesCurrentEnvironment ( SearchPathMatcher path)

Definition at line 3896 of file namespace.c.

3897 {
3898  ListCell *lc,
3899  *lcp;
3900 
3902 
3903  /* Quick out if already known equal to active path. */
3904  if (path->generation == activePathGeneration)
3905  return true;
3906 
3907  /* We scan down the activeSearchPath to see if it matches the input. */
3909 
3910  /* If path->addTemp, first item should be my temp namespace. */
3911  if (path->addTemp)
3912  {
3913  if (lc && lfirst_oid(lc) == myTempNamespace)
3914  lc = lnext(activeSearchPath, lc);
3915  else
3916  return false;
3917  }
3918  /* If path->addCatalog, next item should be pg_catalog. */
3919  if (path->addCatalog)
3920  {
3921  if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
3922  lc = lnext(activeSearchPath, lc);
3923  else
3924  return false;
3925  }
3926  /* We should now be looking at the activeCreationNamespace. */
3927  if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
3928  return false;
3929  /* The remainder of activeSearchPath should match path->schemas. */
3930  foreach(lcp, path->schemas)
3931  {
3932  if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
3933  lc = lnext(activeSearchPath, lc);
3934  else
3935  return false;
3936  }
3937  if (lc)
3938  return false;
3939 
3940  /*
3941  * Update path->generation so that future tests will return quickly, so
3942  * long as the active search path doesn't change.
3943  */
3945 
3946  return true;
3947 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343

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

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

◆ SetTempNamespaceState()

void SetTempNamespaceState ( Oid  tempNamespaceId,
Oid  tempToastNamespaceId 
)

Definition at line 3806 of file namespace.c.

3807 {
3808  /* Worker should not have created its own namespaces ... */
3812 
3813  /* Assign same namespace OIDs that leader has */
3814  myTempNamespace = tempNamespaceId;
3815  myTempToastNamespace = tempToastNamespaceId;
3816 
3817  /*
3818  * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
3819  * Even if the namespace is new so far as the leader is concerned, it's
3820  * not new to the worker, and we certainly wouldn't want the worker trying
3821  * to destroy it.
3822  */
3823 
3824  baseSearchPathValid = false; /* may need to rebuild list */
3825  searchPathCacheValid = false;
3826 }

References Assert(), baseSearchPathValid, InvalidOid, InvalidSubTransactionId, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, and searchPathCacheValid.

Referenced by ParallelWorkerMain().

◆ StatisticsObjIsVisible()

bool StatisticsObjIsVisible ( Oid  stxid)

Definition at line 2617 of file namespace.c.

2618 {
2619  return StatisticsObjIsVisibleExt(stxid, NULL);
2620 }
static bool StatisticsObjIsVisibleExt(Oid stxid, bool *is_missing)
Definition: namespace.c:2629

References StatisticsObjIsVisibleExt().

Referenced by getObjectDescription().

◆ TSConfigIsVisible()

bool TSConfigIsVisible ( Oid  cfgid)

Definition at line 3195 of file namespace.c.

3196 {
3197  return TSConfigIsVisibleExt(cfgid, NULL);
3198 }
static bool TSConfigIsVisibleExt(Oid cfgid, bool *is_missing)
Definition: namespace.c:3207

References TSConfigIsVisibleExt().

Referenced by getObjectDescription(), and regconfigout().

◆ TSDictionaryIsVisible()

bool TSDictionaryIsVisible ( Oid  dictId)

Definition at line 2904 of file namespace.c.

2905 {
2906  return TSDictionaryIsVisibleExt(dictId, NULL);
2907 }
static bool TSDictionaryIsVisibleExt(Oid dictId, bool *is_missing)
Definition: namespace.c:2916

References TSDictionaryIsVisibleExt().

Referenced by getObjectDescription(), and regdictionaryout().

◆ TSParserIsVisible()

bool TSParserIsVisible ( Oid  prsId)

Definition at line 2759 of file namespace.c.

2760 {
2761  return TSParserIsVisibleExt(prsId, NULL);
2762 }
static bool TSParserIsVisibleExt(Oid prsId, bool *is_missing)
Definition: namespace.c:2771

References TSParserIsVisibleExt().

Referenced by getObjectDescription().

◆ TSTemplateIsVisible()

bool TSTemplateIsVisible ( Oid  tmplId)

Definition at line 3050 of file namespace.c.

3051 {
3052  return TSTemplateIsVisibleExt(tmplId, NULL);
3053 }
static bool TSTemplateIsVisibleExt(Oid tmplId, bool *is_missing)
Definition: namespace.c:3062

References TSTemplateIsVisibleExt().

Referenced by getObjectDescription().

◆ TypeIsVisible()

bool TypeIsVisible ( Oid  typid)

Definition at line 1025 of file namespace.c.

1026 {
1027  return TypeIsVisibleExt(typid, NULL);
1028 }
static bool TypeIsVisibleExt(Oid typid, bool *is_missing)
Definition: namespace.c:1037

References TypeIsVisibleExt().

Referenced by format_type_extended().

◆ TypenameGetTypid()

Oid TypenameGetTypid ( const char *  typname)

Definition at line 980 of file namespace.c.

981 {
982  return TypenameGetTypidExtended(typname, true);
983 }
Oid TypenameGetTypidExtended(const char *typname, bool temp_ok)
Definition: namespace.c:993
NameData typname
Definition: pg_type.h:41

References TypenameGetTypidExtended(), and typname.

◆ TypenameGetTypidExtended()

Oid TypenameGetTypidExtended ( const char *  typname,
bool  temp_ok 
)

Definition at line 993 of file namespace.c.

994 {
995  Oid typid;
996  ListCell *l;
997 
999 
1000  foreach(l, activeSearchPath)
1001  {
1002  Oid namespaceId = lfirst_oid(l);
1003 
1004  if (!temp_ok && namespaceId == myTempNamespace)
1005  continue; /* do not look in temp namespace */
1006 
1007  typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
1009  ObjectIdGetDatum(namespaceId));
1010  if (OidIsValid(typid))
1011  return typid;
1012  }
1013 
1014  /* Not found in path */
1015  return InvalidOid;
1016 }

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

Referenced by LookupTypeNameExtended(), and TypenameGetTypid().

Variable Documentation

◆ namespace_search_path

PGDLLIMPORT char* namespace_search_path
extern

Definition at line 211 of file namespace.c.

Referenced by CreateSchemaCommand(), and recomputeNamespacePath().