From 354d913f9745c4ce39c891d9a73b0b2535fd9c4c Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 23 Dec 2019 12:08:24 -0500 Subject: [PATCH] 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 --- src/backend/catalog/heap.c | 9 +++++++++ src/test/regress/expected/rangetypes.out | 3 +++ src/test/regress/sql/rangetypes.sql | 3 +++ 3 files changed, 15 insertions(+) diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index eea1638a2e6..79de6d71c69 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -564,6 +564,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 49432efa1a2..fcb9335bce3 100644 --- a/src/test/regress/expected/rangetypes.out +++ b/src/test/regress/expected/rangetypes.out @@ -1376,6 +1376,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_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 -- diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql index 8960add976f..2d0ec8964e6 100644 --- a/src/test/regress/sql/rangetypes.sql +++ b/src/test/regress/sql/rangetypes.sql @@ -463,6 +463,9 @@ 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; --