mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Centralize some ALTER <whatever> .. SET SCHEMA checks.
Any flavor of ALTER <whatever> .. SET SCHEMA fails if (1) the object is already in the new schema, (2) either the old or new schema is a temp schema, or (3) either the old or new schema is the TOAST schema. Extraced from a patch by Dimitri Fontaine, with additional hacking by me.
This commit is contained in:
@ -2684,6 +2684,21 @@ getObjectDescription(const ObjectAddress *object)
|
|||||||
return buffer.data;
|
return buffer.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getObjectDescriptionOids: as above, except the object is specified by Oids
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
getObjectDescriptionOids(Oid classid, Oid objid)
|
||||||
|
{
|
||||||
|
ObjectAddress address;
|
||||||
|
|
||||||
|
address.classId = classid;
|
||||||
|
address.objectId = objid;
|
||||||
|
address.objectSubId = 0;
|
||||||
|
|
||||||
|
return getObjectDescription(&address);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subroutine for getObjectDescription: describe a relation
|
* subroutine for getObjectDescription: describe a relation
|
||||||
*/
|
*/
|
||||||
|
@ -2339,6 +2339,40 @@ LookupCreationNamespace(const char *nspname)
|
|||||||
return namespaceId;
|
return namespaceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common checks on switching namespaces.
|
||||||
|
*
|
||||||
|
* We complain if (1) the old and new namespaces are the same, (2) either the
|
||||||
|
* old or new namespaces is a temporary schema (or temporary toast schema), or
|
||||||
|
* (3) either the old or new namespaces is the TOAST schema.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
CheckSetNamespace(Oid oldNspOid, Oid nspOid, Oid classid, Oid objid)
|
||||||
|
{
|
||||||
|
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")));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* QualifiedNameGetCreationNamespace
|
* QualifiedNameGetCreationNamespace
|
||||||
* Given a possibly-qualified name for an object (in List-of-Values
|
* Given a possibly-qualified name for an object (in List-of-Values
|
||||||
|
@ -1899,24 +1899,8 @@ AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
|
|||||||
/* get schema OID and check its permissions */
|
/* get schema OID and check its permissions */
|
||||||
nspOid = LookupCreationNamespace(newschema);
|
nspOid = LookupCreationNamespace(newschema);
|
||||||
|
|
||||||
if (oldNspOid == nspOid)
|
/* common checks on switching namespaces */
|
||||||
ereport(ERROR,
|
CheckSetNamespace(oldNspOid, nspOid, ProcedureRelationId, procOid);
|
||||||
(errcode(ERRCODE_DUPLICATE_FUNCTION),
|
|
||||||
errmsg("function \"%s\" is already in schema \"%s\"",
|
|
||||||
NameListToString(name),
|
|
||||||
newschema)));
|
|
||||||
|
|
||||||
/* 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")));
|
|
||||||
|
|
||||||
/* check for duplicate name (more friendly than unique-index failure) */
|
/* check for duplicate name (more friendly than unique-index failure) */
|
||||||
if (SearchSysCacheExists3(PROCNAMEARGSNSP,
|
if (SearchSysCacheExists3(PROCNAMEARGSNSP,
|
||||||
|
@ -8114,24 +8114,8 @@ AlterTableNamespace(RangeVar *relation, const char *newschema,
|
|||||||
/* get schema OID and check its permissions */
|
/* get schema OID and check its permissions */
|
||||||
nspOid = LookupCreationNamespace(newschema);
|
nspOid = LookupCreationNamespace(newschema);
|
||||||
|
|
||||||
if (oldNspOid == nspOid)
|
/* common checks on switching namespaces */
|
||||||
ereport(ERROR,
|
CheckSetNamespace(oldNspOid, nspOid, RelationRelationId, relid);
|
||||||
(errcode(ERRCODE_DUPLICATE_TABLE),
|
|
||||||
errmsg("relation \"%s\" is already in schema \"%s\"",
|
|
||||||
RelationGetRelationName(rel),
|
|
||||||
newschema)));
|
|
||||||
|
|
||||||
/* 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")));
|
|
||||||
|
|
||||||
/* OK, modify the pg_class row and pg_depend entry */
|
/* OK, modify the pg_class row and pg_depend entry */
|
||||||
classRel = heap_open(RelationRelationId, RowExclusiveLock);
|
classRel = heap_open(RelationRelationId, RowExclusiveLock);
|
||||||
|
@ -2828,24 +2828,8 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
|
|||||||
oldNspOid = typform->typnamespace;
|
oldNspOid = typform->typnamespace;
|
||||||
arrayOid = typform->typarray;
|
arrayOid = typform->typarray;
|
||||||
|
|
||||||
if (oldNspOid == nspOid)
|
/* common checks on switching namespaces */
|
||||||
ereport(ERROR,
|
CheckSetNamespace(oldNspOid, nspOid, TypeRelationId, typeOid);
|
||||||
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
||||||
errmsg("type %s is already in schema \"%s\"",
|
|
||||||
format_type_be(typeOid),
|
|
||||||
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")));
|
|
||||||
|
|
||||||
/* check for duplicate name (more friendly than unique-index failure) */
|
/* check for duplicate name (more friendly than unique-index failure) */
|
||||||
if (SearchSysCacheExists2(TYPENAMENSP,
|
if (SearchSysCacheExists2(TYPENAMENSP,
|
||||||
|
@ -165,6 +165,7 @@ extern void recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
|
|||||||
extern ObjectClass getObjectClass(const ObjectAddress *object);
|
extern ObjectClass getObjectClass(const ObjectAddress *object);
|
||||||
|
|
||||||
extern char *getObjectDescription(const ObjectAddress *object);
|
extern char *getObjectDescription(const ObjectAddress *object);
|
||||||
|
extern char *getObjectDescriptionOids(Oid classid, Oid objid);
|
||||||
|
|
||||||
extern ObjectAddresses *new_object_addresses(void);
|
extern ObjectAddresses *new_object_addresses(void);
|
||||||
|
|
||||||
|
@ -94,6 +94,8 @@ extern Oid LookupExplicitNamespace(const char *nspname);
|
|||||||
extern Oid get_namespace_oid(const char *nspname, bool missing_ok);
|
extern Oid get_namespace_oid(const char *nspname, bool missing_ok);
|
||||||
|
|
||||||
extern Oid LookupCreationNamespace(const char *nspname);
|
extern Oid LookupCreationNamespace(const char *nspname);
|
||||||
|
extern void CheckSetNamespace(Oid oldNspOid, Oid nspOid, Oid classid,
|
||||||
|
Oid objid);
|
||||||
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
|
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
|
||||||
extern RangeVar *makeRangeVarFromNameList(List *names);
|
extern RangeVar *makeRangeVarFromNameList(List *names);
|
||||||
extern char *NameListToString(List *names);
|
extern char *NameListToString(List *names);
|
||||||
|
Reference in New Issue
Block a user