aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/typecmds.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2024-02-14 11:30:39 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2024-02-14 11:30:39 -0500
commit3e8235ba4f9cc3375b061fb5d3f3575434539b5f (patch)
tree44b71342fadc8cb3dc5e0fe50359ee2e23c31506 /src/backend/commands/typecmds.c
parentbd8fc1677b88ed80e4e00e0e46401ec537952482 (diff)
downloadpostgresql-3e8235ba4f9cc3375b061fb5d3f3575434539b5f.tar.gz
postgresql-3e8235ba4f9cc3375b061fb5d3f3575434539b5f.zip
Fix multiranges to behave more like dependent types.
For most purposes, multiranges act like dependent objects of the associated range type: you can't create them separately or drop them separately. This is like the way that autogenerated array types behave. However, a couple of points were overlooked: array types automatically track the ownership of their base type, and array types do not have their own permissions but use those of the base type, while multiranges didn't emulate those behaviors. This is fairly broken, mainly because pg_dump doesn't think it needs to worry about multiranges as separate objects, and thus it fails to dump/restore ownership or permissions of multiranges. There's no apparent value in letting a multirange diverge from its parent's ownership or permissions, so let's make them act like arrays in these respects. However, we continue to let multiranges be renamed or moved to a different schema independently of their parent, since that doesn't break anything. Discussion: https://postgr.es/m/1580383.1705343264@sss.pgh.pa.us
Diffstat (limited to 'src/backend/commands/typecmds.c')
-rw-r--r--src/backend/commands/typecmds.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index a400fb39f67..e0275e5fe9c 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -3647,6 +3647,8 @@ RenameType(RenameStmt *stmt)
errhint("You can alter type %s, which will alter the array type as well.",
format_type_be(typTup->typelem))));
+ /* we do allow separate renaming of multirange types, though */
+
/*
* If type is composite we need to rename associated pg_class entry too.
* RenameRelationInternal will call RenameTypeInternal automatically.
@@ -3730,6 +3732,21 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
errhint("You can alter type %s, which will alter the array type as well.",
format_type_be(typTup->typelem))));
+ /* don't allow direct alteration of multirange types, either */
+ if (typTup->typtype == TYPTYPE_MULTIRANGE)
+ {
+ Oid rangetype = get_multirange_range(typeOid);
+
+ /* We don't expect get_multirange_range to fail, but cope if so */
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot alter multirange type %s",
+ format_type_be(typeOid)),
+ OidIsValid(rangetype) ?
+ errhint("You can alter type %s, which will alter the multirange type as well.",
+ format_type_be(rangetype)) : 0));
+ }
+
/*
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
@@ -3769,13 +3786,13 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
/*
* AlterTypeOwner_oid - change type owner unconditionally
*
- * This function recurses to handle a pg_class entry, if necessary. It
- * invokes any necessary access object hooks. If hasDependEntry is true, this
- * function modifies the pg_shdepend entry appropriately (this should be
- * passed as false only for table rowtypes and array types).
+ * This function recurses to handle dependent types (arrays and multiranges).
+ * It invokes any necessary access object hooks. If hasDependEntry is true,
+ * this function modifies the pg_shdepend entry appropriately (this should be
+ * passed as false only for table rowtypes and dependent types).
*
* This is used by ALTER TABLE/TYPE OWNER commands, as well as by REASSIGN
- * OWNED BY. It assumes the caller has done all needed check.
+ * OWNED BY. It assumes the caller has done all needed checks.
*/
void
AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry)
@@ -3815,7 +3832,7 @@ AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry)
* AlterTypeOwnerInternal - bare-bones type owner change.
*
* This routine simply modifies the owner of a pg_type entry, and recurses
- * to handle a possible array type.
+ * to handle any dependent types.
*/
void
AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId)
@@ -3865,6 +3882,19 @@ AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId)
if (OidIsValid(typTup->typarray))
AlterTypeOwnerInternal(typTup->typarray, newOwnerId);
+ /* If it is a range type, update the associated multirange too */
+ if (typTup->typtype == TYPTYPE_RANGE)
+ {
+ Oid multirange_typeid = get_range_multirange(typeOid);
+
+ if (!OidIsValid(multirange_typeid))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("could not find multirange type for data type %s",
+ format_type_be(typeOid))));
+ AlterTypeOwnerInternal(multirange_typeid, newOwnerId);
+ }
+
/* Clean up */
table_close(rel, RowExclusiveLock);
}