#include "postgres.h"
#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/dependency.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_conversion_fn.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_ts_parser.h"
#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "funcapi.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_func.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/sinval.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/catcache.h"
#include "utils/guc.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/syscache.h"
Go to the source code of this file.
#define SPACE_PER_OP MAXALIGN(sizeof(struct _FuncCandidateList) + sizeof(Oid)) |
Referenced by OpernameGetCandidates().
void assign_search_path | ( | const char * | newval, | |
void * | extra | |||
) |
Definition at line 3871 of file namespace.c.
References baseSearchPathValid.
{ /* * We mark the path as needing recomputation, but don't do anything until * it's needed. This avoids trying to do database access during GUC * initialization, or outside a transaction. */ baseSearchPathValid = false; }
void AtEOSubXact_Namespace | ( | bool | isCommit, | |
SubTransactionId | mySubid, | |||
SubTransactionId | parentSubid | |||
) |
Definition at line 3725 of file namespace.c.
References activeCreationNamespace, activeTempCreationPending, baseCreationNamespace, baseSearchPathValid, baseTempCreationPending, OverrideStackEntry::creationNamespace, elog, GetCurrentTransactionNestLevel(), linitial, list_delete_first(), list_free(), myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, OverrideStackEntry::nestLevel, pfree(), OverrideStackEntry::searchPath, and WARNING.
Referenced by AbortSubTransaction(), and CommitSubTransaction().
{ OverrideStackEntry *entry; if (myTempNamespaceSubID == mySubid) { if (isCommit) myTempNamespaceSubID = parentSubid; else { myTempNamespaceSubID = InvalidSubTransactionId; /* TEMP namespace creation failed, so reset state */ myTempNamespace = InvalidOid; myTempToastNamespace = InvalidOid; baseSearchPathValid = false; /* need to rebuild list */ } } /* * Clean up if someone failed to do PopOverrideSearchPath */ while (overrideStack) { entry = (OverrideStackEntry *) linitial(overrideStack); if (entry->nestLevel < GetCurrentTransactionNestLevel()) break; if (isCommit) elog(WARNING, "leaked override search path"); overrideStack = list_delete_first(overrideStack); list_free(entry->searchPath); pfree(entry); } /* Activate the next level down. */ if (overrideStack) { entry = (OverrideStackEntry *) linitial(overrideStack); activeSearchPath = entry->searchPath; activeCreationNamespace = entry->creationNamespace; activeTempCreationPending = false; /* XXX is this OK? */ } else { /* If not baseSearchPathValid, this is useless but harmless */ activeSearchPath = baseSearchPath; activeCreationNamespace = baseCreationNamespace; activeTempCreationPending = baseTempCreationPending; } }
void AtEOXact_Namespace | ( | bool | isCommit | ) |
Definition at line 3670 of file namespace.c.
References activeCreationNamespace, activeTempCreationPending, baseCreationNamespace, baseSearchPathValid, baseTempCreationPending, elog, InvalidSubTransactionId, linitial, list_delete_first(), list_free(), myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, on_shmem_exit(), pfree(), RemoveTempRelationsCallback(), OverrideStackEntry::searchPath, and WARNING.
Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().
{ /* * If we abort the transaction in which a temp namespace was selected, * we'll have to do any creation or cleanout work over again. So, just * forget the namespace entirely until next time. On the other hand, if * we commit then register an exit callback to clean out the temp tables * at backend shutdown. (We only want to register the callback once per * session, so this is a good place to do it.) */ if (myTempNamespaceSubID != InvalidSubTransactionId) { if (isCommit) on_shmem_exit(RemoveTempRelationsCallback, 0); else { myTempNamespace = InvalidOid; myTempToastNamespace = InvalidOid; baseSearchPathValid = false; /* need to rebuild list */ } myTempNamespaceSubID = InvalidSubTransactionId; } /* * Clean up if someone failed to do PopOverrideSearchPath */ if (overrideStack) { if (isCommit) elog(WARNING, "leaked override search path"); while (overrideStack) { OverrideStackEntry *entry; entry = (OverrideStackEntry *) linitial(overrideStack); overrideStack = list_delete_first(overrideStack); list_free(entry->searchPath); pfree(entry); } /* If not baseSearchPathValid, this is useless but harmless */ activeSearchPath = baseSearchPath; activeCreationNamespace = baseCreationNamespace; activeTempCreationPending = baseTempCreationPending; } }
Definition at line 3837 of file namespace.c.
References GUC_check_errdetail, list_free(), pfree(), pstrdup(), and SplitIdentifierString().
{ char *rawname; List *namelist; /* Need a modifiable copy of string */ rawname = pstrdup(*newval); /* Parse string into list of identifiers */ if (!SplitIdentifierString(rawname, ',', &namelist)) { /* syntax error in name list */ GUC_check_errdetail("List syntax is invalid."); pfree(rawname); list_free(namelist); return false; } /* * We used to try to check that the named schemas exist, but there are * many valid use-cases for having search_path settings that include * schemas that don't exist; and often, we are not inside a transaction * here and so can't consult the system catalogs anyway. So now, the only * requirement is syntactic validity of the identifier list. */ pfree(rawname); list_free(namelist); return true; }
Definition at line 2758 of file namespace.c.
References ereport, errcode(), errmsg(), ERROR, get_namespace_name(), getObjectDescriptionOids(), isAnyTempNamespace(), PG_TOAST_NAMESPACE, ProcedureRelationId, and RelationRelationId.
Referenced by AlterObjectNamespace_internal(), AlterTableNamespace(), and AlterTypeNamespaceInternal().
{ if (oldNspOid == nspOid) ereport(ERROR, (classid == RelationRelationId ? errcode(ERRCODE_DUPLICATE_TABLE) : classid == ProcedureRelationId ? errcode(ERRCODE_DUPLICATE_FUNCTION) : errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("%s is already in schema \"%s\"", getObjectDescriptionOids(classid, objid), get_namespace_name(nspOid)))); /* disallow renaming into or out of temp schemas */ if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot move objects into or out of temporary schemas"))); /* same for TOAST schema */ if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot move objects into or out of TOAST schema"))); }
Oid CollationGetCollid | ( | const char * | collname | ) |
Definition at line 1918 of file namespace.c.
References COLLNAMEENCNSP, GetDatabaseEncoding(), GetSysCacheOid3, Int32GetDatum, lfirst_oid, myTempNamespace, ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().
Referenced by CollationIsVisible().
{ int32 dbencoding = GetDatabaseEncoding(); ListCell *l; recomputeNamespacePath(); foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); Oid collid; if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ /* Check for database-encoding-specific entry */ collid = GetSysCacheOid3(COLLNAMEENCNSP, PointerGetDatum(collname), Int32GetDatum(dbencoding), ObjectIdGetDatum(namespaceId)); if (OidIsValid(collid)) return collid; /* Check for any-encoding entry */ collid = GetSysCacheOid3(COLLNAMEENCNSP, PointerGetDatum(collname), Int32GetDatum(-1), ObjectIdGetDatum(namespaceId)); if (OidIsValid(collid)) return collid; } /* Not found in path */ return InvalidOid; }
Definition at line 1961 of file namespace.c.
References CollationGetCollid(), COLLOID, elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.
Referenced by generate_collation_name(), and pg_collation_is_visible().
{ HeapTuple colltup; Form_pg_collation collform; Oid collnamespace; bool visible; colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid)); if (!HeapTupleIsValid(colltup)) elog(ERROR, "cache lookup failed for collation %u", collid); collform = (Form_pg_collation) GETSTRUCT(colltup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ collnamespace = collform->collnamespace; if (collnamespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, collnamespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another conversion of the same name earlier in the path. * So we must do a slow check to see if this conversion would be found * by CollationGetCollid. */ char *collname = NameStr(collform->collname); visible = (CollationGetCollid(collname) == collid); } ReleaseSysCache(colltup); return visible; }
Oid ConversionGetConid | ( | const char * | conname | ) |
Definition at line 2011 of file namespace.c.
References CONNAMENSP, GetSysCacheOid2, lfirst_oid, myTempNamespace, ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().
Referenced by ConversionIsVisible().
{ Oid conid; ListCell *l; recomputeNamespacePath(); foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ conid = GetSysCacheOid2(CONNAMENSP, PointerGetDatum(conname), ObjectIdGetDatum(namespaceId)); if (OidIsValid(conid)) return conid; } /* Not found in path */ return InvalidOid; }
Definition at line 2043 of file namespace.c.
References ConversionGetConid(), CONVOID, elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.
Referenced by pg_conversion_is_visible().
{ HeapTuple contup; Form_pg_conversion conform; Oid connamespace; bool visible; contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid)); if (!HeapTupleIsValid(contup)) elog(ERROR, "cache lookup failed for conversion %u", conid); conform = (Form_pg_conversion) GETSTRUCT(contup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ connamespace = conform->connamespace; if (connamespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, connamespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another conversion of the same name earlier in the path. * So we must do a slow check to see if this conversion would be found * by ConversionGetConid. */ char *conname = NameStr(conform->conname); visible = (ConversionGetConid(conname) == conid); } ReleaseSysCache(contup); return visible; }
OverrideSearchPath* CopyOverrideSearchPath | ( | OverrideSearchPath * | path | ) |
Definition at line 3113 of file namespace.c.
References OverrideSearchPath::addCatalog, OverrideSearchPath::addTemp, list_copy(), palloc(), and OverrideSearchPath::schemas.
Referenced by CopyCachedPlan().
{ OverrideSearchPath *result; result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath)); result->schemas = list_copy(path->schemas); result->addCatalog = path->addCatalog; result->addTemp = path->addTemp; return result; }
void DeconstructQualifiedName | ( | List * | names, | |
char ** | nspname_p, | |||
char ** | objname_p | |||
) |
Definition at line 2599 of file namespace.c.
References ereport, errcode(), errmsg(), ERROR, get_database_name(), linitial, list_length(), lsecond, lthird, MyDatabaseId, NameListToString(), and strVal.
Referenced by FuncnameGetCandidates(), get_collation_oid(), get_conversion_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), GetIndexOpClass(), LookupTypeName(), make_oper_cache_key(), OpClassCacheLookup(), OpernameGetCandidates(), OpernameGetOprid(), OpFamilyCacheLookup(), and QualifiedNameGetCreationNamespace().
{ char *catalogname; char *schemaname = NULL; char *objname = NULL; switch (list_length(names)) { case 1: objname = strVal(linitial(names)); break; case 2: schemaname = strVal(linitial(names)); objname = strVal(lsecond(names)); break; case 3: catalogname = strVal(linitial(names)); schemaname = strVal(lsecond(names)); objname = strVal(lthird(names)); /* * We check the catalog name and then ignore it. */ if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cross-database references are not implemented: %s", NameListToString(names)))); break; default: ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("improper qualified name (too many dotted names): %s", NameListToString(names)))); break; } *nspname_p = schemaname; *objname_p = objname; }
Definition at line 3945 of file namespace.c.
References activeCreationNamespace, activeTempCreationPending, InitTempTableNamespace(), linitial_oid, list_copy(), list_delete_first(), and recomputeNamespacePath().
Referenced by AfterTriggerSetState(), CreateExtension(), current_schema(), and current_schemas().
{ List *result; recomputeNamespacePath(); /* * If the temp namespace should be first, force it to exist. This is so * that callers can trust the result to reflect the actual default * creation namespace. It's a bit bogus to do this here, since * current_schema() is supposedly a stable function without side-effects, * but the alternatives seem worse. */ if (activeTempCreationPending) { InitTempTableNamespace(); recomputeNamespacePath(); } result = list_copy(activeSearchPath); if (!includeImplicit) { while (result && linitial_oid(result) != activeCreationNamespace) result = list_delete_first(result); } return result; }
int fetch_search_path_array | ( | Oid * | sarray, | |
int | sarray_len | |||
) |
Definition at line 3985 of file namespace.c.
References lfirst_oid, myTempNamespace, and recomputeNamespacePath().
Referenced by make_oper_cache_key().
{ int count = 0; ListCell *l; recomputeNamespacePath(); foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not include temp namespace */ if (count < sarray_len) sarray[count] = namespaceId; count++; } return count; }
Definition at line 3390 of file namespace.c.
References FindDefaultConversion(), lfirst_oid, myTempNamespace, OidIsValid, and recomputeNamespacePath().
Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().
{ Oid proc; ListCell *l; recomputeNamespacePath(); foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding); if (OidIsValid(proc)) return proc; } /* Not found in path */ return InvalidOid; }
FuncCandidateList FuncnameGetCandidates | ( | List * | names, | |
int | nargs, | |||
List * | argnames, | |||
bool | expand_variadic, | |||
bool | expand_defaults | |||
) |
Definition at line 910 of file namespace.c.
References _FuncCandidateList::argnumbers, _FuncCandidateList::args, Assert, CStringGetDatum, DeconstructQualifiedName(), GETSTRUCT, HeapTupleGetOid, i, lfirst_oid, LookupExplicitNamespace(), MatchNamedCall(), Max, catclist::members, memcmp(), myTempNamespace, catclist::n_members, _FuncCandidateList::nargs, _FuncCandidateList::ndargs, _FuncCandidateList::next, NIL, NULL, _FuncCandidateList::nvargs, _FuncCandidateList::oid, OidIsValid, catclist::ordered, palloc(), _FuncCandidateList::pathpos, pfree(), PROCNAMEARGSNSP, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, and catctup::tuple.
Referenced by func_get_detail(), FunctionIsVisible(), LookupFuncName(), regprocedurein(), regprocin(), and regprocout().
{ FuncCandidateList resultList = NULL; bool any_special = false; char *schemaname; char *funcname; Oid namespaceId; CatCList *catlist; int i; /* check for caller error */ Assert(nargs >= 0 || !(expand_variadic | expand_defaults)); /* deconstruct the name list */ DeconstructQualifiedName(names, &schemaname, &funcname); if (schemaname) { /* use exact schema given */ namespaceId = LookupExplicitNamespace(schemaname, false); } else { /* flag to indicate we need namespace search */ namespaceId = InvalidOid; recomputeNamespacePath(); } /* Search syscache by name only */ catlist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(funcname)); for (i = 0; i < catlist->n_members; i++) { HeapTuple proctup = &catlist->members[i]->tuple; Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup); int pronargs = procform->pronargs; int effective_nargs; int pathpos = 0; bool variadic; bool use_defaults; Oid va_elem_type; int *argnumbers = NULL; FuncCandidateList newResult; if (OidIsValid(namespaceId)) { /* Consider only procs in specified namespace */ if (procform->pronamespace != namespaceId) continue; } else { /* * Consider only procs that are in the search path and are not in * the temp namespace. */ ListCell *nsp; foreach(nsp, activeSearchPath) { if (procform->pronamespace == lfirst_oid(nsp) && procform->pronamespace != myTempNamespace) break; pathpos++; } if (nsp == NULL) continue; /* proc is not in search path */ } if (argnames != NIL) { /* * Call uses named or mixed notation * * Named or mixed notation can match a variadic function only if * expand_variadic is off; otherwise there is no way to match the * presumed-nameless parameters expanded from the variadic array. */ if (OidIsValid(procform->provariadic) && expand_variadic) continue; va_elem_type = InvalidOid; variadic = false; /* * Check argument count. */ Assert(nargs >= 0); /* -1 not supported with argnames */ if (pronargs > nargs && expand_defaults) { /* Ignore if not enough default expressions */ if (nargs + procform->pronargdefaults < pronargs) continue; use_defaults = true; } else use_defaults = false; /* Ignore if it doesn't match requested argument count */ if (pronargs != nargs && !use_defaults) continue; /* Check for argument name match, generate positional mapping */ if (!MatchNamedCall(proctup, nargs, argnames, &argnumbers)) continue; /* Named argument matching is always "special" */ any_special = true; } else { /* * Call uses positional notation * * Check if function is variadic, and get variadic element type if * so. If expand_variadic is false, we should just ignore * variadic-ness. */ if (pronargs <= nargs && expand_variadic) { va_elem_type = procform->provariadic; variadic = OidIsValid(va_elem_type); any_special |= variadic; } else { va_elem_type = InvalidOid; variadic = false; } /* * Check if function can match by using parameter defaults. */ if (pronargs > nargs && expand_defaults) { /* Ignore if not enough default expressions */ if (nargs + procform->pronargdefaults < pronargs) continue; use_defaults = true; any_special = true; } else use_defaults = false; /* Ignore if it doesn't match requested argument count */ if (nargs >= 0 && pronargs != nargs && !variadic && !use_defaults) continue; } /* * We must compute the effective argument list so that we can easily * compare it to earlier results. We waste a palloc cycle if it gets * masked by an earlier result, but really that's a pretty infrequent * case so it's not worth worrying about. */ effective_nargs = Max(pronargs, nargs); newResult = (FuncCandidateList) palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid) + effective_nargs * sizeof(Oid)); newResult->pathpos = pathpos; newResult->oid = HeapTupleGetOid(proctup); newResult->nargs = effective_nargs; newResult->argnumbers = argnumbers; if (argnumbers) { /* Re-order the argument types into call's logical order */ Oid *proargtypes = procform->proargtypes.values; int i; for (i = 0; i < pronargs; i++) newResult->args[i] = proargtypes[argnumbers[i]]; } else { /* Simple positional case, just copy proargtypes as-is */ memcpy(newResult->args, procform->proargtypes.values, pronargs * sizeof(Oid)); } if (variadic) { int i; newResult->nvargs = effective_nargs - pronargs + 1; /* Expand variadic argument into N copies of element type */ for (i = pronargs - 1; i < effective_nargs; i++) newResult->args[i] = va_elem_type; } else newResult->nvargs = 0; newResult->ndargs = use_defaults ? pronargs - nargs : 0; /* * Does it have the same arguments as something we already accepted? * If so, decide what to do to avoid returning duplicate argument * lists. We can skip this check for the single-namespace case if no * special (named, variadic or defaults) match has been made, since * then the unique index on pg_proc guarantees all the matches have * different argument lists. */ if (resultList != NULL && (any_special || !OidIsValid(namespaceId))) { /* * If we have an ordered list from SearchSysCacheList (the normal * case), then any conflicting proc must immediately adjoin this * one in the list, so we only need to look at the newest result * item. If we have an unordered list, we have to scan the whole * result list. Also, if either the current candidate or any * previous candidate is a special match, we can't assume that * conflicts are adjacent. * * We ignore defaulted arguments in deciding what is a match. */ FuncCandidateList prevResult; if (catlist->ordered && !any_special) { /* ndargs must be 0 if !any_special */ if (effective_nargs == resultList->nargs && memcmp(newResult->args, resultList->args, effective_nargs * sizeof(Oid)) == 0) prevResult = resultList; else prevResult = NULL; } else { int cmp_nargs = newResult->nargs - newResult->ndargs; for (prevResult = resultList; prevResult; prevResult = prevResult->next) { if (cmp_nargs == prevResult->nargs - prevResult->ndargs && memcmp(newResult->args, prevResult->args, cmp_nargs * sizeof(Oid)) == 0) break; } } if (prevResult) { /* * We have a match with a previous result. Decide which one * to keep, or mark it ambiguous if we can't decide. The * logic here is preference > 0 means prefer the old result, * preference < 0 means prefer the new, preference = 0 means * ambiguous. */ int preference; if (pathpos != prevResult->pathpos) { /* * Prefer the one that's earlier in the search path. */ preference = pathpos - prevResult->pathpos; } else if (variadic && prevResult->nvargs == 0) { /* * With variadic functions we could have, for example, * both foo(numeric) and foo(variadic numeric[]) in the * same namespace; if so we prefer the non-variadic match * on efficiency grounds. */ preference = 1; } else if (!variadic && prevResult->nvargs > 0) { preference = -1; } else { /*---------- * We can't decide. This can happen with, for example, * both foo(numeric, variadic numeric[]) and * foo(variadic numeric[]) in the same namespace, or * both foo(int) and foo (int, int default something) * in the same namespace, or both foo(a int, b text) * and foo(b text, a int) in the same namespace. *---------- */ preference = 0; } if (preference > 0) { /* keep previous result */ pfree(newResult); continue; } else if (preference < 0) { /* remove previous result from the list */ if (prevResult == resultList) resultList = prevResult->next; else { FuncCandidateList prevPrevResult; for (prevPrevResult = resultList; prevPrevResult; prevPrevResult = prevPrevResult->next) { if (prevResult == prevPrevResult->next) { prevPrevResult->next = prevResult->next; break; } } Assert(prevPrevResult); /* assert we found it */ } pfree(prevResult); /* fall through to add newResult to list */ } else { /* mark old result as ambiguous, discard new */ prevResult->oid = InvalidOid; pfree(newResult); continue; } } } /* * Okay to add it to result list */ newResult->next = resultList; resultList = newResult; } ReleaseSysCacheList(catlist); return resultList; }
Definition at line 1378 of file namespace.c.
References _FuncCandidateList::args, elog, ERROR, FuncnameGetCandidates(), GETSTRUCT, HeapTupleIsValid, list_make1, list_member_oid(), makeString(), memcmp(), NameStr, _FuncCandidateList::next, NIL, ObjectIdGetDatum, _FuncCandidateList::oid, PG_CATALOG_NAMESPACE, PROCOID, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.
Referenced by format_procedure_internal(), and pg_function_is_visible().
{ HeapTuple proctup; Form_pg_proc procform; Oid pronamespace; bool visible; proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); if (!HeapTupleIsValid(proctup)) elog(ERROR, "cache lookup failed for function %u", funcid); procform = (Form_pg_proc) GETSTRUCT(proctup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ pronamespace = procform->pronamespace; if (pronamespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, pronamespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another proc of the same name and arguments earlier in * the path. So we must do a slow check to see if this is the same * proc that would be found by FuncnameGetCandidates. */ char *proname = NameStr(procform->proname); int nargs = procform->pronargs; FuncCandidateList clist; visible = false; clist = FuncnameGetCandidates(list_make1(makeString(proname)), nargs, NIL, false, false); for (; clist; clist = clist->next) { if (memcmp(clist->args, procform->proargtypes.values, nargs * sizeof(Oid)) == 0) { /* Found the expected entry; is it the right proc? */ visible = (clist->oid == funcid); break; } } } ReleaseSysCache(proctup); return visible; }
Definition at line 3262 of file namespace.c.
References COLLNAMEENCNSP, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetDatabaseEncoding(), GetDatabaseEncodingName(), GetSysCacheOid3, Int32GetDatum, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().
Referenced by ComputeIndexAttrs(), DefineCollation(), DefineDomain(), DefineRange(), get_object_address(), and LookupCollation().
{ char *schemaname; char *collation_name; int32 dbencoding = GetDatabaseEncoding(); Oid namespaceId; Oid colloid; ListCell *l; /* deconstruct the name list */ DeconstructQualifiedName(name, &schemaname, &collation_name); if (schemaname) { /* use exact schema given */ namespaceId = LookupExplicitNamespace(schemaname, missing_ok); if (missing_ok && !OidIsValid(namespaceId)) return InvalidOid; /* first try for encoding-specific entry, then any-encoding */ colloid = GetSysCacheOid3(COLLNAMEENCNSP, PointerGetDatum(collation_name), Int32GetDatum(dbencoding), ObjectIdGetDatum(namespaceId)); if (OidIsValid(colloid)) return colloid; colloid = GetSysCacheOid3(COLLNAMEENCNSP, PointerGetDatum(collation_name), Int32GetDatum(-1), ObjectIdGetDatum(namespaceId)); if (OidIsValid(colloid)) return colloid; } else { /* search for it in search path */ recomputeNamespacePath(); foreach(l, activeSearchPath) { namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ colloid = GetSysCacheOid3(COLLNAMEENCNSP, PointerGetDatum(collation_name), Int32GetDatum(dbencoding), ObjectIdGetDatum(namespaceId)); if (OidIsValid(colloid)) return colloid; colloid = GetSysCacheOid3(COLLNAMEENCNSP, PointerGetDatum(collation_name), Int32GetDatum(-1), ObjectIdGetDatum(namespaceId)); if (OidIsValid(colloid)) return colloid; } } /* Not found in path */ if (!missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("collation \"%s\" for encoding \"%s\" does not exist", NameListToString(name), GetDatabaseEncodingName()))); return InvalidOid; }
Definition at line 3335 of file namespace.c.
References CONNAMENSP, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().
Referenced by get_object_address().
{ char *schemaname; char *conversion_name; Oid namespaceId; Oid conoid = InvalidOid; ListCell *l; /* deconstruct the name list */ DeconstructQualifiedName(name, &schemaname, &conversion_name); if (schemaname) { /* use exact schema given */ namespaceId = LookupExplicitNamespace(schemaname, missing_ok); if (missing_ok && !OidIsValid(namespaceId)) conoid = InvalidOid; else conoid = GetSysCacheOid2(CONNAMENSP, PointerGetDatum(conversion_name), ObjectIdGetDatum(namespaceId)); } else { /* search for it in search path */ recomputeNamespacePath(); foreach(l, activeSearchPath) { namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ conoid = GetSysCacheOid2(CONNAMENSP, PointerGetDatum(conversion_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(conoid)) return conoid; } } /* Not found in path */ if (!OidIsValid(conoid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion \"%s\" does not exist", NameListToString(name)))); return conoid; }
Definition at line 2846 of file namespace.c.
References CStringGetDatum, ereport, errcode(), errmsg(), ERROR, GetSysCacheOid1, NAMESPACENAME, and OidIsValid.
Referenced by convert_schema_name(), create_empty_extension(), CreateExtension(), get_object_address_unqualified(), InitTempTableNamespace(), LookupCreationNamespace(), LookupExplicitNamespace(), LookupNamespaceNoError(), objectNamesToOids(), QualifiedNameGetCreationNamespace(), RangeVarGetCreationNamespace(), recomputeNamespacePath(), RenameSchema(), and SetDefaultACLsInSchemas().
{ Oid oid; oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("schema \"%s\" does not exist", nspname))); return oid; }
Definition at line 2469 of file namespace.c.
References DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, recomputeNamespacePath(), and TSCONFIGNAMENSP.
Referenced by check_TSCurrentConfig(), DefineTSConfiguration(), get_object_address(), GetTSConfigTuple(), getTSCurrentConfig(), regconfigin(), and tsvector_update_trigger().
{ char *schemaname; char *config_name; Oid namespaceId; Oid cfgoid = InvalidOid; ListCell *l; /* deconstruct the name list */ DeconstructQualifiedName(names, &schemaname, &config_name); if (schemaname) { /* use exact schema given */ namespaceId = LookupExplicitNamespace(schemaname, missing_ok); if (missing_ok && !OidIsValid(namespaceId)) cfgoid = InvalidOid; else cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, PointerGetDatum(config_name), ObjectIdGetDatum(namespaceId)); } else { /* search for it in search path */ recomputeNamespacePath(); foreach(l, activeSearchPath) { namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, PointerGetDatum(config_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(cfgoid)) break; } } if (!OidIsValid(cfgoid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("text search configuration \"%s\" does not exist", NameListToString(names)))); return cfgoid; }
Definition at line 2216 of file namespace.c.
References DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, recomputeNamespacePath(), and TSDICTNAMENSP.
Referenced by AlterTSDictionary(), get_object_address(), MakeConfigurationMapping(), regdictionaryin(), thesaurus_init(), tsa_set_curdict_byname(), and unaccent_dict().
{ char *schemaname; char *dict_name; Oid namespaceId; Oid dictoid = InvalidOid; ListCell *l; /* deconstruct the name list */ DeconstructQualifiedName(names, &schemaname, &dict_name); if (schemaname) { /* use exact schema given */ namespaceId = LookupExplicitNamespace(schemaname, missing_ok); if (missing_ok && !OidIsValid(namespaceId)) dictoid = InvalidOid; else dictoid = GetSysCacheOid2(TSDICTNAMENSP, PointerGetDatum(dict_name), ObjectIdGetDatum(namespaceId)); } else { /* search for it in search path */ recomputeNamespacePath(); foreach(l, activeSearchPath) { namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ dictoid = GetSysCacheOid2(TSDICTNAMENSP, PointerGetDatum(dict_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(dictoid)) break; } } if (!OidIsValid(dictoid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("text search dictionary \"%s\" does not exist", NameListToString(names)))); return dictoid; }
Definition at line 2090 of file namespace.c.
References DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, recomputeNamespacePath(), and TSPARSERNAMENSP.
Referenced by DefineTSConfiguration(), get_object_address(), GetCurrentParser(), ts_parse_byname(), ts_token_type_byname(), and tsa_set_curprs_byname().
{ char *schemaname; char *parser_name; Oid namespaceId; Oid prsoid = InvalidOid; ListCell *l; /* deconstruct the name list */ DeconstructQualifiedName(names, &schemaname, &parser_name); if (schemaname) { /* use exact schema given */ namespaceId = LookupExplicitNamespace(schemaname, missing_ok); if (missing_ok && !OidIsValid(namespaceId)) prsoid = InvalidOid; else prsoid = GetSysCacheOid2(TSPARSERNAMENSP, PointerGetDatum(parser_name), ObjectIdGetDatum(namespaceId)); } else { /* search for it in search path */ recomputeNamespacePath(); foreach(l, activeSearchPath) { namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ prsoid = GetSysCacheOid2(TSPARSERNAMENSP, PointerGetDatum(parser_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(prsoid)) break; } } if (!OidIsValid(prsoid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("text search parser \"%s\" does not exist", NameListToString(names)))); return prsoid; }
Definition at line 2343 of file namespace.c.
References DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, recomputeNamespacePath(), and TSTEMPLATENAMENSP.
Referenced by DefineTSDictionary(), and get_object_address().
{ char *schemaname; char *template_name; Oid namespaceId; Oid tmploid = InvalidOid; ListCell *l; /* deconstruct the name list */ DeconstructQualifiedName(names, &schemaname, &template_name); if (schemaname) { /* use exact schema given */ namespaceId = LookupExplicitNamespace(schemaname, missing_ok); if (missing_ok && !OidIsValid(namespaceId)) tmploid = InvalidOid; else tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, PointerGetDatum(template_name), ObjectIdGetDatum(namespaceId)); } else { /* search for it in search path */ recomputeNamespacePath(); foreach(l, activeSearchPath) { namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, PointerGetDatum(template_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(tmploid)) break; } } if (!OidIsValid(tmploid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("text search template \"%s\" does not exist", NameListToString(names)))); return tmploid; }
OverrideSearchPath* GetOverrideSearchPath | ( | MemoryContext | context | ) |
Definition at line 3077 of file namespace.c.
References activeCreationNamespace, OverrideSearchPath::addCatalog, OverrideSearchPath::addTemp, Assert, linitial_oid, list_copy(), list_delete_first(), MemoryContextSwitchTo(), myTempNamespace, palloc0(), PG_CATALOG_NAMESPACE, recomputeNamespacePath(), and OverrideSearchPath::schemas.
Referenced by CompleteCachedPlan(), CreateSchemaCommand(), OverrideSearchPathMatchesCurrent(), and RevalidateCachedQuery().
{ OverrideSearchPath *result; List *schemas; MemoryContext oldcxt; recomputeNamespacePath(); oldcxt = MemoryContextSwitchTo(context); result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath)); schemas = list_copy(activeSearchPath); while (schemas && linitial_oid(schemas) != activeCreationNamespace) { if (linitial_oid(schemas) == myTempNamespace) result->addTemp = true; else { Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE); result->addCatalog = true; } schemas = list_delete_first(schemas); } result->schemas = schemas; MemoryContextSwitchTo(oldcxt); return result; }
int GetTempNamespaceBackendId | ( | Oid | namespaceId | ) |
Definition at line 3036 of file namespace.c.
References get_namespace_name(), and pfree().
Referenced by do_autovacuum(), pg_relation_filepath(), and RelationBuildDesc().
{ int result; char *nspname; /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */ nspname = get_namespace_name(namespaceId); if (!nspname) return InvalidBackendId; /* no such namespace? */ if (strncmp(nspname, "pg_temp_", 8) == 0) result = atoi(nspname + 8); else if (strncmp(nspname, "pg_toast_temp_", 14) == 0) result = atoi(nspname + 14); else result = InvalidBackendId; pfree(nspname); return result; }
Oid GetTempToastNamespace | ( | void | ) |
Definition at line 3061 of file namespace.c.
References Assert, myTempToastNamespace, and OidIsValid.
Referenced by create_toast_table().
{ Assert(OidIsValid(myTempToastNamespace)); return myTempToastNamespace; }
void InitializeSearchPath | ( | void | ) |
Definition at line 3887 of file namespace.c.
References activeCreationNamespace, activeTempCreationPending, baseCreationNamespace, baseSearchPathValid, baseTempCreationPending, CacheRegisterSyscacheCallback(), GetUserId(), IsBootstrapProcessingMode, list_make1_oid, MemoryContextSwitchTo(), NamespaceCallback(), NAMESPACEOID, namespaceUser, PG_CATALOG_NAMESPACE, and TopMemoryContext.
Referenced by InitPostgres().
{ if (IsBootstrapProcessingMode()) { /* * In bootstrap mode, the search path must be 'pg_catalog' so that * tables are created in the proper namespace; ignore the GUC setting. */ MemoryContext oldcxt; oldcxt = MemoryContextSwitchTo(TopMemoryContext); baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE); MemoryContextSwitchTo(oldcxt); baseCreationNamespace = PG_CATALOG_NAMESPACE; baseTempCreationPending = false; baseSearchPathValid = true; namespaceUser = GetUserId(); activeSearchPath = baseSearchPath; activeCreationNamespace = baseCreationNamespace; activeTempCreationPending = baseTempCreationPending; } else { /* * In normal mode, arrange for a callback on any syscache invalidation * of pg_namespace rows. */ CacheRegisterSyscacheCallback(NAMESPACEOID, NamespaceCallback, (Datum) 0); /* Force search path to be recomputed on next use */ baseSearchPathValid = false; } }
static void InitTempTableNamespace | ( | void | ) | [static] |
Definition at line 3567 of file namespace.c.
References ACL_CREATE_TEMP, ACLCHECK_OK, Assert, AssertState, baseSearchPathValid, BOOTSTRAP_SUPERUSERID, CommandCounterIncrement(), ereport, errcode(), errmsg(), ERROR, get_database_name(), get_namespace_oid(), GetCurrentSubTransactionId(), GetUserId(), InvalidSubTransactionId, MyBackendId, MyDatabaseId, myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, NamespaceCreate(), OidIsValid, pg_database_aclcheck(), RecoveryInProgress(), RemoveTempRelations(), and snprintf().
Referenced by fetch_search_path(), LookupCreationNamespace(), QualifiedNameGetCreationNamespace(), and RangeVarGetCreationNamespace().
{ char namespaceName[NAMEDATALEN]; Oid namespaceId; Oid toastspaceId; Assert(!OidIsValid(myTempNamespace)); /* * First, do permission check to see if we are authorized to make temp * tables. We use a nonstandard error message here since "databasename: * permission denied" might be a tad cryptic. * * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask; * that's necessary since current user ID could change during the session. * But there's no need to make the namespace in the first place until a * temp table creation request is made by someone with appropriate rights. */ if (pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CREATE_TEMP) != ACLCHECK_OK) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied to create temporary tables in database \"%s\"", get_database_name(MyDatabaseId)))); /* * Do not allow a Hot Standby slave session to make temp tables. Aside * from problems with modifying the system catalogs, there is a naming * conflict: pg_temp_N belongs to the session with BackendId N on the * master, not to a slave session with the same BackendId. We should not * be able to get here anyway due to XactReadOnly checks, but let's just * make real sure. Note that this also backstops various operations that * allow XactReadOnly transactions to modify temp tables; they'd need * RecoveryInProgress checks if not for this. */ if (RecoveryInProgress()) ereport(ERROR, (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION), errmsg("cannot create temporary tables during recovery"))); snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId); namespaceId = get_namespace_oid(namespaceName, true); if (!OidIsValid(namespaceId)) { /* * First use of this temp namespace in this database; create it. The * temp namespaces are always owned by the superuser. We leave their * permissions at default --- i.e., no access except to superuser --- * to ensure that unprivileged users can't peek at other backends' * temp tables. This works because the places that access the temp * namespace for my own backend skip permissions checks on it. */ namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID, true); /* Advance command counter to make namespace visible */ CommandCounterIncrement(); } else { /* * If the namespace already exists, clean it out (in case the former * owner crashed without doing so). */ RemoveTempRelations(namespaceId); } /* * If the corresponding toast-table namespace doesn't exist yet, create * it. (We assume there is no need to clean it out if it does exist, since * dropping a parent table should make its toast table go away.) */ snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d", MyBackendId); toastspaceId = get_namespace_oid(namespaceName, true); if (!OidIsValid(toastspaceId)) { toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID, true); /* Advance command counter to make namespace visible */ CommandCounterIncrement(); } /* * Okay, we've prepared the temp namespace ... but it's not committed yet, * so all our work could be undone by transaction rollback. Set flag for * AtEOXact_Namespace to know what to do. */ myTempNamespace = namespaceId; myTempToastNamespace = toastspaceId; /* It should not be done already. */ AssertState(myTempNamespaceSubID == InvalidSubTransactionId); myTempNamespaceSubID = GetCurrentSubTransactionId(); baseSearchPathValid = false; /* need to rebuild list */ }
Definition at line 2997 of file namespace.c.
References get_namespace_name(), and pfree().
Referenced by CheckSetNamespace(), EventTriggerSQLDropAddObject(), isOtherTempNamespace(), and RangeVarAdjustRelationPersistence().
{ bool result; char *nspname; /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */ nspname = get_namespace_name(namespaceId); if (!nspname) return false; /* no such namespace? */ result = (strncmp(nspname, "pg_temp_", 8) == 0) || (strncmp(nspname, "pg_toast_temp_", 14) == 0); pfree(nspname); return result; }
Definition at line 3020 of file namespace.c.
References isAnyTempNamespace(), and isTempOrToastNamespace().
Referenced by pg_is_other_temp_schema().
{ /* If it's my own temp namespace, say "false" */ if (isTempOrToastNamespace(namespaceId)) return false; /* Else, if it's any temp namespace, say "true" */ return isAnyTempNamespace(namespaceId); }
Definition at line 2959 of file namespace.c.
References myTempNamespace, and OidIsValid.
Referenced by ExecCheckXactReadOnly(), pg_namespace_aclmask(), and ReindexDatabase().
{ if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId) return true; return false; }
Definition at line 2983 of file namespace.c.
References myTempNamespace, myTempToastNamespace, and OidIsValid.
Referenced by create_toast_table(), isOtherTempNamespace(), pg_relation_filepath(), RangeVarAdjustRelationPersistence(), RelationBuildDesc(), and RelationBuildLocalRelation().
{ if (OidIsValid(myTempNamespace) && (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId)) return true; return false; }
Definition at line 2971 of file namespace.c.
References myTempToastNamespace, and OidIsValid.
Referenced by IsToastNamespace().
{ if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId) return true; return false; }
Oid LookupCreationNamespace | ( | const char * | nspname | ) |
Definition at line 2726 of file namespace.c.
References ACL_CREATE, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_OK, get_namespace_oid(), GetUserId(), InitTempTableNamespace(), myTempNamespace, OidIsValid, and pg_namespace_aclcheck().
Referenced by AlterExtensionNamespace(), AlterTypeNamespace(), and ExecAlterObjectSchemaStmt().
{ Oid namespaceId; AclResult aclresult; /* check for pg_temp alias */ if (strcmp(nspname, "pg_temp") == 0) { /* Initialize temp namespace if first time through */ if (!OidIsValid(myTempNamespace)) InitTempTableNamespace(); return myTempNamespace; } namespaceId = get_namespace_oid(nspname, false); aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, nspname); return namespaceId; }
Definition at line 2683 of file namespace.c.
References ACL_KIND_NAMESPACE, ACL_USAGE, aclcheck_error(), ACLCHECK_OK, get_namespace_oid(), GetUserId(), InvokeNamespaceSearchHook, myTempNamespace, OidIsValid, and pg_namespace_aclcheck().
Referenced by AfterTriggerSetState(), FuncnameGetCandidates(), get_collation_oid(), get_conversion_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), GetIndexOpClass(), LookupTypeName(), make_oper_cache_key(), objectsInSchemaToOids(), OpClassCacheLookup(), OpernameGetCandidates(), OpernameGetOprid(), OpFamilyCacheLookup(), RangeVarGetRelidExtended(), schema_to_xml(), schema_to_xml_and_xmlschema(), and schema_to_xmlschema_internal().
{ Oid namespaceId; AclResult aclresult; /* check for pg_temp alias */ if (strcmp(nspname, "pg_temp") == 0) { if (OidIsValid(myTempNamespace)) return myTempNamespace; /* * Since this is used only for looking up existing objects, there is * no point in trying to initialize the temp namespace here; and doing * so might create problems for some callers --- just fall through. */ } namespaceId = get_namespace_oid(nspname, missing_ok); if (missing_ok && !OidIsValid(namespaceId)) return InvalidOid; aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, nspname); /* Schema search hook for this lookup */ InvokeNamespaceSearchHook(namespaceId, true); return namespaceId; }
Oid LookupNamespaceNoError | ( | const char * | nspname | ) |
Definition at line 2653 of file namespace.c.
References get_namespace_oid(), InvokeNamespaceSearchHook, myTempNamespace, and OidIsValid.
Referenced by refnameRangeTblEntry().
{ /* check for pg_temp alias */ if (strcmp(nspname, "pg_temp") == 0) { if (OidIsValid(myTempNamespace)) { InvokeNamespaceSearchHook(myTempNamespace, true); return myTempNamespace; } /* * Since this is used only for looking up existing objects, there is * no point in trying to initialize the temp namespace here; and doing * so might create problems for some callers. Just report "not found". */ return InvalidOid; } return get_namespace_oid(nspname, true); }
Definition at line 2864 of file namespace.c.
References RangeVar::catalogname, ereport, errcode(), errmsg(), ERROR, linitial, list_length(), lsecond, lthird, makeRangeVar(), NameListToString(), NULL, RangeVar::relname, RangeVar::schemaname, and strVal.
Referenced by bt_metap(), bt_page_items(), bt_page_stats(), convert_table_name(), currtid_byrelname(), get_object_address_attribute(), get_object_address_relobject(), get_raw_page_internal(), get_rel_from_relname(), get_relation_by_qualified_name(), nextval(), pg_get_serial_sequence(), pg_get_viewdef_name(), pg_get_viewdef_name_ext(), pg_relpages(), pgrowlocks(), pgstatindex(), pgstattuple(), process_owned_by(), regclassin(), RelationNameGetTupleDesc(), RemoveRelations(), and text_regclass().
{ RangeVar *rel = makeRangeVar(NULL, NULL, -1); switch (list_length(names)) { case 1: rel->relname = strVal(linitial(names)); break; case 2: rel->schemaname = strVal(linitial(names)); rel->relname = strVal(lsecond(names)); break; case 3: rel->catalogname = strVal(linitial(names)); rel->schemaname = strVal(lsecond(names)); rel->relname = strVal(lthird(names)); break; default: ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("improper relation name (too many dotted names): %s", NameListToString(names)))); break; } return rel; }
static bool MatchNamedCall | ( | HeapTuple | proctup, | |
int | nargs, | |||
List * | argnames, | |||
int ** | argnumbers | |||
) | [static] |
Definition at line 1270 of file namespace.c.
References Anum_pg_proc_proargnames, Assert, FUNC_PARAM_IN, FUNC_PARAM_INOUT, FUNC_PARAM_VARIADIC, get_func_arg_info(), GETSTRUCT, i, lfirst, list_length(), NIL, NULL, palloc(), PROCOID, and SysCacheGetAttr().
Referenced by FuncnameGetCandidates().
{ Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup); int pronargs = procform->pronargs; int numposargs = nargs - list_length(argnames); int pronallargs; Oid *p_argtypes; char **p_argnames; char *p_argmodes; bool arggiven[FUNC_MAX_ARGS]; bool isnull; int ap; /* call args position */ int pp; /* proargs position */ ListCell *lc; Assert(argnames != NIL); Assert(numposargs >= 0); Assert(nargs <= pronargs); /* Ignore this function if its proargnames is null */ (void) SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proargnames, &isnull); if (isnull) return false; /* OK, let's extract the argument names and types */ pronallargs = get_func_arg_info(proctup, &p_argtypes, &p_argnames, &p_argmodes); Assert(p_argnames != NULL); /* initialize state for matching */ *argnumbers = (int *) palloc(pronargs * sizeof(int)); memset(arggiven, false, pronargs * sizeof(bool)); /* there are numposargs positional args before the named args */ for (ap = 0; ap < numposargs; ap++) { (*argnumbers)[ap] = ap; arggiven[ap] = true; } /* now examine the named args */ foreach(lc, argnames) { char *argname = (char *) lfirst(lc); bool found; int i; pp = 0; found = false; for (i = 0; i < pronallargs; i++) { /* consider only input parameters */ if (p_argmodes && (p_argmodes[i] != FUNC_PARAM_IN && p_argmodes[i] != FUNC_PARAM_INOUT && p_argmodes[i] != FUNC_PARAM_VARIADIC)) continue; if (p_argnames[i] && strcmp(p_argnames[i], argname) == 0) { /* fail if argname matches a positional argument */ if (arggiven[pp]) return false; arggiven[pp] = true; (*argnumbers)[ap] = pp; found = true; break; } /* increase pp only for input parameters */ pp++; } /* if name isn't in proargnames, fail */ if (!found) return false; ap++; } Assert(ap == nargs); /* processed all actual parameters */ /* Check for default arguments */ if (nargs < pronargs) { int first_arg_with_default = pronargs - procform->pronargdefaults; for (pp = numposargs; pp < pronargs; pp++) { if (arggiven[pp]) continue; /* fail if arg not given and no default available */ if (pp < first_arg_with_default) return false; (*argnumbers)[ap++] = pp; } } Assert(ap == pronargs); /* processed all function parameters */ return true; }
char* NameListToQuotedString | ( | List * | names | ) |
Definition at line 2938 of file namespace.c.
References appendStringInfoChar(), appendStringInfoString(), initStringInfo(), lfirst, list_head(), quote_identifier(), and strVal.
{ StringInfoData string; ListCell *l; initStringInfo(&string); foreach(l, names) { if (l != list_head(names)) appendStringInfoChar(&string, '.'); appendStringInfoString(&string, quote_identifier(strVal(lfirst(l)))); } return string.data; }
char* NameListToString | ( | List * | names | ) |
Definition at line 2904 of file namespace.c.
References appendStringInfoChar(), appendStringInfoString(), elog, ERROR, initStringInfo(), IsA, lfirst, list_head(), name, nodeTag, and strVal.
Referenced by AggregateCreate(), AlterFunction(), AlterTSConfiguration(), AlterTSDictionary(), check_object_ownership(), CreateConversionCommand(), CreateEventTrigger(), CreateProceduralLanguage(), CreateTrigger(), DeconstructQualifiedName(), defGetString(), DefineOperator(), DefineType(), does_not_exist_skipping(), dropOperators(), dropProcedures(), ExpandColumnRefStar(), findRangeSubOpclass(), findTypeAnalyzeFunction(), findTypeInputFunction(), findTypeOutputFunction(), findTypeTypmodinFunction(), findTypeTypmodoutFunction(), func_signature_string(), get_collation_oid(), get_conversion_oid(), get_object_address_attribute(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), GetIndexOpClass(), lookup_fdw_handler_func(), LookupAggNameTypeNames(), LookupTypeName(), makeRangeVarFromNameList(), op_signature_string(), OpClassCacheLookup(), OperatorCreate(), OpFamilyCacheLookup(), ParseFuncOrColumn(), plpgsql_post_column_ref(), RemoveObjects(), storeOperators(), storeProcedures(), and transformColumnRef().
{ StringInfoData string; ListCell *l; initStringInfo(&string); foreach(l, names) { Node *name = (Node *) lfirst(l); if (l != list_head(names)) appendStringInfoChar(&string, '.'); if (IsA(name, String)) appendStringInfoString(&string, strVal(name)); else if (IsA(name, A_Star)) appendStringInfoString(&string, "*"); else elog(ERROR, "unexpected node type in name list: %d", (int) nodeTag(name)); } return string.data; }
Definition at line 3927 of file namespace.c.
References baseSearchPathValid.
Referenced by InitializeSearchPath().
{ /* Force search path to be recomputed on next use */ baseSearchPathValid = false; }
Definition at line 1788 of file namespace.c.
References CLAOID, elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, OpclassnameGetOpcid(), PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.
Referenced by get_opclass_name(), getObjectDescription(), and pg_opclass_is_visible().
{ HeapTuple opctup; Form_pg_opclass opcform; Oid opcnamespace; bool visible; opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid)); if (!HeapTupleIsValid(opctup)) elog(ERROR, "cache lookup failed for opclass %u", opcid); opcform = (Form_pg_opclass) GETSTRUCT(opctup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ opcnamespace = opcform->opcnamespace; if (opcnamespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, opcnamespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another opclass of the same name earlier in the path. So * we must do a slow check to see if this opclass would be found by * OpclassnameGetOpcid. */ char *opcname = NameStr(opcform->opcname); visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid); } ReleaseSysCache(opctup); return visible; }
Definition at line 1755 of file namespace.c.
References CLAAMNAMENSP, GetSysCacheOid3, lfirst_oid, myTempNamespace, ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().
Referenced by GetIndexOpClass(), OpClassCacheLookup(), and OpclassIsVisible().
{ Oid opcid; ListCell *l; recomputeNamespacePath(); foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ opcid = GetSysCacheOid3(CLAAMNAMENSP, ObjectIdGetDatum(amid), PointerGetDatum(opcname), ObjectIdGetDatum(namespaceId)); if (OidIsValid(opcid)) return opcid; } /* Not found in path */ return InvalidOid; }
Definition at line 1702 of file namespace.c.
References elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_make1, list_member_oid(), makeString(), NameStr, ObjectIdGetDatum, OpernameGetOprid(), OPEROID, PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.
Referenced by format_operator_internal(), and pg_operator_is_visible().
{ HeapTuple oprtup; Form_pg_operator oprform; Oid oprnamespace; bool visible; oprtup = SearchSysCache1(OPEROID, ObjectIdGetDatum(oprid)); if (!HeapTupleIsValid(oprtup)) elog(ERROR, "cache lookup failed for operator %u", oprid); oprform = (Form_pg_operator) GETSTRUCT(oprtup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ oprnamespace = oprform->oprnamespace; if (oprnamespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, oprnamespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another operator of the same name and arguments earlier * in the path. So we must do a slow check to see if this is the same * operator that would be found by OpernameGetOprId. */ char *oprname = NameStr(oprform->oprname); visible = (OpernameGetOprid(list_make1(makeString(oprname)), oprform->oprleft, oprform->oprright) == oprid); } ReleaseSysCache(oprtup); return visible; }
FuncCandidateList OpernameGetCandidates | ( | List * | names, | |
char | oprkind | |||
) |
Definition at line 1545 of file namespace.c.
References _FuncCandidateList::argnumbers, _FuncCandidateList::args, Assert, CStringGetDatum, DeconstructQualifiedName(), GETSTRUCT, HeapTupleGetOid, i, lfirst_oid, LookupExplicitNamespace(), catclist::members, myTempNamespace, catclist::n_members, _FuncCandidateList::nargs, _FuncCandidateList::ndargs, _FuncCandidateList::next, NULL, _FuncCandidateList::nvargs, _FuncCandidateList::oid, OidIsValid, OPERNAMENSP, catclist::ordered, palloc(), _FuncCandidateList::pathpos, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, SPACE_PER_OP, and catctup::tuple.
Referenced by left_oper(), oper(), regoperin(), regoperout(), and right_oper().
{ FuncCandidateList resultList = NULL; char *resultSpace = NULL; int nextResult = 0; char *schemaname; char *opername; Oid namespaceId; CatCList *catlist; int i; /* deconstruct the name list */ DeconstructQualifiedName(names, &schemaname, &opername); if (schemaname) { /* use exact schema given */ namespaceId = LookupExplicitNamespace(schemaname, false); } else { /* flag to indicate we need namespace search */ namespaceId = InvalidOid; recomputeNamespacePath(); } /* Search syscache by name only */ catlist = SearchSysCacheList1(OPERNAMENSP, CStringGetDatum(opername)); /* * In typical scenarios, most if not all of the operators found by the * catcache search will end up getting returned; and there can be quite a * few, for common operator names such as '=' or '+'. To reduce the time * spent in palloc, we allocate the result space as an array large enough * to hold all the operators. The original coding of this routine did a * separate palloc for each operator, but profiling revealed that the * pallocs used an unreasonably large fraction of parsing time. */ #define SPACE_PER_OP MAXALIGN(sizeof(struct _FuncCandidateList) + sizeof(Oid)) if (catlist->n_members > 0) resultSpace = palloc(catlist->n_members * SPACE_PER_OP); for (i = 0; i < catlist->n_members; i++) { HeapTuple opertup = &catlist->members[i]->tuple; Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup); int pathpos = 0; FuncCandidateList newResult; /* Ignore operators of wrong kind, if specific kind requested */ if (oprkind && operform->oprkind != oprkind) continue; if (OidIsValid(namespaceId)) { /* Consider only opers in specified namespace */ if (operform->oprnamespace != namespaceId) continue; /* No need to check args, they must all be different */ } else { /* * Consider only opers that are in the search path and are not in * the temp namespace. */ ListCell *nsp; foreach(nsp, activeSearchPath) { if (operform->oprnamespace == lfirst_oid(nsp) && operform->oprnamespace != myTempNamespace) break; pathpos++; } if (nsp == NULL) continue; /* oper is not in search path */ /* * Okay, it's in the search path, but does it have the same * arguments as something we already accepted? If so, keep only * the one that appears earlier in the search path. * * If we have an ordered list from SearchSysCacheList (the normal * case), then any conflicting oper must immediately adjoin this * one in the list, so we only need to look at the newest result * item. If we have an unordered list, we have to scan the whole * result list. */ if (resultList) { FuncCandidateList prevResult; if (catlist->ordered) { if (operform->oprleft == resultList->args[0] && operform->oprright == resultList->args[1]) prevResult = resultList; else prevResult = NULL; } else { for (prevResult = resultList; prevResult; prevResult = prevResult->next) { if (operform->oprleft == prevResult->args[0] && operform->oprright == prevResult->args[1]) break; } } if (prevResult) { /* We have a match with a previous result */ Assert(pathpos != prevResult->pathpos); if (pathpos > prevResult->pathpos) continue; /* keep previous result */ /* replace previous result */ prevResult->pathpos = pathpos; prevResult->oid = HeapTupleGetOid(opertup); continue; /* args are same, of course */ } } } /* * Okay to add it to result list */ newResult = (FuncCandidateList) (resultSpace + nextResult); nextResult += SPACE_PER_OP; newResult->pathpos = pathpos; newResult->oid = HeapTupleGetOid(opertup); newResult->nargs = 2; newResult->nvargs = 0; newResult->ndargs = 0; newResult->argnumbers = NULL; newResult->args[0] = operform->oprleft; newResult->args[1] = operform->oprright; newResult->next = resultList; resultList = newResult; } ReleaseSysCacheList(catlist); return resultList; }
Definition at line 1448 of file namespace.c.
References CStringGetDatum, DeconstructQualifiedName(), GETSTRUCT, HeapTupleGetOid, HeapTupleIsValid, i, lfirst_oid, LookupExplicitNamespace(), catclist::members, myTempNamespace, catclist::n_members, ObjectIdGetDatum, OPERNAMENSP, recomputeNamespacePath(), ReleaseSysCache(), ReleaseSysCacheList, SearchSysCache4, SearchSysCacheList3, and catctup::tuple.
Referenced by binary_oper_exact(), left_oper(), LookupOperName(), OperatorIsVisible(), regoperatorin(), and right_oper().
{ char *schemaname; char *opername; CatCList *catlist; ListCell *l; /* deconstruct the name list */ DeconstructQualifiedName(names, &schemaname, &opername); if (schemaname) { /* search only in exact schema given */ Oid namespaceId; HeapTuple opertup; namespaceId = LookupExplicitNamespace(schemaname, false); opertup = SearchSysCache4(OPERNAMENSP, CStringGetDatum(opername), ObjectIdGetDatum(oprleft), ObjectIdGetDatum(oprright), ObjectIdGetDatum(namespaceId)); if (HeapTupleIsValid(opertup)) { Oid result = HeapTupleGetOid(opertup); ReleaseSysCache(opertup); return result; } return InvalidOid; } /* Search syscache by name and argument types */ catlist = SearchSysCacheList3(OPERNAMENSP, CStringGetDatum(opername), ObjectIdGetDatum(oprleft), ObjectIdGetDatum(oprright)); if (catlist->n_members == 0) { /* no hope, fall out early */ ReleaseSysCacheList(catlist); return InvalidOid; } /* * We have to find the list member that is first in the search path, if * there's more than one. This doubly-nested loop looks ugly, but in * practice there should usually be few catlist members. */ recomputeNamespacePath(); foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); int i; if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ for (i = 0; i < catlist->n_members; i++) { HeapTuple opertup = &catlist->members[i]->tuple; Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup); if (operform->oprnamespace == namespaceId) { Oid result = HeapTupleGetOid(opertup); ReleaseSysCacheList(catlist); return result; } } } ReleaseSysCacheList(catlist); return InvalidOid; }
Definition at line 1871 of file namespace.c.
References elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, OpfamilynameGetOpfid(), OPFAMILYOID, PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.
Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().
{ HeapTuple opftup; Form_pg_opfamily opfform; Oid opfnamespace; bool visible; opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid)); if (!HeapTupleIsValid(opftup)) elog(ERROR, "cache lookup failed for opfamily %u", opfid); opfform = (Form_pg_opfamily) GETSTRUCT(opftup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ opfnamespace = opfform->opfnamespace; if (opfnamespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, opfnamespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another opfamily of the same name earlier in the path. So * we must do a slow check to see if this opfamily would be found by * OpfamilynameGetOpfid. */ char *opfname = NameStr(opfform->opfname); visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid); } ReleaseSysCache(opftup); return visible; }
Definition at line 1838 of file namespace.c.
References GetSysCacheOid3, lfirst_oid, myTempNamespace, ObjectIdGetDatum, OidIsValid, OPFAMILYAMNAMENSP, PointerGetDatum, and recomputeNamespacePath().
Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().
{ Oid opfid; ListCell *l; recomputeNamespacePath(); foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, ObjectIdGetDatum(amid), PointerGetDatum(opfname), ObjectIdGetDatum(namespaceId)); if (OidIsValid(opfid)) return opfid; } /* Not found in path */ return InvalidOid; }
bool OverrideSearchPathMatchesCurrent | ( | OverrideSearchPath * | path | ) |
Definition at line 3129 of file namespace.c.
References OverrideSearchPath::addCatalog, OverrideSearchPath::addTemp, cur, CurrentMemoryContext, equal(), GetOverrideSearchPath(), list_free(), pfree(), and OverrideSearchPath::schemas.
Referenced by RevalidateCachedQuery().
{ /* Easiest way to do this is GetOverrideSearchPath() and compare */ bool result; OverrideSearchPath *cur; cur = GetOverrideSearchPath(CurrentMemoryContext); if (path->addCatalog == cur->addCatalog && path->addTemp == cur->addTemp && equal(path->schemas, cur->schemas)) result = true; else result = false; list_free(cur->schemas); pfree(cur); return result; }
Datum pg_collation_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4088 of file namespace.c.
References CollationIsVisible(), COLLOID, ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and SearchSysCacheExists1.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(COLLOID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(CollationIsVisible(oid)); }
Datum pg_conversion_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4099 of file namespace.c.
References ConversionIsVisible(), CONVOID, ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and SearchSysCacheExists1.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(CONVOID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(ConversionIsVisible(oid)); }
Datum pg_function_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4044 of file namespace.c.
References FunctionIsVisible(), ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, PROCOID, and SearchSysCacheExists1.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(FunctionIsVisible(oid)); }
Datum pg_is_other_temp_schema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4160 of file namespace.c.
References isOtherTempNamespace(), PG_GETARG_OID, and PG_RETURN_BOOL.
{ Oid oid = PG_GETARG_OID(0); PG_RETURN_BOOL(isOtherTempNamespace(oid)); }
Datum pg_my_temp_schema | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4154 of file namespace.c.
References myTempNamespace, and PG_RETURN_OID.
{ PG_RETURN_OID(myTempNamespace); }
Datum pg_opclass_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4066 of file namespace.c.
References CLAOID, ObjectIdGetDatum, OpclassIsVisible(), PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and SearchSysCacheExists1.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(CLAOID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(OpclassIsVisible(oid)); }
Datum pg_operator_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4055 of file namespace.c.
References ObjectIdGetDatum, OperatorIsVisible(), OPEROID, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and SearchSysCacheExists1.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(OPEROID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(OperatorIsVisible(oid)); }
Datum pg_opfamily_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4077 of file namespace.c.
References ObjectIdGetDatum, OpfamilyIsVisible(), OPFAMILYOID, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, and SearchSysCacheExists1.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(OPFAMILYOID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(OpfamilyIsVisible(oid)); }
Datum pg_table_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4022 of file namespace.c.
References ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, RelationIsVisible(), RELOID, and SearchSysCacheExists1.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(RelationIsVisible(oid)); }
Datum pg_ts_config_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4143 of file namespace.c.
References ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, TSConfigIsVisible(), and TSCONFIGOID.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(TSCONFIGOID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(TSConfigIsVisible(oid)); }
Datum pg_ts_dict_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4121 of file namespace.c.
References ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, TSDictionaryIsVisible(), and TSDICTOID.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(TSDICTOID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(TSDictionaryIsVisible(oid)); }
Datum pg_ts_parser_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4110 of file namespace.c.
References ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, TSParserIsVisible(), and TSPARSEROID.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(TSPARSEROID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(TSParserIsVisible(oid)); }
Datum pg_ts_template_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4132 of file namespace.c.
References ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, TSTemplateIsVisible(), and TSTEMPLATEOID.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(TSTEMPLATEOID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(TSTemplateIsVisible(oid)); }
Datum pg_type_is_visible | ( | PG_FUNCTION_ARGS | ) |
Definition at line 4033 of file namespace.c.
References ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_BOOL, PG_RETURN_NULL, SearchSysCacheExists1, TypeIsVisible(), and TYPEOID.
{ Oid oid = PG_GETARG_OID(0); if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(oid))) PG_RETURN_NULL(); PG_RETURN_BOOL(TypeIsVisible(oid)); }
void PopOverrideSearchPath | ( | void | ) |
Definition at line 3224 of file namespace.c.
References activeCreationNamespace, activeTempCreationPending, baseCreationNamespace, baseTempCreationPending, OverrideStackEntry::creationNamespace, elog, ERROR, GetCurrentTransactionNestLevel(), linitial, list_delete_first(), list_free(), OverrideStackEntry::nestLevel, NIL, pfree(), and OverrideStackEntry::searchPath.
Referenced by CreateSchemaCommand().
{ OverrideStackEntry *entry; /* Sanity checks. */ if (overrideStack == NIL) elog(ERROR, "bogus PopOverrideSearchPath call"); entry = (OverrideStackEntry *) linitial(overrideStack); if (entry->nestLevel != GetCurrentTransactionNestLevel()) elog(ERROR, "bogus PopOverrideSearchPath call"); /* Pop the stack and free storage. */ overrideStack = list_delete_first(overrideStack); list_free(entry->searchPath); pfree(entry); /* Activate the next level down. */ if (overrideStack) { entry = (OverrideStackEntry *) linitial(overrideStack); activeSearchPath = entry->searchPath; activeCreationNamespace = entry->creationNamespace; activeTempCreationPending = false; /* XXX is this OK? */ } else { /* If not baseSearchPathValid, this is useless but harmless */ activeSearchPath = baseSearchPath; activeCreationNamespace = baseCreationNamespace; activeTempCreationPending = baseTempCreationPending; } }
void PushOverrideSearchPath | ( | OverrideSearchPath * | newpath | ) |
Definition at line 3165 of file namespace.c.
References activeCreationNamespace, activeTempCreationPending, OverrideSearchPath::addCatalog, OverrideSearchPath::addTemp, OverrideStackEntry::creationNamespace, GetCurrentTransactionNestLevel(), lcons(), lcons_oid(), linitial_oid, list_copy(), MemoryContextSwitchTo(), myTempNamespace, OverrideStackEntry::nestLevel, NIL, OidIsValid, palloc(), PG_CATALOG_NAMESPACE, OverrideSearchPath::schemas, OverrideStackEntry::searchPath, and TopMemoryContext.
Referenced by CreateSchemaCommand().
{ OverrideStackEntry *entry; List *oidlist; Oid firstNS; MemoryContext oldcxt; /* * Copy the list for safekeeping, and insert implicitly-searched * namespaces as needed. This code should track recomputeNamespacePath. */ oldcxt = MemoryContextSwitchTo(TopMemoryContext); oidlist = list_copy(newpath->schemas); /* * Remember the first member of the explicit list. */ if (oidlist == NIL) firstNS = InvalidOid; else firstNS = linitial_oid(oidlist); /* * Add any implicitly-searched namespaces to the list. Note these go on * the front, not the back; also notice that we do not check USAGE * permissions for these. */ if (newpath->addCatalog) oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist); if (newpath->addTemp && OidIsValid(myTempNamespace)) oidlist = lcons_oid(myTempNamespace, oidlist); /* * Build the new stack entry, then insert it at the head of the list. */ entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry)); entry->searchPath = oidlist; entry->creationNamespace = firstNS; entry->nestLevel = GetCurrentTransactionNestLevel(); overrideStack = lcons(entry, overrideStack); /* And make it active. */ activeSearchPath = entry->searchPath; activeCreationNamespace = entry->creationNamespace; activeTempCreationPending = false; /* XXX is this OK? */ MemoryContextSwitchTo(oldcxt); }
Definition at line 2797 of file namespace.c.
References activeCreationNamespace, activeTempCreationPending, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, get_namespace_oid(), InitTempTableNamespace(), myTempNamespace, OidIsValid, and recomputeNamespacePath().
Referenced by compute_return_type(), CreateConversionCommand(), CreateFunction(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), DefineType(), and get_other_operator().
{ char *schemaname; Oid namespaceId; /* deconstruct the name list */ DeconstructQualifiedName(names, &schemaname, objname_p); if (schemaname) { /* check for pg_temp alias */ if (strcmp(schemaname, "pg_temp") == 0) { /* Initialize temp namespace if first time through */ if (!OidIsValid(myTempNamespace)) InitTempTableNamespace(); return myTempNamespace; } /* use exact schema given */ namespaceId = get_namespace_oid(schemaname, false); /* we do not check for USAGE rights here! */ } else { /* use the default creation namespace */ recomputeNamespacePath(); if (activeTempCreationPending) { /* Need to initialize temp namespace */ InitTempTableNamespace(); return myTempNamespace; } namespaceId = activeCreationNamespace; if (!OidIsValid(namespaceId)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("no schema has been selected to create in"))); } return namespaceId; }
Definition at line 626 of file namespace.c.
References ereport, errcode(), errmsg(), ERROR, isAnyTempNamespace(), isTempOrToastNamespace(), RangeVar::relpersistence, RELPERSISTENCE_PERMANENT, and RELPERSISTENCE_TEMP.
Referenced by DefineCompositeType(), RangeVarGetAndCheckCreationNamespace(), and transformColumnDefinition().
{ switch (newRelation->relpersistence) { case RELPERSISTENCE_TEMP: if (!isTempOrToastNamespace(nspid)) { if (isAnyTempNamespace(nspid)) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("cannot create relations in temporary schemas of other sessions"))); else ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("cannot create temporary relation in non-temporary schema"))); } break; case RELPERSISTENCE_PERMANENT: if (isTempOrToastNamespace(nspid)) newRelation->relpersistence = RELPERSISTENCE_TEMP; else if (isAnyTempNamespace(nspid)) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("cannot create relations in temporary schemas of other sessions"))); break; default: if (isAnyTempNamespace(nspid)) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("only temporary relations may be created in temporary schemas"))); } }
Oid RangeVarGetAndCheckCreationNamespace | ( | RangeVar * | relation, | |
LOCKMODE | lockmode, | |||
Oid * | existing_relation_id | |||
) |
Definition at line 519 of file namespace.c.
References AccessShareLock, ACL_CREATE, ACL_KIND_CLASS, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, RangeVar::catalogname, ereport, errcode(), errmsg(), ERROR, get_database_name(), get_namespace_name(), get_relname_relid(), GetUserId(), IsBootstrapProcessingMode, LockDatabaseObject(), LockRelationOid(), MyDatabaseId, NamespaceRelationId, NoLock, NULL, OidIsValid, pg_class_ownercheck(), pg_namespace_aclcheck(), RangeVarAdjustRelationPersistence(), RangeVarGetCreationNamespace(), RangeVar::relname, RangeVar::schemaname, SharedInvalidMessageCounter, UnlockDatabaseObject(), and UnlockRelationOid().
Referenced by AlterTableNamespace(), DefineCompositeType(), DefineRelation(), DefineVirtualRelation(), and transformCreateStmt().
{ uint64 inval_count; Oid relid; Oid oldrelid = InvalidOid; Oid nspid; Oid oldnspid = InvalidOid; bool retry = false; /* * We check the catalog name and then ignore it. */ if (relation->catalogname) { if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cross-database references are not implemented: \"%s.%s.%s\"", relation->catalogname, relation->schemaname, relation->relname))); } /* * As in RangeVarGetRelidExtended(), we guard against concurrent DDL * operations by tracking whether any invalidation messages are processed * while we're doing the name lookups and acquiring locks. See comments * in that function for a more detailed explanation of this logic. */ for (;;) { AclResult aclresult; inval_count = SharedInvalidMessageCounter; /* Look up creation namespace and check for existing relation. */ nspid = RangeVarGetCreationNamespace(relation); Assert(OidIsValid(nspid)); if (existing_relation_id != NULL) relid = get_relname_relid(relation->relname, nspid); else relid = InvalidOid; /* * In bootstrap processing mode, we don't bother with permissions or * locking. Permissions might not be working yet, and locking is * unnecessary. */ if (IsBootstrapProcessingMode()) break; /* Check namespace permissions. */ aclresult = pg_namespace_aclcheck(nspid, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_NAMESPACE, get_namespace_name(nspid)); if (retry) { /* If nothing changed, we're done. */ if (relid == oldrelid && nspid == oldnspid) break; /* If creation namespace has changed, give up old lock. */ if (nspid != oldnspid) UnlockDatabaseObject(NamespaceRelationId, oldnspid, 0, AccessShareLock); /* If name points to something different, give up old lock. */ if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock) UnlockRelationOid(oldrelid, lockmode); } /* Lock namespace. */ if (nspid != oldnspid) LockDatabaseObject(NamespaceRelationId, nspid, 0, AccessShareLock); /* Lock relation, if required if and we have permission. */ if (lockmode != NoLock && OidIsValid(relid)) { if (!pg_class_ownercheck(relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, relation->relname); if (relid != oldrelid) LockRelationOid(relid, lockmode); } /* If no invalidation message were processed, we're done! */ if (inval_count == SharedInvalidMessageCounter) break; /* Something may have changed, so recheck our work. */ retry = true; oldrelid = relid; oldnspid = nspid; } RangeVarAdjustRelationPersistence(relation, nspid); if (existing_relation_id != NULL) *existing_relation_id = relid; return nspid; }
Definition at line 432 of file namespace.c.
References activeCreationNamespace, activeTempCreationPending, RangeVar::catalogname, ereport, errcode(), errmsg(), ERROR, get_database_name(), get_namespace_oid(), InitTempTableNamespace(), MyDatabaseId, myTempNamespace, OidIsValid, recomputeNamespacePath(), RangeVar::relname, RangeVar::relpersistence, RELPERSISTENCE_TEMP, and RangeVar::schemaname.
Referenced by RangeVarGetAndCheckCreationNamespace(), and transformColumnDefinition().
{ Oid namespaceId; /* * We check the catalog name and then ignore it. */ if (newRelation->catalogname) { if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cross-database references are not implemented: \"%s.%s.%s\"", newRelation->catalogname, newRelation->schemaname, newRelation->relname))); } if (newRelation->schemaname) { /* check for pg_temp alias */ if (strcmp(newRelation->schemaname, "pg_temp") == 0) { /* Initialize temp namespace if first time through */ if (!OidIsValid(myTempNamespace)) InitTempTableNamespace(); return myTempNamespace; } /* use exact schema given */ namespaceId = get_namespace_oid(newRelation->schemaname, false); /* we do not check for USAGE rights here! */ } else if (newRelation->relpersistence == RELPERSISTENCE_TEMP) { /* Initialize temp namespace if first time through */ if (!OidIsValid(myTempNamespace)) InitTempTableNamespace(); return myTempNamespace; } else { /* use the default creation namespace */ recomputeNamespacePath(); if (activeTempCreationPending) { /* Need to initialize temp namespace */ InitTempTableNamespace(); return myTempNamespace; } namespaceId = activeCreationNamespace; if (!OidIsValid(namespaceId)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("no schema has been selected to create in"))); } /* Note: callers will check for CREATE rights when appropriate */ return namespaceId; }
Oid RangeVarGetRelidExtended | ( | const RangeVar * | relation, | |
LOCKMODE | lockmode, | |||
bool | missing_ok, | |||
bool | nowait, | |||
RangeVarGetRelidCallback | callback, | |||
void * | callback_arg | |||
) |
Definition at line 230 of file namespace.c.
References AcceptInvalidationMessages(), callback(), RangeVar::catalogname, ConditionalLockRelationOid(), ereport, errcode(), errmsg(), ERROR, get_database_name(), get_relname_relid(), LockRelationOid(), LookupExplicitNamespace(), MyDatabaseId, myTempNamespace, NoLock, OidIsValid, RangeVar::relname, RelnameGetRelid(), RangeVar::relpersistence, RELPERSISTENCE_TEMP, RangeVar::schemaname, SharedInvalidMessageCounter, and UnlockRelationOid().
Referenced by AlterTableLookupRelation(), AlterTableNamespace(), cluster(), ExecRefreshMatView(), LockTableCommand(), ReindexIndex(), ReindexTable(), RemoveRelations(), renameatt(), RenameConstraint(), RenameRelation(), RenameRewriteRule(), and renametrig().
{ uint64 inval_count; Oid relId; Oid oldRelId = InvalidOid; bool retry = false; /* * We check the catalog name and then ignore it. */ if (relation->catalogname) { if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cross-database references are not implemented: \"%s.%s.%s\"", relation->catalogname, relation->schemaname, relation->relname))); } /* * DDL operations can change the results of a name lookup. Since all such * operations will generate invalidation messages, we keep track of * whether any such messages show up while we're performing the operation, * and retry until either (1) no more invalidation messages show up or (2) * the answer doesn't change. * * But if lockmode = NoLock, then we assume that either the caller is OK * with the answer changing under them, or that they already hold some * appropriate lock, and therefore return the first answer we get without * checking for invalidation messages. Also, if the requested lock is * already held, no LockRelationOid will not AcceptInvalidationMessages, * so we may fail to notice a change. We could protect against that case * by calling AcceptInvalidationMessages() before beginning this loop, but * that would add a significant amount overhead, so for now we don't. */ for (;;) { /* * Remember this value, so that, after looking up the relation name * and locking its OID, we can check whether any invalidation messages * have been processed that might require a do-over. */ inval_count = SharedInvalidMessageCounter; /* * Some non-default relpersistence value may have been specified. The * parser never generates such a RangeVar in simple DML, but it can * happen in contexts such as "CREATE TEMP TABLE foo (f1 int PRIMARY * KEY)". Such a command will generate an added CREATE INDEX * operation, which must be careful to find the temp table, even when * pg_temp is not first in the search path. */ if (relation->relpersistence == RELPERSISTENCE_TEMP) { if (!OidIsValid(myTempNamespace)) relId = InvalidOid; /* this probably can't happen? */ else { if (relation->schemaname) { Oid namespaceId; namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok); /* * For missing_ok, allow a non-existant schema name to * return InvalidOid. */ if (namespaceId != myTempNamespace) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("temporary tables cannot specify a schema name"))); } relId = get_relname_relid(relation->relname, myTempNamespace); } } else if (relation->schemaname) { Oid namespaceId; /* use exact schema given */ namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok); if (missing_ok && !OidIsValid(namespaceId)) relId = InvalidOid; else relId = get_relname_relid(relation->relname, namespaceId); } else { /* search the namespace path */ relId = RelnameGetRelid(relation->relname); } /* * Invoke caller-supplied callback, if any. * * This callback is a good place to check permissions: we haven't * taken the table lock yet (and it's really best to check permissions * before locking anything!), but we've gotten far enough to know what * OID we think we should lock. Of course, concurrent DDL might * change things while we're waiting for the lock, but in that case * the callback will be invoked again for the new OID. */ if (callback) callback(relation, relId, oldRelId, callback_arg); /* * If no lock requested, we assume the caller knows what they're * doing. They should have already acquired a heavyweight lock on * this relation earlier in the processing of this same statement, so * it wouldn't be appropriate to AcceptInvalidationMessages() here, as * that might pull the rug out from under them. */ if (lockmode == NoLock) break; /* * If, upon retry, we get back the same OID we did last time, then the * invalidation messages we processed did not change the final answer. * So we're done. * * If we got a different OID, we've locked the relation that used to * have this name rather than the one that does now. So release the * lock. */ if (retry) { if (relId == oldRelId) break; if (OidIsValid(oldRelId)) UnlockRelationOid(oldRelId, lockmode); } /* * Lock relation. This will also accept any pending invalidation * messages. If we got back InvalidOid, indicating not found, then * there's nothing to lock, but we accept invalidation messages * anyway, to flush any negative catcache entries that may be * lingering. */ if (!OidIsValid(relId)) AcceptInvalidationMessages(); else if (!nowait) LockRelationOid(relId, lockmode); else if (!ConditionalLockRelationOid(relId, lockmode)) { if (relation->schemaname) ereport(ERROR, (errcode(ERRCODE_LOCK_NOT_AVAILABLE), errmsg("could not obtain lock on relation \"%s.%s\"", relation->schemaname, relation->relname))); else ereport(ERROR, (errcode(ERRCODE_LOCK_NOT_AVAILABLE), errmsg("could not obtain lock on relation \"%s\"", relation->relname))); } /* * If no invalidation message were processed, we're done! */ if (inval_count == SharedInvalidMessageCounter) break; /* * Something may have changed. Let's repeat the name lookup, to make * sure this name still references the same relation it did * previously. */ retry = true; oldRelId = relId; } if (!OidIsValid(relId) && !missing_ok) { if (relation->schemaname) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("relation \"%s.%s\" does not exist", relation->schemaname, relation->relname))); else ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("relation \"%s\" does not exist", relation->relname))); } return relId; }
static void recomputeNamespacePath | ( | void | ) | [static] |
Definition at line 3417 of file namespace.c.
References ACL_USAGE, ACLCHECK_OK, activeCreationNamespace, activeTempCreationPending, AUTHOID, baseCreationNamespace, baseSearchPathValid, baseTempCreationPending, elog, ERROR, get_namespace_oid(), GETSTRUCT, GetUserId(), HeapTupleIsValid, InvokeNamespaceSearchHook, lappend_oid(), lcons_oid(), lfirst, linitial_oid, list_copy(), list_free(), list_member_oid(), MemoryContextSwitchTo(), myTempNamespace, namespace_search_path, namespaceUser, NameStr, NIL, ObjectIdGetDatum, OidIsValid, pfree(), PG_CATALOG_NAMESPACE, pg_namespace_aclcheck(), pstrdup(), ReleaseSysCache(), SearchSysCache1, SplitIdentifierString(), and TopMemoryContext.
Referenced by CollationGetCollid(), CollationIsVisible(), ConversionGetConid(), ConversionIsVisible(), fetch_search_path(), fetch_search_path_array(), FindDefaultConversionProc(), FuncnameGetCandidates(), FunctionIsVisible(), get_collation_oid(), get_conversion_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), GetOverrideSearchPath(), OpclassIsVisible(), OpclassnameGetOpcid(), OperatorIsVisible(), OpernameGetCandidates(), OpernameGetOprid(), OpfamilyIsVisible(), OpfamilynameGetOpfid(), QualifiedNameGetCreationNamespace(), RangeVarGetCreationNamespace(), RelationIsVisible(), RelnameGetRelid(), TSConfigIsVisible(), TSDictionaryIsVisible(), TSParserIsVisible(), TSTemplateIsVisible(), TypeIsVisible(), and TypenameGetTypid().
{ Oid roleid = GetUserId(); char *rawname; List *namelist; List *oidlist; List *newpath; ListCell *l; bool temp_missing; Oid firstNS; MemoryContext oldcxt; /* Do nothing if an override search spec is active. */ if (overrideStack) return; /* Do nothing if path is already valid. */ if (baseSearchPathValid && namespaceUser == roleid) return; /* Need a modifiable copy of namespace_search_path string */ rawname = pstrdup(namespace_search_path); /* Parse string into list of identifiers */ if (!SplitIdentifierString(rawname, ',', &namelist)) { /* syntax error in name list */ /* this should not happen if GUC checked check_search_path */ elog(ERROR, "invalid list syntax"); } /* * Convert the list of names to a list of OIDs. If any names are not * recognizable or we don't have read access, just leave them out of the * list. (We can't raise an error, since the search_path setting has * already been accepted.) Don't make duplicate entries, either. */ oidlist = NIL; temp_missing = false; foreach(l, namelist) { char *curname = (char *) lfirst(l); Oid namespaceId; if (strcmp(curname, "$user") == 0) { /* $user --- substitute namespace matching user name, if any */ HeapTuple tuple; tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid)); if (HeapTupleIsValid(tuple)) { char *rname; rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname); namespaceId = get_namespace_oid(rname, true); ReleaseSysCache(tuple); if (OidIsValid(namespaceId) && !list_member_oid(oidlist, namespaceId) && pg_namespace_aclcheck(namespaceId, roleid, ACL_USAGE) == ACLCHECK_OK && InvokeNamespaceSearchHook(namespaceId, false)) oidlist = lappend_oid(oidlist, namespaceId); } } else if (strcmp(curname, "pg_temp") == 0) { /* pg_temp --- substitute temp namespace, if any */ if (OidIsValid(myTempNamespace)) { if (!list_member_oid(oidlist, myTempNamespace) && InvokeNamespaceSearchHook(myTempNamespace, false)) oidlist = lappend_oid(oidlist, myTempNamespace); } else { /* If it ought to be the creation namespace, set flag */ if (oidlist == NIL) temp_missing = true; } } else { /* normal namespace reference */ namespaceId = get_namespace_oid(curname, true); if (OidIsValid(namespaceId) && !list_member_oid(oidlist, namespaceId) && pg_namespace_aclcheck(namespaceId, roleid, ACL_USAGE) == ACLCHECK_OK && InvokeNamespaceSearchHook(namespaceId, false)) oidlist = lappend_oid(oidlist, namespaceId); } } /* * Remember the first member of the explicit list. (Note: this is * nominally wrong if temp_missing, but we need it anyway to distinguish * explicit from implicit mention of pg_catalog.) */ if (oidlist == NIL) firstNS = InvalidOid; else firstNS = linitial_oid(oidlist); /* * Add any implicitly-searched namespaces to the list. Note these go on * the front, not the back; also notice that we do not check USAGE * permissions for these. */ if (!list_member_oid(oidlist, PG_CATALOG_NAMESPACE)) oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist); if (OidIsValid(myTempNamespace) && !list_member_oid(oidlist, myTempNamespace)) oidlist = lcons_oid(myTempNamespace, oidlist); /* * Now that we've successfully built the new list of namespace OIDs, save * it in permanent storage. */ oldcxt = MemoryContextSwitchTo(TopMemoryContext); newpath = list_copy(oidlist); MemoryContextSwitchTo(oldcxt); /* Now safe to assign to state variables. */ list_free(baseSearchPath); baseSearchPath = newpath; baseCreationNamespace = firstNS; baseTempCreationPending = temp_missing; /* Mark the path valid. */ baseSearchPathValid = true; namespaceUser = roleid; /* And make it active. */ activeSearchPath = baseSearchPath; activeCreationNamespace = baseCreationNamespace; activeTempCreationPending = baseTempCreationPending; /* Clean up. */ pfree(rawname); list_free(namelist); list_free(oidlist); }
Definition at line 693 of file namespace.c.
References elog, ERROR, get_relname_relid(), GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), NameStr, ObjectIdGetDatum, OidIsValid, PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), RELOID, and SearchSysCache1.
Referenced by generate_relation_name(), getRelationDescription(), pg_table_is_visible(), and regclassout().
{ HeapTuple reltup; Form_pg_class relform; Oid relnamespace; bool visible; reltup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(reltup)) elog(ERROR, "cache lookup failed for relation %u", relid); relform = (Form_pg_class) GETSTRUCT(reltup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ relnamespace = relform->relnamespace; if (relnamespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, relnamespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another relation of the same name earlier in the path. So * we must do a slow check for conflicting relations. */ char *relname = NameStr(relform->relname); ListCell *l; visible = false; foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == relnamespace) { /* Found it first in path */ visible = true; break; } if (OidIsValid(get_relname_relid(relname, namespaceId))) { /* Found something else first in path */ break; } } } ReleaseSysCache(reltup); return visible; }
Oid RelnameGetRelid | ( | const char * | relname | ) |
Definition at line 665 of file namespace.c.
References get_relname_relid(), lfirst_oid, OidIsValid, and recomputeNamespacePath().
Referenced by plpgsql_parse_cwordtype(), plpgsql_parse_wordrowtype(), and RangeVarGetRelidExtended().
{ Oid relid; ListCell *l; recomputeNamespacePath(); foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); relid = get_relname_relid(relname, namespaceId); if (OidIsValid(relid)) return relid; } /* Not found in path */ return InvalidOid; }
static void RemoveTempRelations | ( | Oid | tempNamespaceId | ) | [static] |
Definition at line 3785 of file namespace.c.
References deleteWhatDependsOn().
Referenced by InitTempTableNamespace(), RemoveTempRelationsCallback(), and ResetTempTableNamespace().
{ ObjectAddress object; /* * We want to get rid of everything in the target namespace, but not the * namespace itself (deleting it only to recreate it later would be a * waste of cycles). We do this by finding everything that has a * dependency on the namespace. */ object.classId = NamespaceRelationId; object.objectId = tempNamespaceId; object.objectSubId = 0; deleteWhatDependsOn(&object, false); }
static void RemoveTempRelationsCallback | ( | int | code, | |
Datum | arg | |||
) | [static] |
Definition at line 3806 of file namespace.c.
References AbortOutOfAnyTransaction(), CommitTransactionCommand(), myTempNamespace, OidIsValid, RemoveTempRelations(), and StartTransactionCommand().
Referenced by AtEOXact_Namespace().
{ if (OidIsValid(myTempNamespace)) /* should always be true */ { /* Need to ensure we have a usable transaction. */ AbortOutOfAnyTransaction(); StartTransactionCommand(); RemoveTempRelations(myTempNamespace); CommitTransactionCommand(); } }
void ResetTempTableNamespace | ( | void | ) |
Definition at line 3824 of file namespace.c.
References myTempNamespace, OidIsValid, and RemoveTempRelations().
Referenced by DiscardAll(), and DiscardCommand().
{ if (OidIsValid(myTempNamespace)) RemoveTempRelations(myTempNamespace); }
Definition at line 2527 of file namespace.c.
References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1, SearchSysCacheExists2, TSCONFIGNAMENSP, and TSCONFIGOID.
Referenced by pg_ts_config_is_visible(), and regconfigout().
{ HeapTuple tup; Form_pg_ts_config form; Oid namespace; bool visible; tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgid)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search configuration %u", cfgid); form = (Form_pg_ts_config) GETSTRUCT(tup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ namespace = form->cfgnamespace; if (namespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, namespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another configuration of the same name earlier in the * path. So we must do a slow check for conflicting configurations. */ char *name = NameStr(form->cfgname); ListCell *l; visible = false; foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ if (namespaceId == namespace) { /* Found it first in path */ visible = true; break; } if (SearchSysCacheExists2(TSCONFIGNAMENSP, PointerGetDatum(name), ObjectIdGetDatum(namespaceId))) { /* Found something else first in path */ break; } } } ReleaseSysCache(tup); return visible; }
Definition at line 2274 of file namespace.c.
References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1, SearchSysCacheExists2, TSDICTNAMENSP, and TSDICTOID.
Referenced by pg_ts_dict_is_visible(), and regdictionaryout().
{ HeapTuple tup; Form_pg_ts_dict form; Oid namespace; bool visible; tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search dictionary %u", dictId); form = (Form_pg_ts_dict) GETSTRUCT(tup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ namespace = form->dictnamespace; if (namespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, namespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another dictionary of the same name earlier in the path. * So we must do a slow check for conflicting dictionaries. */ char *name = NameStr(form->dictname); ListCell *l; visible = false; foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ if (namespaceId == namespace) { /* Found it first in path */ visible = true; break; } if (SearchSysCacheExists2(TSDICTNAMENSP, PointerGetDatum(name), ObjectIdGetDatum(namespaceId))) { /* Found something else first in path */ break; } } } ReleaseSysCache(tup); return visible; }
Definition at line 2148 of file namespace.c.
References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1, SearchSysCacheExists2, TSPARSERNAMENSP, and TSPARSEROID.
Referenced by pg_ts_parser_is_visible().
{ HeapTuple tup; Form_pg_ts_parser form; Oid namespace; bool visible; tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(prsId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search parser %u", prsId); form = (Form_pg_ts_parser) GETSTRUCT(tup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ namespace = form->prsnamespace; if (namespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, namespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another parser of the same name earlier in the path. So * we must do a slow check for conflicting parsers. */ char *name = NameStr(form->prsname); ListCell *l; visible = false; foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ if (namespaceId == namespace) { /* Found it first in path */ visible = true; break; } if (SearchSysCacheExists2(TSPARSERNAMENSP, PointerGetDatum(name), ObjectIdGetDatum(namespaceId))) { /* Found something else first in path */ break; } } } ReleaseSysCache(tup); return visible; }
Definition at line 2401 of file namespace.c.
References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1, SearchSysCacheExists2, TSTEMPLATENAMENSP, and TSTEMPLATEOID.
Referenced by pg_ts_template_is_visible().
{ HeapTuple tup; Form_pg_ts_template form; Oid namespace; bool visible; tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search template %u", tmplId); form = (Form_pg_ts_template) GETSTRUCT(tup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ namespace = form->tmplnamespace; if (namespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, namespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another template of the same name earlier in the path. So * we must do a slow check for conflicting templates. */ char *name = NameStr(form->tmplname); ListCell *l; visible = false; foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ if (namespaceId == namespace) { /* Found it first in path */ visible = true; break; } if (SearchSysCacheExists2(TSTEMPLATENAMENSP, PointerGetDatum(name), ObjectIdGetDatum(namespaceId))) { /* Found something else first in path */ break; } } } ReleaseSysCache(tup); return visible; }
Definition at line 788 of file namespace.c.
References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1, SearchSysCacheExists2, TYPENAMENSP, and TYPEOID.
Referenced by format_type_internal(), and pg_type_is_visible().
{ HeapTuple typtup; Form_pg_type typform; Oid typnamespace; bool visible; typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); if (!HeapTupleIsValid(typtup)) elog(ERROR, "cache lookup failed for type %u", typid); typform = (Form_pg_type) GETSTRUCT(typtup); recomputeNamespacePath(); /* * Quick check: if it ain't in the path at all, it ain't visible. Items in * the system namespace are surely in the path and so we needn't even do * list_member_oid() for them. */ typnamespace = typform->typnamespace; if (typnamespace != PG_CATALOG_NAMESPACE && !list_member_oid(activeSearchPath, typnamespace)) visible = false; else { /* * If it is in the path, it might still not be visible; it could be * hidden by another type of the same name earlier in the path. So we * must do a slow check for conflicting types. */ char *typname = NameStr(typform->typname); ListCell *l; visible = false; foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); if (namespaceId == typnamespace) { /* Found it first in path */ visible = true; break; } if (SearchSysCacheExists2(TYPENAMENSP, PointerGetDatum(typname), ObjectIdGetDatum(namespaceId))) { /* Found something else first in path */ break; } } } ReleaseSysCache(typtup); return visible; }
Oid TypenameGetTypid | ( | const char * | typname | ) |
Definition at line 759 of file namespace.c.
References GetSysCacheOid2, lfirst_oid, ObjectIdGetDatum, OidIsValid, PointerGetDatum, recomputeNamespacePath(), and TYPENAMENSP.
Referenced by LookupTypeName().
{ Oid typid; ListCell *l; recomputeNamespacePath(); foreach(l, activeSearchPath) { Oid namespaceId = lfirst_oid(l); typid = GetSysCacheOid2(TYPENAMENSP, PointerGetDatum(typname), ObjectIdGetDatum(namespaceId)); if (OidIsValid(typid)) return typid; } /* Not found in path */ return InvalidOid; }
Oid activeCreationNamespace = InvalidOid [static] |
Definition at line 133 of file namespace.c.
Referenced by AtEOSubXact_Namespace(), AtEOXact_Namespace(), fetch_search_path(), GetOverrideSearchPath(), InitializeSearchPath(), PopOverrideSearchPath(), PushOverrideSearchPath(), QualifiedNameGetCreationNamespace(), RangeVarGetCreationNamespace(), and recomputeNamespacePath().
List* activeSearchPath = NIL [static] |
Definition at line 130 of file namespace.c.
bool activeTempCreationPending = false [static] |
Definition at line 136 of file namespace.c.
Referenced by AtEOSubXact_Namespace(), AtEOXact_Namespace(), fetch_search_path(), InitializeSearchPath(), PopOverrideSearchPath(), PushOverrideSearchPath(), QualifiedNameGetCreationNamespace(), RangeVarGetCreationNamespace(), and recomputeNamespacePath().
Oid baseCreationNamespace = InvalidOid [static] |
Definition at line 142 of file namespace.c.
Referenced by AtEOSubXact_Namespace(), AtEOXact_Namespace(), InitializeSearchPath(), PopOverrideSearchPath(), and recomputeNamespacePath().
List* baseSearchPath = NIL [static] |
Definition at line 140 of file namespace.c.
bool baseSearchPathValid = true [static] |
Definition at line 149 of file namespace.c.
Referenced by assign_search_path(), AtEOSubXact_Namespace(), AtEOXact_Namespace(), InitializeSearchPath(), InitTempTableNamespace(), NamespaceCallback(), and recomputeNamespacePath().
bool baseTempCreationPending = false [static] |
Definition at line 144 of file namespace.c.
Referenced by AtEOSubXact_Namespace(), AtEOXact_Namespace(), InitializeSearchPath(), PopOverrideSearchPath(), and recomputeNamespacePath().
Oid myTempNamespace = InvalidOid [static] |
Definition at line 177 of file namespace.c.
Referenced by AtEOSubXact_Namespace(), AtEOXact_Namespace(), CollationGetCollid(), ConversionGetConid(), fetch_search_path_array(), FindDefaultConversionProc(), FuncnameGetCandidates(), get_collation_oid(), get_conversion_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), GetOverrideSearchPath(), InitTempTableNamespace(), isTempNamespace(), isTempOrToastNamespace(), LookupCreationNamespace(), LookupExplicitNamespace(), LookupNamespaceNoError(), OpclassnameGetOpcid(), OpernameGetCandidates(), OpernameGetOprid(), OpfamilynameGetOpfid(), pg_my_temp_schema(), PushOverrideSearchPath(), QualifiedNameGetCreationNamespace(), RangeVarGetCreationNamespace(), RangeVarGetRelidExtended(), recomputeNamespacePath(), RemoveTempRelationsCallback(), ResetTempTableNamespace(), TSConfigIsVisible(), TSDictionaryIsVisible(), TSParserIsVisible(), and TSTemplateIsVisible().
SubTransactionId myTempNamespaceSubID = InvalidSubTransactionId [static] |
Definition at line 181 of file namespace.c.
Referenced by AtEOSubXact_Namespace(), AtEOXact_Namespace(), and InitTempTableNamespace().
Oid myTempToastNamespace = InvalidOid [static] |
Definition at line 179 of file namespace.c.
Referenced by AtEOSubXact_Namespace(), AtEOXact_Namespace(), GetTempToastNamespace(), InitTempTableNamespace(), isTempOrToastNamespace(), and isTempToastNamespace().
char* namespace_search_path = NULL |
Definition at line 187 of file namespace.c.
Referenced by recomputeNamespacePath().
Oid namespaceUser = InvalidOid [static] |
Definition at line 146 of file namespace.c.
Referenced by InitializeSearchPath(), and recomputeNamespacePath().
List* overrideStack = NIL [static] |
Definition at line 160 of file namespace.c.