1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-15 19:21:59 +03:00

Invalidate partitions of table being attached/detached

Failing to do that, any direct inserts/updates of those partitions
would fail to enforce the correct constraint, that is, one that
considers the new partition constraint of their parent table.

Backpatch to 10.

Reported by: Hou Zhijie <houzj.fnst@fujitsu.com>
Author: Amit Langote <amitlangote09@gmail.com>
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reviewed-by: Nitin Jadhav <nitinjadhavpostgres@gmail.com>
Reviewed-by: Pavel Borisov <pashkin.elfe@gmail.com>

Discussion: https://postgr.es/m/OS3PR01MB5718DA1C4609A25186D1FBF194089%40OS3PR01MB5718.jpnprd01.prod.outlook.com
This commit is contained in:
Alvaro Herrera
2021-10-18 19:08:25 -03:00
parent a207b85213
commit 8b26be8a32
3 changed files with 74 additions and 0 deletions

View File

@ -16341,6 +16341,22 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
ObjectAddressSet(address, RelationRelationId, RelationGetRelid(attachrel));
/*
* If the partition we just attached is partitioned itself, invalidate
* relcache for all descendent partitions too to ensure that their
* rd_partcheck expression trees are rebuilt; partitions already locked
* at the beginning of this function.
*/
if (attachrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{
ListCell *l;
foreach(l, attachrel_children)
{
CacheInvalidateRelcacheByRelid(lfirst_oid(l));
}
}
/* keep our lock until commit */
table_close(attachrel, NoLock);
@ -16917,6 +16933,25 @@ ATExecDetachPartition(Relation rel, RangeVar *name)
*/
CacheInvalidateRelcache(rel);
/*
* If the partition we just detached is partitioned itself, invalidate
* relcache for all descendent partitions too to ensure that their
* rd_partcheck expression trees are rebuilt; must lock partitions
* before doing so, using the same lockmode as what partRel has been
* locked with by the caller.
*/
if (partRel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{
List *children;
children = find_all_inheritors(RelationGetRelid(partRel),
AccessExclusiveLock, NULL);
foreach(cell, children)
{
CacheInvalidateRelcacheByRelid(lfirst_oid(cell));
}
}
ObjectAddressSet(address, RelationRelationId, RelationGetRelid(partRel));
/* keep our lock until commit */