Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1phBk0-000113-At for pgsql-bugs@arkaria.postgresql.org; Tue, 28 Mar 2023 16:00:08 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1phBjz-0004At-9e for pgsql-bugs@arkaria.postgresql.org; Tue, 28 Mar 2023 16:00:07 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1phBjy-0004Ai-TT for pgsql-bugs@lists.postgresql.org; Tue, 28 Mar 2023 16:00:07 +0000 Received: from mail-lf1-x130.google.com ([2a00:1450:4864:20::130]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1phBjw-0008UG-Mn for pgsql-bugs@lists.postgresql.org; Tue, 28 Mar 2023 16:00:06 +0000 Received: by mail-lf1-x130.google.com with SMTP id g17so16470701lfv.4 for ; Tue, 28 Mar 2023 09:00:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680019203; h=in-reply-to:from:references:cc:to:content-language:subject :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=ll9R4LuiZzwahx949l1dTDQpBpNE7JnrXTkwY66BWqk=; b=D+D6z/QikA7M8LOuaXYUnYiP8O3/QUj/97k4yg0S6bV9DQpp/QF+exgeFgHDcm/PD7 UC0RexbnTQoAuuQuI/bnHP9khEAUbc1DC0Aa5zo/0U6hTv0oxO+Pz0+ijcbPST3vAZtw kVFaYO6ItR1BiUkLRml4KvefRzoWH4Bp26Yuuucd2PBeDgShbx3UxXYhqgWa1ZCOIQnw 17Clb/o3Avtgwrz6RajT0NbuYkmmLxH+25wW7Sfkkwp+I6LoeIOifFYnXglU6kNgc34J KF2ogN8vMn4Cvc7PER67UkFtIkRCflTn929iZQqCYs0k15sSJ4X/MnRdyXnxSlecSz2t nNdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680019203; h=in-reply-to:from:references:cc:to:content-language:subject :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ll9R4LuiZzwahx949l1dTDQpBpNE7JnrXTkwY66BWqk=; b=UWe2rwFNEPkTKSL4u9nbeL3OaSVplhRdscGMn/2L5HhBlvm+oln6VN4SY5lBOcCFQi rkwUZSe+f4bol+KTHXuQSdmei8sJlNceQnWUtD+g7BYoPNwu3X1wO1Hy5o3983SCTok2 +IDyZsk9HUw5lj0IESC9MHmVnOvcFhjoMcKh97k/RHKGsO0JJ5hGNwGoXwbSCKlCcBEV nS2jgAXle5q4mKiIEr50x+1sbGVFJWvTUk7K/ODXljVxmoFoizbBMzWwZmqUvPzE++q0 LDPkZa8045mXznqGGr2XI3FzzUiWRhi8xKp5jFVdu12/sup8RksgEjA4TjXamPHg9V0n S2DQ== X-Gm-Message-State: AAQBX9dFFGB0On+lOlP0htbTd7C18AK9pOtZ8T7ohxKJOnU5ScPS7xk/ N9+9DAFBSefe1mwhLrcfD+o= X-Google-Smtp-Source: AKy350ZN/cPaZK7yKdhezR6OG7l/bJ6FYfkDCaQXUjBRZdoDpeWM9rtZuLRTGk5Lf6+x2U8xxdzgWA== X-Received: by 2002:ac2:485c:0:b0:4e2:40ba:af44 with SMTP id 28-20020ac2485c000000b004e240baaf44mr5183559lfy.7.1680019202608; Tue, 28 Mar 2023 09:00:02 -0700 (PDT) Received: from [1.0.0.7] ([178.155.30.16]) by smtp.gmail.com with ESMTPSA id k23-20020a2e92d7000000b002a5f38ef2e1sm1103537ljh.59.2023.03.28.09.00.01 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 28 Mar 2023 09:00:01 -0700 (PDT) Content-Type: multipart/alternative; boundary="------------Us8UmO9FwdNYFANceilHWzt7" Message-ID: <65c49195-7117-67c4-5bfe-45ca8832dfe3@gmail.com> Date: Tue, 28 Mar 2023 19:00:00 +0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2 Subject: Re: BUG #17872: Dropping an attribute of a composite type breaks indexes over the type silently Content-Language: en-US To: Tom Lane Cc: pgsql-bugs@lists.postgresql.org, Peter Eisentraut References: <17872-d0fbb799dc3fd85d@postgresql.org> <3169550.1679928579@sss.pgh.pa.us> <3182314.1679935605@sss.pgh.pa.us> <1aa2eec0-2017-3870-6d88-228d08c587d3@gmail.com> <3267914.1679941213@sss.pgh.pa.us> <67cb509e-93c7-1c7b-2388-d7e00277b344@gmail.com> <3332642.1679943981@sss.pgh.pa.us> From: Alexander Lakhin In-Reply-To: <3332642.1679943981@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------Us8UmO9FwdNYFANceilHWzt7 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit 27.03.2023 22:06, Tom Lane wrote: > Alexander Lakhin writes: >> 27.03.2023 21:20, Tom Lane wrote: >>> Hmm ... really? I'd just concluded that a partitioned table is okay >>> as long as it doesn't yet have any partitions. Even if the modified >>> type is a partitioning column, there's no structure yet that could >>> depend on the contents of the type. (If it does have partitions, >>> we'll fail when we get to one of those.) >> The following query leads to a failure on showing a partition definition: >> CREATE TABLE tbl(a int, b int) PARTITION BY LIST ((tbl)); >> CREATE TABLE tblp PARTITION OF tbl FOR VALUES IN ('(2,4)'); >> ALTER TABLE tbl ALTER COLUMN a TYPE char(5); > Sure, but there you already have a partition. If you only had "tbl" > then there would be no stored partition bounds. Yes, that's a separate case when a value of the composite type "tbl" stored in relpartbound for "tblp", but there is no dependency of "tbl"/"tblp" on the type "tbl". The similar situation: CREATE TYPE ctype AS (a int, b int); CREATE TABLE tbl(x ctype) PARTITION BY LIST (x); CREATE TABLE tblp PARTITION OF tbl FOR VALUES IN ('(2,4)'); ALTER TYPE ctype ALTER ATTRIBUTE b TYPE char(5); is prevented with ERROR:  cannot alter type "ctype" because column "tbl.x" uses it because there is dependency {"tbl", objsubid = 1} on the "ctype". Regarding dropping attributes/columns, I've added the find_composite_type_dependencies() call inside ATPrepDropColumn() and found that it breaks cases that were valid before (according to regression tests). E.g.:  CREATE TYPE test_type3 AS (a int);  CREATE TABLE test_tbl3 (c) AS SELECT '(1)'::test_type3;  ALTER TYPE test_type3 DROP ATTRIBUTE a, ADD ATTRIBUTE b int; +ERROR:  cannot alter type "test_type3" because column "test_tbl3.c" uses it So I agree, that disabling the drop operation when a composite type has dependencies is not a harmless change. On the other hand, the code might be not ready to deal with the uniqueness assumption violated. For example: CREATE TYPE ctype AS (a int, b int); CREATE TABLE lp (t ctype) PARTITION BY RANGE (t); CREATE TABLE lp_1_0 PARTITION OF lp FOR VALUES FROM (ROW(1, 01)::ctype) TO (ROW(1, 10)::ctype); CREATE TABLE lp_1_1 PARTITION OF lp FOR VALUES FROM (ROW(1, 11)::ctype) TO (ROW(1, 20)::ctype); ALTER TYPE ctype DROP ATTRIBUTE b; INSERT INTO lp values(ROW(1)::ctype); leads to an assertion failure: ... #5  0x000055d3131e314f in ExceptionalCondition (     conditionName=conditionName@entry=0x55d313357b85 "next_index == nparts",     fileName=fileName@entry=0x55d313357887 "partbounds.c", lineNumber=lineNumber@entry=884) at assert.c:66 #6  0x000055d312fe2e2b in create_range_bounds (boundspecs=boundspecs@entry=0x55d314e4b028,     nparts=nparts@entry=2, key=key@entry=0x55d314ed7170, mapping=mapping@entry=0x7fffa34bc438)     at partbounds.c:884 #7  0x000055d312fe46c7 in partition_bounds_create (boundspecs=boundspecs@entry=0x55d314e4b028, nparts=2,     key=key@entry=0x55d314ed7170, mapping=mapping@entry=0x7fffa34bc438) at partbounds.c:336 #8  0x000055d312fe6a2c in RelationBuildPartitionDesc (rel=rel@entry=0x7f609da02920,     omit_detached=omit_detached@entry=true) at partdesc.c:271 #9  0x000055d312fe6c99 in RelationGetPartitionDesc (rel=rel@entry=0x7f609da02920,     omit_detached=) at partdesc.c:110 ... Maybe that exact Assert could be replaced with just elog(ERROR), but I'm afraid it's not the only such place that exists today and will appear tomorrow. At least without a comprehensive testing this way seems dangerous to me. Though maybe postgres should be robust enough to not crash in such situations (caused by a composite type modification or by something else). Best regards, Alexander --------------Us8UmO9FwdNYFANceilHWzt7 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
27.03.2023 22:06, Tom Lane wrote:
Alexander Lakhin <exclusion@gmail.com> writes:
27.03.2023 21:20, Tom Lane wrote:
Hmm ... really?  I'd just concluded that a partitioned table is okay
as long as it doesn't yet have any partitions.  Even if the modified
type is a partitioning column, there's no structure yet that could
depend on the contents of the type.  (If it does have partitions,
we'll fail when we get to one of those.)

      
The following query leads to a failure on showing a partition definition:
CREATE TABLE tbl(a int, b int) PARTITION BY LIST ((tbl));
CREATE TABLE tblp PARTITION OF tbl FOR VALUES IN ('(2,4)');
ALTER TABLE tbl ALTER COLUMN a TYPE char(5);
Sure, but there you already have a partition.  If you only had "tbl"
then there would be no stored partition bounds.

Yes, that's a separate case when a value of the composite type "tbl" stored
in relpartbound for "tblp", but there is no dependency of "tbl"/"tblp" on the
type "tbl".

The similar situation:
CREATE TYPE ctype AS (a int, b int);
CREATE TABLE tbl(x ctype) PARTITION BY LIST (x);
CREATE TABLE tblp PARTITION OF tbl FOR VALUES IN ('(2,4)');
ALTER TYPE ctype ALTER ATTRIBUTE b TYPE char(5);
is prevented with
ERROR:  cannot alter type "ctype" because column "tbl.x" uses it
because there is dependency {"tbl", objsubid = 1} on the "ctype".

Regarding dropping attributes/columns, I've added the
find_composite_type_dependencies() call inside ATPrepDropColumn() and found
that it breaks cases that were valid before (according to regression tests). E.g.:
 CREATE TYPE test_type3 AS (a int);
 CREATE TABLE test_tbl3 (c) AS SELECT '(1)'::test_type3;
 ALTER TYPE test_type3 DROP ATTRIBUTE a, ADD ATTRIBUTE b int;
+ERROR:  cannot alter type "test_type3" because column "test_tbl3.c" uses it

So I agree, that disabling the drop operation when a composite type has
dependencies is not a harmless change. On the other hand, the code might be
not ready to deal with the uniqueness assumption violated.
For example:
CREATE TYPE ctype AS (a int, b int);
CREATE TABLE lp (t ctype) PARTITION BY RANGE (t);
CREATE TABLE lp_1_0 PARTITION OF lp FOR VALUES FROM (ROW(1, 01)::ctype) TO (ROW(1, 10)::ctype);
CREATE TABLE lp_1_1 PARTITION OF lp FOR VALUES FROM (ROW(1, 11)::ctype) TO (ROW(1, 20)::ctype);
ALTER TYPE ctype DROP ATTRIBUTE b;
INSERT INTO lp values(ROW(1)::ctype);
leads to an assertion failure:
...
#5  0x000055d3131e314f in ExceptionalCondition (
    conditionName=conditionName@entry=0x55d313357b85 "next_index == nparts",
    fileName=fileName@entry=0x55d313357887 "partbounds.c", lineNumber=lineNumber@entry=884) at assert.c:66
#6  0x000055d312fe2e2b in create_range_bounds (boundspecs=boundspecs@entry=0x55d314e4b028,
    nparts=nparts@entry=2, key=key@entry=0x55d314ed7170, mapping=mapping@entry=0x7fffa34bc438)
    at partbounds.c:884
#7  0x000055d312fe46c7 in partition_bounds_create (boundspecs=boundspecs@entry=0x55d314e4b028, nparts=2,
    key=key@entry=0x55d314ed7170, mapping=mapping@entry=0x7fffa34bc438) at partbounds.c:336
#8  0x000055d312fe6a2c in RelationBuildPartitionDesc (rel=rel@entry=0x7f609da02920,
    omit_detached=omit_detached@entry=true) at partdesc.c:271
#9  0x000055d312fe6c99 in RelationGetPartitionDesc (rel=rel@entry=0x7f609da02920,
    omit_detached=<optimized out>) at partdesc.c:110
...
Maybe that exact Assert could be replaced with just elog(ERROR), but I'm
afraid it's not the only such place that exists today and will appear
tomorrow. At least without a comprehensive testing this way seems dangerous
to me. Though maybe postgres should be robust enough to not crash in such
situations (caused by a composite type modification or by something else).

Best regards,
Alexander
--------------Us8UmO9FwdNYFANceilHWzt7--