You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Install dependencies to prevent dropping partition key columns.
The logic in ATExecDropColumn that rejects dropping partition key
columns is quite an inadequate defense, because it doesn't execute
in cases where a column needs to be dropped due to cascade from
something that only the column, not the whole partitioned table,
depends on. That leaves us with a badly broken partitioned table;
even an attempt to load its relcache entry will fail.
We really need to have explicit pg_depend entries that show that the
column can't be dropped without dropping the whole table. Hence,
add those entries. In v12 and HEAD, bump catversion to ensure that
partitioned tables will have such entries. We can't do that in
released branches of course, so in v10 and v11 this patch affords
protection only to partitioned tables created after the patch is
installed. Given the lack of field complaints (this bug was found
by fuzz-testing not by end users), that's probably good enough.
In passing, fix ATExecDropColumn and ATPrepAlterColumnType
messages to be more specific about which partition key column
they're complaining about.
Per report from Manuel Rigger. Back-patch to v10 where partitioned
tables were added.
Discussion: https://postgr.es/m/CA+u7OA4JKCPFrdrAbOs7XBiCyD61XJxeNav4LefkSmBLQ-Vobg@mail.gmail.com
Discussion: https://postgr.es/m/31920.1562526703@sss.pgh.pa.us
Copy file name to clipboardExpand all lines: src/test/regress/expected/create_table.out
+36Lines changed: 36 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -461,6 +461,42 @@ Partition of: partitioned2 FOR VALUES FROM ('-1', 'aaaaa') TO (100, 'ccccc')
461
461
Partition constraint: (((a + 1) IS NOT NULL) AND (substr(b, 1, 5) IS NOT NULL) AND (((a + 1) > '-1'::integer) OR (((a + 1) = '-1'::integer) AND (substr(b, 1, 5) >= 'aaaaa'::text))) AND (((a + 1) < 100) OR (((a + 1) = 100) AND (substr(b, 1, 5) < 'ccccc'::text))))
462
462
463
463
DROP TABLE partitioned, partitioned2;
464
+
-- check that dependencies of partition columns are handled correctly
465
+
create domain intdom1 as int;
466
+
create table partitioned (
467
+
a intdom1,
468
+
b text
469
+
) partition by range (a);
470
+
alter table partitioned drop column a; -- fail
471
+
ERROR: cannot drop column "a" because it is part of the partition key of relation "partitioned"
472
+
drop domain intdom1; -- fail, requires cascade
473
+
ERROR: cannot drop type intdom1 because other objects depend on it
474
+
DETAIL: table partitioned depends on type intdom1
475
+
HINT: Use DROP ... CASCADE to drop the dependent objects too.
476
+
drop domain intdom1 cascade;
477
+
NOTICE: drop cascades to table partitioned
478
+
table partitioned; -- gone
479
+
ERROR: relation "partitioned" does not exist
480
+
LINE 1: table partitioned;
481
+
^
482
+
-- likewise for columns used in partition expressions
483
+
create domain intdom1 as int;
484
+
create table partitioned (
485
+
a intdom1,
486
+
b text
487
+
) partition by range (plusone(a));
488
+
alter table partitioned drop column a; -- fail
489
+
ERROR: cannot drop column "a" because it is part of the partition key of relation "partitioned"
490
+
drop domain intdom1; -- fail, requires cascade
491
+
ERROR: cannot drop type intdom1 because other objects depend on it
492
+
DETAIL: table partitioned depends on type intdom1
493
+
HINT: Use DROP ... CASCADE to drop the dependent objects too.
0 commit comments