mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
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
This commit is contained in:
@ -7021,27 +7021,28 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
|
||||
errmsg("cannot drop system column \"%s\"",
|
||||
colName)));
|
||||
|
||||
/* Don't drop inherited columns */
|
||||
/*
|
||||
* Don't drop inherited columns, unless recursing (presumably from a drop
|
||||
* of the parent column)
|
||||
*/
|
||||
if (targetatt->attinhcount > 0 && !recursing)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("cannot drop inherited column \"%s\"",
|
||||
colName)));
|
||||
|
||||
/* Don't drop columns used in the partition key */
|
||||
/*
|
||||
* Don't drop columns used in the partition key, either. (If we let this
|
||||
* go through, the key column's dependencies would cause a cascaded drop
|
||||
* of the whole table, which is surely not what the user expected.)
|
||||
*/
|
||||
if (has_partition_attrs(rel,
|
||||
bms_make_singleton(attnum - FirstLowInvalidHeapAttributeNumber),
|
||||
&is_expr))
|
||||
{
|
||||
if (!is_expr)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("cannot drop column named in partition key")));
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("cannot drop column referenced in partition key expression")));
|
||||
}
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("cannot drop column \"%s\" because it is part of the partition key of relation \"%s\"",
|
||||
colName, RelationGetRelationName(rel))));
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
@ -10255,16 +10256,10 @@ ATPrepAlterColumnType(List **wqueue,
|
||||
if (has_partition_attrs(rel,
|
||||
bms_make_singleton(attnum - FirstLowInvalidHeapAttributeNumber),
|
||||
&is_expr))
|
||||
{
|
||||
if (!is_expr)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("cannot alter type of column named in partition key")));
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("cannot alter type of column referenced in partition key expression")));
|
||||
}
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"",
|
||||
colName, RelationGetRelationName(rel))));
|
||||
|
||||
/* Look up the target type */
|
||||
typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod);
|
||||
|
Reference in New Issue
Block a user