summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2019-12-23 17:08:24 +0000
committerTom Lane2019-12-23 17:08:24 +0000
commit0d245d13c643d9ee089ad59fc4673a6b520461b1 (patch)
tree78da244e4738e4d7f57b24801a391ecf12ac03b0
parent297b9ccff44859f274b7408045a9c91d2bb1c6d1 (diff)
Prevent a rowtype from being included in itself via a range.
We probably should have thought of this case when ranges were added, but we didn't. (It's not the fault of commit eb51af71f, because ranges didn't exist then.) It's an old bug, so back-patch to all supported branches. Discussion: https://postgr.es/m/7782.1577051475@sss.pgh.pa.us
-rw-r--r--src/backend/catalog/heap.c9
-rw-r--r--src/test/regress/expected/rangetypes.out19
-rw-r--r--src/test/regress/sql/rangetypes.sql16
3 files changed, 44 insertions, 0 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 3637d618e12..a441b16ec66 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -561,6 +561,15 @@ CheckAttributeType(const char *attname,
containing_rowtypes = list_delete_first(containing_rowtypes);
}
+ else if (att_typtype == TYPTYPE_RANGE)
+ {
+ /*
+ * If it's a range, recurse to check its subtype.
+ */
+ CheckAttributeType(attname, get_range_subtype(atttypid), attcollation,
+ containing_rowtypes,
+ allow_system_table_mods);
+ }
else if (OidIsValid((att_typelem = get_element_type(atttypid))))
{
/*
diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out
index 36bbcbb607e..b47db28eb67 100644
--- a/src/test/regress/expected/rangetypes.out
+++ b/src/test/regress/expected/rangetypes.out
@@ -1324,6 +1324,25 @@ select array[1,3] <@ arrayrange(array[1,2], array[2,1]);
(1 row)
--
+-- Ranges of composites
+--
+create type two_ints as (a int, b int);
+create type two_ints_range as range (subtype = two_ints);
+select *, row_to_json(upper(t)) as u from
+ (values (two_ints_range(row(1,2), row(3,4))),
+ (two_ints_range(row(5,6), row(7,8)))) v(t);
+ t | u
+-------------------+---------------
+ ["(1,2)","(3,4)") | {"a":3,"b":4}
+ ["(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_range;
+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
+--
-- Check behavior when subtype lacks a hash function
--
create type cashrange as range (subtype = money);
diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql
index 7153ee0c819..b6ec4fcafc6 100644
--- a/src/test/regress/sql/rangetypes.sql
+++ b/src/test/regress/sql/rangetypes.sql
@@ -443,6 +443,22 @@ select array[1,1] <@ arrayrange(array[1,2], array[2,1]);
select array[1,3] <@ arrayrange(array[1,2], array[2,1]);
--
+-- Ranges of composites
+--
+
+create type two_ints as (a int, b int);
+create type two_ints_range as range (subtype = two_ints);
+
+select *, row_to_json(upper(t)) as u from
+ (values (two_ints_range(row(1,2), row(3,4))),
+ (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_range;
+
+drop type two_ints cascade;
+
+--
-- Check behavior when subtype lacks a hash function
--