Skip to content

Commit 0d245d1

Browse files
committed
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 eb51af7, 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
1 parent 297b9cc commit 0d245d1

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

src/backend/catalog/heap.c

+9
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,15 @@ CheckAttributeType(const char *attname,
561561

562562
containing_rowtypes = list_delete_first(containing_rowtypes);
563563
}
564+
else if (att_typtype == TYPTYPE_RANGE)
565+
{
566+
/*
567+
* If it's a range, recurse to check its subtype.
568+
*/
569+
CheckAttributeType(attname, get_range_subtype(atttypid), attcollation,
570+
containing_rowtypes,
571+
allow_system_table_mods);
572+
}
564573
else if (OidIsValid((att_typelem = get_element_type(atttypid))))
565574
{
566575
/*

src/test/regress/expected/rangetypes.out

+19
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,25 @@ select array[1,3] <@ arrayrange(array[1,2], array[2,1]);
13231323
t
13241324
(1 row)
13251325

1326+
--
1327+
-- Ranges of composites
1328+
--
1329+
create type two_ints as (a int, b int);
1330+
create type two_ints_range as range (subtype = two_ints);
1331+
select *, row_to_json(upper(t)) as u from
1332+
(values (two_ints_range(row(1,2), row(3,4))),
1333+
(two_ints_range(row(5,6), row(7,8)))) v(t);
1334+
t | u
1335+
-------------------+---------------
1336+
["(1,2)","(3,4)") | {"a":3,"b":4}
1337+
["(5,6)","(7,8)") | {"a":7,"b":8}
1338+
(2 rows)
1339+
1340+
-- this must be rejected to avoid self-inclusion issues:
1341+
alter type two_ints add attribute c two_ints_range;
1342+
ERROR: composite type two_ints cannot be made a member of itself
1343+
drop type two_ints cascade;
1344+
NOTICE: drop cascades to type two_ints_range
13261345
--
13271346
-- Check behavior when subtype lacks a hash function
13281347
--

src/test/regress/sql/rangetypes.sql

+16
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,22 @@ select arrayrange(ARRAY[2,1], ARRAY[1,2]); -- fail
442442
select array[1,1] <@ arrayrange(array[1,2], array[2,1]);
443443
select array[1,3] <@ arrayrange(array[1,2], array[2,1]);
444444

445+
--
446+
-- Ranges of composites
447+
--
448+
449+
create type two_ints as (a int, b int);
450+
create type two_ints_range as range (subtype = two_ints);
451+
452+
select *, row_to_json(upper(t)) as u from
453+
(values (two_ints_range(row(1,2), row(3,4))),
454+
(two_ints_range(row(5,6), row(7,8)))) v(t);
455+
456+
-- this must be rejected to avoid self-inclusion issues:
457+
alter type two_ints add attribute c two_ints_range;
458+
459+
drop type two_ints cascade;
460+
445461
--
446462
-- Check behavior when subtype lacks a hash function
447463
--

0 commit comments

Comments
 (0)