postgres.git / summary / log / commit / refs
commit dd4069197650d5c6d1d6385ceccc43ae2ccffc67
Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Thu Apr 23 18:28:11 2026 +0000
Don't allow composite type to be member of itself via multirange
CheckAttributeType() checks that a composite type is not made a member
of itself with ALTER TABLE ADD COLUMN or ALTER TYPE ADD ATTRIBUTE,
even indirectly via a domain, array, another composite type or a range
type. But it missed checking for multiranges. That was a simple
oversight when multiranges were added.
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://www.postgresql.org/message-id/93ce56cd-02a6-4db1-8224-c8999372facc@iki.fi
Backpatch-through: 14
src/backend/catalog/heap.c | 10 ++++++++++
src/test/regress/expected/multirangetypes.out | 3 +++
src/test/regress/sql/multirangetypes.sql | 3 +++
3 files changed, 16 insertions(+)
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index ae6b7cda3dd..a19e63c3a59 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -654,6 +654,16 @@ CheckAttributeType(const char *attname,
containing_rowtypes,
flags);
}
+ else if (att_typtype == TYPTYPE_MULTIRANGE)
+ {
+ /*
+ * If it's a multirange, recurse to check its plain range type.
+ */
+ CheckAttributeType(attname, get_multirange_range(atttypid),
+ InvalidOid, /* range types are not collatable */
+ containing_rowtypes,
+ flags);
+ }
else if (OidIsValid((att_typelem = get_element_type(atttypid))))
{
/*
diff --git a/src/test/regress/expected/multirangetypes.out b/src/test/regress/expected/multirangetypes.out
index f5e7df8df43..5fcfec49c69 100644
--- a/src/test/regress/expected/multirangetypes.out
+++ b/src/test/regress/expected/multirangetypes.out
@@ -3418,6 +3418,9 @@ select *, row_to_json(upper(t)) as u from
{["(5,6)","(7,8)")} | {"a":7,"b":8}
(2 rows)
+-- this must be rejected to avoid self-inclusion issues:
+alter type two_ints add attribute c two_ints_multirange;
+ERROR: composite type two_ints cannot be made a member of itself
drop type two_ints cascade;
NOTICE: drop cascades to type two_ints_range
--
diff --git a/src/test/regress/sql/multirangetypes.sql b/src/test/regress/sql/multirangetypes.sql
index 112334b03eb..763fc07a875 100644
--- a/src/test/regress/sql/multirangetypes.sql
+++ b/src/test/regress/sql/multirangetypes.sql
@@ -837,6 +837,9 @@ select *, row_to_json(upper(t)) as u from
(values (two_ints_multirange(two_ints_range(row(1,2), row(3,4)))),
(two_ints_multirange(two_ints_range(row(5,6), row(7,8))))) v(t);
+-- this must be rejected to avoid self-inclusion issues:
+alter type two_ints add attribute c two_ints_multirange;
+
drop type two_ints cascade;
--
[parent: 4b2aa4b39cba]