diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2021-10-18 19:08:25 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2021-10-18 19:08:25 -0300 |
commit | d6f1e16c8fe27100e371a15aeeb498faa680ceed (patch) | |
tree | 3b173c99f903876f2a073b18fc725c04f7fc9aa1 /src/backend/commands/tablecmds.c | |
parent | fc0f3b4cb0e882a9c5d51c302d4aa3591e4f80fd (diff) | |
download | postgresql-d6f1e16c8fe27100e371a15aeeb498faa680ceed.tar.gz postgresql-d6f1e16c8fe27100e371a15aeeb498faa680ceed.zip |
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
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 1c2ebe1bf69..14c8003535b 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -17460,6 +17460,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); @@ -18150,6 +18166,25 @@ DetachPartitionFinalize(Relation rel, Relation partRel, bool concurrent, * included in its partition descriptor. */ 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)); + } + } } /* |