Skip to content

Commit 44475e7

Browse files
committed
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.
1 parent 5272d79 commit 44475e7

File tree

7 files changed

+58
-54
lines changed

7 files changed

+58
-54
lines changed

src/backend/catalog/dependency.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2684,6 +2684,21 @@ getObjectDescription(const ObjectAddress *object)
26842684
return buffer.data;
26852685
}
26862686

2687+
/*
2688+
* getObjectDescriptionOids: as above, except the object is specified by Oids
2689+
*/
2690+
char *
2691+
getObjectDescriptionOids(Oid classid, Oid objid)
2692+
{
2693+
ObjectAddress address;
2694+
2695+
address.classId = classid;
2696+
address.objectId = objid;
2697+
address.objectSubId = 0;
2698+
2699+
return getObjectDescription(&address);
2700+
}
2701+
26872702
/*
26882703
* subroutine for getObjectDescription: describe a relation
26892704
*/

src/backend/catalog/namespace.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,6 +2339,40 @@ LookupCreationNamespace(const char *nspname)
23392339
return namespaceId;
23402340
}
23412341

2342+
/*
2343+
* Common checks on switching namespaces.
2344+
*
2345+
* We complain if (1) the old and new namespaces are the same, (2) either the
2346+
* old or new namespaces is a temporary schema (or temporary toast schema), or
2347+
* (3) either the old or new namespaces is the TOAST schema.
2348+
*/
2349+
void
2350+
CheckSetNamespace(Oid oldNspOid, Oid nspOid, Oid classid, Oid objid)
2351+
{
2352+
if (oldNspOid == nspOid)
2353+
ereport(ERROR,
2354+
(classid == RelationRelationId ?
2355+
errcode(ERRCODE_DUPLICATE_TABLE) :
2356+
classid == ProcedureRelationId ?
2357+
errcode(ERRCODE_DUPLICATE_FUNCTION) :
2358+
errcode(ERRCODE_DUPLICATE_OBJECT),
2359+
errmsg("%s is already in schema \"%s\"",
2360+
getObjectDescriptionOids(classid, objid),
2361+
get_namespace_name(nspOid))));
2362+
2363+
/* disallow renaming into or out of temp schemas */
2364+
if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2365+
ereport(ERROR,
2366+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2367+
errmsg("cannot move objects into or out of temporary schemas")));
2368+
2369+
/* same for TOAST schema */
2370+
if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
2371+
ereport(ERROR,
2372+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2373+
errmsg("cannot move objects into or out of TOAST schema")));
2374+
}
2375+
23422376
/*
23432377
* QualifiedNameGetCreationNamespace
23442378
* Given a possibly-qualified name for an object (in List-of-Values

src/backend/commands/functioncmds.c

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,24 +1899,8 @@ AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
18991899
/* get schema OID and check its permissions */
19001900
nspOid = LookupCreationNamespace(newschema);
19011901

1902-
if (oldNspOid == nspOid)
1903-
ereport(ERROR,
1904-
(errcode(ERRCODE_DUPLICATE_FUNCTION),
1905-
errmsg("function \"%s\" is already in schema \"%s\"",
1906-
NameListToString(name),
1907-
newschema)));
1908-
1909-
/* disallow renaming into or out of temp schemas */
1910-
if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
1911-
ereport(ERROR,
1912-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1913-
errmsg("cannot move objects into or out of temporary schemas")));
1914-
1915-
/* same for TOAST schema */
1916-
if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
1917-
ereport(ERROR,
1918-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1919-
errmsg("cannot move objects into or out of TOAST schema")));
1902+
/* common checks on switching namespaces */
1903+
CheckSetNamespace(oldNspOid, nspOid, ProcedureRelationId, procOid);
19201904

19211905
/* check for duplicate name (more friendly than unique-index failure) */
19221906
if (SearchSysCacheExists3(PROCNAMEARGSNSP,

src/backend/commands/tablecmds.c

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8114,24 +8114,8 @@ AlterTableNamespace(RangeVar *relation, const char *newschema,
81148114
/* get schema OID and check its permissions */
81158115
nspOid = LookupCreationNamespace(newschema);
81168116

8117-
if (oldNspOid == nspOid)
8118-
ereport(ERROR,
8119-
(errcode(ERRCODE_DUPLICATE_TABLE),
8120-
errmsg("relation \"%s\" is already in schema \"%s\"",
8121-
RelationGetRelationName(rel),
8122-
newschema)));
8123-
8124-
/* disallow renaming into or out of temp schemas */
8125-
if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
8126-
ereport(ERROR,
8127-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8128-
errmsg("cannot move objects into or out of temporary schemas")));
8129-
8130-
/* same for TOAST schema */
8131-
if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
8132-
ereport(ERROR,
8133-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8134-
errmsg("cannot move objects into or out of TOAST schema")));
8117+
/* common checks on switching namespaces */
8118+
CheckSetNamespace(oldNspOid, nspOid, RelationRelationId, relid);
81358119

81368120
/* OK, modify the pg_class row and pg_depend entry */
81378121
classRel = heap_open(RelationRelationId, RowExclusiveLock);

src/backend/commands/typecmds.c

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,24 +2828,8 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
28282828
oldNspOid = typform->typnamespace;
28292829
arrayOid = typform->typarray;
28302830

2831-
if (oldNspOid == nspOid)
2832-
ereport(ERROR,
2833-
(errcode(ERRCODE_DUPLICATE_OBJECT),
2834-
errmsg("type %s is already in schema \"%s\"",
2835-
format_type_be(typeOid),
2836-
get_namespace_name(nspOid))));
2837-
2838-
/* disallow renaming into or out of temp schemas */
2839-
if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
2840-
ereport(ERROR,
2841-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2842-
errmsg("cannot move objects into or out of temporary schemas")));
2843-
2844-
/* same for TOAST schema */
2845-
if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
2846-
ereport(ERROR,
2847-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2848-
errmsg("cannot move objects into or out of TOAST schema")));
2831+
/* common checks on switching namespaces */
2832+
CheckSetNamespace(oldNspOid, nspOid, TypeRelationId, typeOid);
28492833

28502834
/* check for duplicate name (more friendly than unique-index failure) */
28512835
if (SearchSysCacheExists2(TYPENAMENSP,

src/include/catalog/dependency.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ extern void recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
165165
extern ObjectClass getObjectClass(const ObjectAddress *object);
166166

167167
extern char *getObjectDescription(const ObjectAddress *object);
168+
extern char *getObjectDescriptionOids(Oid classid, Oid objid);
168169

169170
extern ObjectAddresses *new_object_addresses(void);
170171

src/include/catalog/namespace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ extern Oid LookupExplicitNamespace(const char *nspname);
9494
extern Oid get_namespace_oid(const char *nspname, bool missing_ok);
9595

9696
extern Oid LookupCreationNamespace(const char *nspname);
97+
extern void CheckSetNamespace(Oid oldNspOid, Oid nspOid, Oid classid,
98+
Oid objid);
9799
extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p);
98100
extern RangeVar *makeRangeVarFromNameList(List *names);
99101
extern char *NameListToString(List *names);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy