if (relation->schemaname)
ereport(elevel,
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
errmsg("could not obtain lock on relation \"%s.%s\"",
relation->schemaname, relation->relname))); else
ereport(elevel,
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
errmsg("could not obtain lock on relation \"%s\"",
relation->relname)));
return InvalidOid;
}
/* *Ifnoinvalidationmessagewereprocessed,we'redone!
*/ if (inval_count == SharedInvalidMessageCounter) break;
if (!OidIsValid(relId))
{ int elevel = missing_ok ? DEBUG1 : ERROR;
if (relation->schemaname)
ereport(elevel,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation \"%s.%s\" does not exist",
relation->schemaname, relation->relname))); else
ereport(elevel,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation \"%s\" does not exist",
relation->relname)));
} return relId;
}
/* *RangeVarGetCreationNamespace *GivenaRangeVardescribingato-be-createdrelation, *choosewhichnamespacetocreateitin. * *Note:callingthismayresultinaCommandCounterIncrementoperation. *Thatwillhappenonthefirstrequestforatemptableinanyparticular *backendrun;wewillneedtoeithercreateorcleanoutthetempschema.
*/
Oid
RangeVarGetCreationNamespace(const RangeVar *newRelation)
{
Oid namespaceId;
/* *Wecheckthecatalognameandthenignoreit.
*/ 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 */
AccessTempTableNamespace(false); return myTempNamespace;
} /* use exact schema given */
namespaceId = get_namespace_oid(newRelation->schemaname, false); /* we do not check for USAGE rights here! */
} elseif (newRelation->relpersistence == RELPERSISTENCE_TEMP)
{ /* Initialize temp namespace */
AccessTempTableNamespace(false); return myTempNamespace;
} else
{ /* use the default creation namespace */
recomputeNamespacePath(); if (activeTempCreationPending)
{ /* Need to initialize temp namespace */
AccessTempTableNamespace(true); 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;
}
/* *RangeVarGetAndCheckCreationNamespace * *ThisfunctionreturnstheOIDofthenamespaceinwhichanewrelation *withagivennameshouldbecreated.IftheuserdoesnothaveCREATE *permissiononthetargetnamespace,thisfunctionwillinsteadsignal *anERROR. * *Ifnon-NULL,*existing_relation_idissettotheOIDofanyexistingrelation *withthesamenamewhichalreadyexistsinthatnamespace,ortoInvalidOid *ifnosuchrelationexists. * *Iflockmode!=NoLock,thespecifiedlockmodeisacquiredontheexisting *relation,ifany,providedthatthecurrentuserownsthetargetrelation. *However,iflockmode!=NoLockandtheuserdoesnotownthetarget *relation,wethrowanERROR,aswemustnottrytolockrelationsthe *userdoesnothavepermissionson. * *Asasideeffect,thisfunctionacquiresAccessShareLockonthetarget *namespace.Withoutthis,thenamespacecouldbedroppedbeforeour *transactioncommits,leavingbehindrelationswithrelnamespacepointing *toano-longer-existentnamespace. * *Asafurtherside-effect,iftheselectednamespaceisatemporarynamespace, *wemarktheRangeVarasRELPERSISTENCE_TEMP.
*/
Oid
RangeVarGetAndCheckCreationNamespace(RangeVar *relation,
LOCKMODE lockmode,
Oid *existing_relation_id)
{
uint64 inval_count;
Oid relid;
Oid oldrelid = InvalidOid;
Oid nspid;
Oid oldnspid = InvalidOid; bool retry = false;
/* *Wecheckthecatalognameandthenignoreit.
*/ 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)));
}
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 relation, if required if and we have permission. */ if (lockmode != NoLock && OidIsValid(relid))
{ if (!object_ownercheck(RelationRelationId, relid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relid)),
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;
}
/* *Adjusttherelpersistenceforanabout-to-be-createdrelationbasedonthe *creationnamespace,andthrowanerrorforinvalidcombinations.
*/ void
RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
{ switch (newRelation->relpersistence)
{ case RELPERSISTENCE_TEMP: if (!isTempOrTempToastNamespace(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 (isTempOrTempToastNamespace(nspid))
newRelation->relpersistence = RELPERSISTENCE_TEMP; elseif (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")));
}
}
/* *RelnameGetRelid *Trytoresolveanunqualifiedrelationname. *ReturnsOIDifrelationfoundinsearchpath,elseInvalidOid.
*/
Oid
RelnameGetRelid(constchar *relname)
{
Oid relid;
ListCell *l;
recomputeNamespacePath();
foreach(l, activeSearchPath)
{
Oid namespaceId = lfirst_oid(l);
relid = get_relname_relid(relname, namespaceId); if (OidIsValid(relid)) return relid;
}
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;
}
}
}
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;
}
}
}
/* deconstruct the name list */
DeconstructQualifiedName(names, &schemaname, &funcname);
if (schemaname)
{ /* use exact schema given */
namespaceId = LookupExplicitNamespace(schemaname, missing_ok); if (!OidIsValid(namespaceId)) return NULL;
} 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);
Oid *proargtypes = procform->proargtypes.values; 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
{ /* *Consideronlyprocsthatareinthesearchpathandarenotin *thetempnamespace.
*/
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 */
}
/* *IfweareaskedtomatchtoOUTarguments,thenusethe *proallargtypesarray(whichincludesthose);otherwiseuse *proargtypes(whichdoesn't).Ofcourse,ifproallargtypesisnull, *wealwaysuseproargtypes.
*/ if (include_out_arguments)
{
Datum proallargtypes; bool isNull;
if (preference > 0)
{ /* keep previous result */
pfree(newResult); continue;
} elseif (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;
}
}
}
/* Ignore this function if its proargnames is null */
(void) SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proargnames,
&isnull); if (isnull) returnfalse;
/* 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 params, except with include_out_arguments */ if (!include_out_arguments &&
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]) returnfalse;
arggiven[pp] = true;
(*argnumbers)[ap] = pp;
found = true; break;
} /* increase pp only for considered parameters */
pp++;
} /* if name isn't in proargnames, fail */ if (!found) returnfalse;
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) returnfalse;
(*argnumbers)[ap++] = pp;
}
}
Assert(ap == pronargs); /* processed all function parameters */
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;
}
/* *OpernameGetOprid *Givenapossibly-qualifiedoperatornameandexactinputdatatypes, *lookuptheoperator.ReturnsInvalidOidifnotfound. * *Passoprleft=InvalidOidforaprefixop. * *Iftheoperatornameisnotschema-qualified,itissoughtinthecurrent *namespacesearchpath.Ifthenameisschema-qualifiedandthegiven *schemadoesnotexist,InvalidOidisreturned.
*/
Oid
OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
{ 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;
namespaceId = LookupExplicitNamespace(schemaname, true); if (OidIsValid(namespaceId))
{
HeapTuple opertup;
opertup = SearchSysCache4(OPERNAMENSP,
CStringGetDatum(opername),
ObjectIdGetDatum(oprleft),
ObjectIdGetDatum(oprright),
ObjectIdGetDatum(namespaceId)); if (HeapTupleIsValid(opertup))
{
Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup);
Oid result = operclass->oid;
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;
}
/* deconstruct the name list */
DeconstructQualifiedName(names, &schemaname, &opername);
if (schemaname)
{ /* use exact schema given */
namespaceId = LookupExplicitNamespace(schemaname, missing_schema_ok); if (missing_schema_ok && !OidIsValid(namespaceId)) return NULL;
} else
{ /* flag to indicate we need namespace search */
namespaceId = InvalidOid;
recomputeNamespacePath();
}
/* Search syscache by name only */
catlist = SearchSysCacheList1(OPERNAMENSP, CStringGetDatum(opername));
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
{ /* *Consideronlyopersthatareinthesearchpathandarenotin *thetempnamespace.
*/
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 */
if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */
stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
PointerGetDatum(stats_name),
ObjectIdGetDatum(namespaceId)); if (OidIsValid(stats_oid)) break;
}
}
if (!OidIsValid(stats_oid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("statistics object \"%s\" does not exist",
NameListToString(names))));
visible = false;
foreach(l, activeSearchPath)
{
Oid namespaceId = lfirst_oid(l);
if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */
if (namespaceId == stxnamespace)
{ /* Found it first in path */
visible = true; break;
} if (SearchSysCacheExists2(STATEXTNAMENSP,
PointerGetDatum(stxname),
ObjectIdGetDatum(namespaceId)))
{ /* Found something else first in path */ break;
}
}
}
ReleaseSysCache(stxtup);
return visible;
}
/* *get_ts_parser_oid-findaTSparserbypossiblyqualifiedname * *Ifnotfound,returnsInvalidOidifmissing_ok,elsethrowserror
*/
Oid
get_ts_parser_oid(List *names, bool missing_ok)
{ 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, Anum_pg_ts_parser_oid,
PointerGetDatum(parser_name),
ObjectIdGetDatum(namespaceId));
} else
{ /* search for it in search path */
recomputeNamespacePath();
if (!OidIsValid(prsoid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("text search parser \"%s\" does not exist",
NameListToString(names))));
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;
}
/* *get_ts_dict_oid-findaTSdictionarybypossiblyqualifiedname * *Ifnotfound,returnsInvalidOidifmissing_ok,elsethrowserror
*/
Oid
get_ts_dict_oid(List *names, bool missing_ok)
{ 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, Anum_pg_ts_dict_oid,
PointerGetDatum(dict_name),
ObjectIdGetDatum(namespaceId));
} else
{ /* search for it in search path */
recomputeNamespacePath();
if (!OidIsValid(dictoid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("text search dictionary \"%s\" does not exist",
NameListToString(names))));
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;
}
/* *get_ts_template_oid-findaTStemplatebypossiblyqualifiedname * *Ifnotfound,returnsInvalidOidifmissing_ok,elsethrowserror
*/
Oid
get_ts_template_oid(List *names, bool missing_ok)
{ 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, Anum_pg_ts_template_oid,
PointerGetDatum(template_name),
ObjectIdGetDatum(namespaceId));
} else
{ /* search for it in search path */
recomputeNamespacePath();
if (!OidIsValid(tmploid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("text search template \"%s\" does not exist",
NameListToString(names))));
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;
}
/* *get_ts_config_oid-findaTSconfigbypossiblyqualifiedname * *Ifnotfound,returnsInvalidOidifmissing_ok,elsethrowserror
*/
Oid
get_ts_config_oid(List *names, bool missing_ok)
{ 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, Anum_pg_ts_config_oid,
PointerGetDatum(config_name),
ObjectIdGetDatum(namespaceId));
} else
{ /* search for it in search path */
recomputeNamespacePath();
if (!OidIsValid(cfgoid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("text search configuration \"%s\" does not exist",
NameListToString(names))));
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;
}
}
}
/* *Commonchecksonswitchingnamespaces. * *Wecomplainifeithertheoldornewnamespacesisatemporaryschema *(ortemporarytoastschema),orifeithertheoldornewnamespacesisthe *TOASTschema.
*/ void
CheckSetNamespace(Oid oldNspOid, Oid 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")));
}
/* *QualifiedNameGetCreationNamespace *Givenapossibly-qualifiednameforanobject(inList-of-Strings *format),determinewhatnamespacetheobjectshouldbecreatedin. *Alsoextractandreturntheobjectname(lastcomponentoflist). * *Note:thisdoesnotapplyanypermissionscheck.Callersmustcheck *forCREATErightsontheselectednamespacewhenappropriate. * *Note:callingthismayresultinaCommandCounterIncrementoperation, *ifwehavetocreateorcleanoutthetempnamespace.
*/
Oid
QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
{ 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 */
AccessTempTableNamespace(false); 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 */
AccessTempTableNamespace(true); return myTempNamespace;
}
namespaceId = activeCreationNamespace; if (!OidIsValid(namespaceId))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("no schema has been selected to create in")));
}
return namespaceId;
}
/* *get_namespace_oid-givenanamespacename,lookuptheOID * *Ifmissing_okisfalse,throwanerrorifnamespacenamenotfound.If *true,justreturnInvalidOid.
*/
Oid
get_namespace_oid(constchar *nspname, bool missing_ok)
{
Oid oid;
oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid,
CStringGetDatum(nspname)); if (!OidIsValid(oid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("schema \"%s\" does not exist", nspname)));
/* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
nspname = get_namespace_name(namespaceId); if (!nspname) returnfalse; /* no such namespace? */
result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
(strncmp(nspname, "pg_toast_temp_", 14) == 0);
pfree(nspname); return result;
}
/* *isOtherTempNamespace-isthegivennamespacesomeotherbackend's *temporary-tablenamespace(includingtemporary-toast-tablenamespaces)? * *Note:formostpurposesintheCcode,thisfunctionisobsolete.Use *RELATION_IS_OTHER_TEMP()insteadtodetectnon-localtemprelations.
*/ bool
isOtherTempNamespace(Oid namespaceId)
{ /* If it's my own temp namespace, say "false" */ if (isTempOrTempToastNamespace(namespaceId)) returnfalse; /* Else, if it's any temp namespace, say "true" */ return isAnyTempNamespace(namespaceId);
}
/* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
nspname = get_namespace_name(namespaceId); if (!nspname) return INVALID_PROC_NUMBER; /* no such namespace? */ if (strncmp(nspname, "pg_temp_", 8) == 0)
result = atoi(nspname + 8); elseif (strncmp(nspname, "pg_toast_temp_", 14) == 0)
result = atoi(nspname + 14); else
result = INVALID_PROC_NUMBER;
pfree(nspname); return result;
}
/* *GetTempNamespaceState-fetchstatusofsession'stemporarynamespace * *Thisisusedforconveyingstatetoaparallelworker,andisnotmeant *forgeneral-purposeaccess.
*/ void
GetTempNamespaceState(Oid *tempNamespaceId, Oid *tempToastNamespaceId)
{ /* Return namespace OIDs, or 0 if session has not created temp namespace */
*tempNamespaceId = myTempNamespace;
*tempToastNamespaceId = myTempToastNamespace;
}
/* *SetTempNamespaceState-setstatusofsession'stemporarynamespace * *Thisisusedforconveyingstatetoaparallelworker,andisnotmeantfor *general-purposeaccess.BytransferringthesenamespaceOIDstoworkers, *weensuretheywillhavethesamenotionofthesearchpathastheirleader *does.
*/ void
SetTempNamespaceState(Oid tempNamespaceId, Oid tempToastNamespaceId)
{ /* Worker should not have created its own namespaces ... */
Assert(myTempNamespace == InvalidOid);
Assert(myTempToastNamespace == InvalidOid);
Assert(myTempNamespaceSubID == InvalidSubTransactionId);
/* Assign same namespace OIDs that leader has */
myTempNamespace = tempNamespaceId;
myTempToastNamespace = tempToastNamespaceId;
/* Quick out if already known equal to active path. */ if (path->generation == activePathGeneration) returntrue;
/* We scan down the activeSearchPath to see if it matches the input. */
lc = list_head(activeSearchPath);
/* If path->addTemp, first item should be my temp namespace. */ if (path->addTemp)
{ if (lc && lfirst_oid(lc) == myTempNamespace)
lc = lnext(activeSearchPath, lc); else returnfalse;
} /* If path->addCatalog, next item should be pg_catalog. */ if (path->addCatalog)
{ if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
lc = lnext(activeSearchPath, lc); else returnfalse;
} /* We should now be looking at the activeCreationNamespace. */ if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid)) returnfalse; /* The remainder of activeSearchPath should match path->schemas. */
foreach(lcp, path->schemas)
{ if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
lc = lnext(activeSearchPath, lc); else returnfalse;
} if (lc) returnfalse;
/* *get_collation_oid-findacollationbypossiblyqualifiedname * *Notethatthiswillonlyfindcollationsthatworkwiththecurrent *database'sencoding.
*/
Oid
get_collation_oid(List *collname, bool missing_ok)
{ char *schemaname; char *collation_name;
int32 dbencoding = GetDatabaseEncoding();
Oid namespaceId;
Oid colloid;
ListCell *l;
/* deconstruct the name list */
DeconstructQualifiedName(collname, &schemaname, &collation_name);
if (schemaname)
{ /* use exact schema given */
namespaceId = LookupExplicitNamespace(schemaname, missing_ok); if (missing_ok && !OidIsValid(namespaceId)) return InvalidOid;
colloid = lookup_collation(collation_name, namespaceId, dbencoding); if (OidIsValid(colloid)) return colloid;
} else
{ /* search for it in search path */
recomputeNamespacePath();
/* Not found in path */ if (!missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("collation \"%s\" for encoding \"%s\" does not exist",
NameListToString(collname), GetDatabaseEncodingName()))); return InvalidOid;
}
/* *get_conversion_oid-findaconversionbypossiblyqualifiedname
*/
Oid
get_conversion_oid(List *conname, bool missing_ok)
{ char *schemaname; char *conversion_name;
Oid namespaceId;
Oid conoid = InvalidOid;
ListCell *l;
/* deconstruct the name list */
DeconstructQualifiedName(conname, &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, Anum_pg_conversion_oid,
PointerGetDatum(conversion_name),
ObjectIdGetDatum(namespaceId));
} else
{ /* search for it in search path */
recomputeNamespacePath();
/* Not found in path */ if (!OidIsValid(conoid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("conversion \"%s\" does not exist",
NameListToString(conname)))); return conoid;
}
/* *FindDefaultConversionProc-finddefaultencodingconversionproc
*/
Oid
FindDefaultConversionProc(int32 for_encoding, int32 to_encoding)
{
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;
}
/* *LookupnamespaceIDsandperformACLchecks.Returnnewly-allocatedlist.
*/ static List *
preprocessNamespacePath(constchar *searchPath, Oid roleid, bool *temp_missing)
{ char *rawname;
List *namelist;
List *oidlist;
ListCell *l;
/* Need a modifiable copy */
rawname = pstrdup(searchPath);
/* 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");
}
/* Must save OID list in permanent storage. */
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
newpath = list_copy(entry->finalPath);
MemoryContextSwitchTo(oldcxt);
/* Now safe to assign to state variables. */
list_free(baseSearchPath);
baseSearchPath = newpath;
baseCreationNamespace = entry->firstNS;
baseTempCreationPending = entry->temp_missing;
}
/* Mark the path valid. */
baseSearchPathValid = true;
namespaceUser = roleid;
/* And make it active. */
activeSearchPath = baseSearchPath;
activeCreationNamespace = baseCreationNamespace;
activeTempCreationPending = baseTempCreationPending;
/* *Bumpthegenerationonlyifsomethingactuallychanged.(Noticethat *whatwecomparedtowastheoldstateofthebasepathvariables.)
*/ if (pathChanged)
activePathGeneration++;
}
/* *Callbacktoremovetemprelationsatbackendexit.
*/ staticvoid
RemoveTempRelationsCallback(int code, Datum arg)
{ if (OidIsValid(myTempNamespace)) /* should always be true */
{ /* Need to ensure we have a usable transaction. */
AbortOutOfAnyTransaction();
StartTransactionCommand();
PushActiveSnapshot(GetTransactionSnapshot());
rawname = pstrdup(searchPath); /* need a modifiable copy */
/* 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); returnfalse;
}
pfree(rawname);
list_free(namelist);
/* OK to create empty cache entry */ if (use_cache)
(void) spcache_insert(searchPath, roleid);
returntrue;
}
/* assign_hook: do extra actions as needed */ void
assign_search_path(constchar *newval, void *extra)
{ /* don't access search_path during bootstrap */
Assert(!IsBootstrapProcessingMode());
result = list_copy(activeSearchPath); if (!includeImplicit)
{ while (result && linitial_oid(result) != activeCreationNamespace)
result = list_delete_first(result);
}
return result;
}
/* *Fetchtheactivesearchpathintoacaller-allocatedarrayofOIDs. *Returnsthenumberofpathentries.(Ifthisismorethansarray_len, *thenthedatadidn'tfitandisnotallstored.) * *Thereturnedlistalwaysincludestheimplicitly-prependednamespaces, *butneverincludesthetempnamespace.(Thisissuitableforexisting *users,whichwouldwanttoignorethetempnamespaceanyway.)This *definitionallowsustonotworryaboutinitializingthetempnamespace.
*/ int
fetch_search_path_array(Oid *sarray, int sarray_len)
{ 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++;
}
Datum
pg_table_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = RelationIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_type_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = TypeIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_function_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = FunctionIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_operator_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = OperatorIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_opclass_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = OpclassIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_opfamily_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = OpfamilyIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_collation_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = CollationIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_conversion_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = ConversionIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_statistics_obj_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = StatisticsObjIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_ts_parser_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = TSParserIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_ts_dict_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = TSDictionaryIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_ts_template_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = TSTemplateIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_ts_config_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0); bool result; bool is_missing = false;
result = TSConfigIsVisibleExt(oid, &is_missing);
if (is_missing)
PG_RETURN_NULL();
PG_RETURN_BOOL(result);
}
Datum
pg_my_temp_schema(PG_FUNCTION_ARGS)
{
PG_RETURN_OID(myTempNamespace);
}
Datum
pg_is_other_temp_schema(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0);
PG_RETURN_BOOL(isOtherTempNamespace(oid));
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.209Bemerkung:
(vorverarbeitet am 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.