Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c301e1c

Browse files
committed
Create FKs properly when attaching table as partition
Commit f56f8f8 added some code in CloneFkReferencing that's way too lax about a Constraint node it manufactures, not initializing enough struct members -- initially_valid in particular was forgotten. This causes some FKs in partitions added by ALTER TABLE ATTACH PARTITION to be marked as not validated. Set initially_valid true, which fixes the bug. While at it, make the struct initialization more complete. Very similar code was added in two other places by the same commit; make them all follow the same pattern for consistency, though no bugs are apparent there. This bug has never been reported: I only happened to notice while working on commit 614a406. The test case that was added there with the improper result is repaired. Backpatch to 12. Discussion: https://postgr.es/m/20221005105523.bhuhkdx4olajboof@alvherre.pgsql
1 parent f2dc7f9 commit c301e1c

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

src/backend/commands/tablecmds.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10126,14 +10126,22 @@ CloneFkReferenced(Relation parentRel, Relation partitionRel)
1012610126
mapped_confkey[i] = attmap->attnums[confkey[i] - 1];
1012710127

1012810128
fkconstraint = makeNode(Constraint);
10129-
/* for now this is all we need */
10129+
fkconstraint->contype = CONSTRAINT_FOREIGN;
1013010130
fkconstraint->conname = NameStr(constrForm->conname);
10131-
fkconstraint->fk_upd_action = constrForm->confupdtype;
10132-
fkconstraint->fk_del_action = constrForm->confdeltype;
1013310131
fkconstraint->deferrable = constrForm->condeferrable;
1013410132
fkconstraint->initdeferred = constrForm->condeferred;
10135-
fkconstraint->initially_valid = true;
10133+
fkconstraint->location = -1;
10134+
fkconstraint->pktable = NULL;
10135+
/* ->fk_attrs determined below */
10136+
fkconstraint->pk_attrs = NIL;
1013610137
fkconstraint->fk_matchtype = constrForm->confmatchtype;
10138+
fkconstraint->fk_upd_action = constrForm->confupdtype;
10139+
fkconstraint->fk_del_action = constrForm->confdeltype;
10140+
fkconstraint->fk_del_set_cols = NIL;
10141+
fkconstraint->old_conpfeqop = NIL;
10142+
fkconstraint->old_pktable_oid = InvalidOid;
10143+
fkconstraint->skip_validation = false;
10144+
fkconstraint->initially_valid = true;
1013710145

1013810146
/* set up colnames that are used to generate the constraint name */
1013910147
for (int i = 0; i < numfks; i++)
@@ -10351,11 +10359,22 @@ CloneFkReferencing(List **wqueue, Relation parentRel, Relation partRel)
1035110359

1035210360
/* No dice. Set up to create our own constraint */
1035310361
fkconstraint = makeNode(Constraint);
10354-
fkconstraint->fk_upd_action = constrForm->confupdtype;
10355-
fkconstraint->fk_del_action = constrForm->confdeltype;
10362+
fkconstraint->contype = CONSTRAINT_FOREIGN;
10363+
/* ->conname determined below */
1035610364
fkconstraint->deferrable = constrForm->condeferrable;
1035710365
fkconstraint->initdeferred = constrForm->condeferred;
10366+
fkconstraint->location = -1;
10367+
fkconstraint->pktable = NULL;
10368+
/* ->fk_attrs determined below */
10369+
fkconstraint->pk_attrs = NIL;
1035810370
fkconstraint->fk_matchtype = constrForm->confmatchtype;
10371+
fkconstraint->fk_upd_action = constrForm->confupdtype;
10372+
fkconstraint->fk_del_action = constrForm->confdeltype;
10373+
fkconstraint->fk_del_set_cols = NIL;
10374+
fkconstraint->old_conpfeqop = NIL;
10375+
fkconstraint->old_pktable_oid = InvalidOid;
10376+
fkconstraint->skip_validation = false;
10377+
fkconstraint->initially_valid = true;
1035910378
for (int i = 0; i < numfks; i++)
1036010379
{
1036110380
Form_pg_attribute att;
@@ -18571,11 +18590,22 @@ DetachPartitionFinalize(Relation rel, Relation partRel, bool concurrent,
1857118590
* still do), but now we need separate ones of our own.
1857218591
*/
1857318592
fkconstraint = makeNode(Constraint);
18593+
fkconstraint->contype = CONSTRAINT_FOREIGN;
1857418594
fkconstraint->conname = pstrdup(NameStr(conform->conname));
18575-
fkconstraint->fk_upd_action = conform->confupdtype;
18576-
fkconstraint->fk_del_action = conform->confdeltype;
1857718595
fkconstraint->deferrable = conform->condeferrable;
1857818596
fkconstraint->initdeferred = conform->condeferred;
18597+
fkconstraint->location = -1;
18598+
fkconstraint->pktable = NULL;
18599+
fkconstraint->fk_attrs = NIL;
18600+
fkconstraint->pk_attrs = NIL;
18601+
fkconstraint->fk_matchtype = conform->confmatchtype;
18602+
fkconstraint->fk_upd_action = conform->confupdtype;
18603+
fkconstraint->fk_del_action = conform->confdeltype;
18604+
fkconstraint->fk_del_set_cols = NIL;
18605+
fkconstraint->old_conpfeqop = NIL;
18606+
fkconstraint->old_pktable_oid = InvalidOid;
18607+
fkconstraint->skip_validation = false;
18608+
fkconstraint->initially_valid = true;
1857918609

1858018610
createForeignKeyActionTriggers(partRel, conform->confrelid,
1858118611
fkconstraint, fk->conoid,

src/test/regress/expected/foreign_key.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,7 +2031,7 @@ ORDER BY co.contype, cr.relname, co.conname, p.conname;
20312031
----------------+----------------------------+---------+--------------+----------------------------+--------------+----------------
20322032
part1_self_fk | parted_self_fk_id_abc_fkey | f | t | parted_self_fk_id_abc_fkey | t | parted_self_fk
20332033
part2_self_fk | parted_self_fk_id_abc_fkey | f | t | parted_self_fk_id_abc_fkey | t | parted_self_fk
2034-
part32_self_fk | parted_self_fk_id_abc_fkey | f | f | parted_self_fk_id_abc_fkey | t | parted_self_fk
2034+
part32_self_fk | parted_self_fk_id_abc_fkey | f | t | parted_self_fk_id_abc_fkey | t | parted_self_fk
20352035
part33_self_fk | parted_self_fk_id_abc_fkey | f | t | parted_self_fk_id_abc_fkey | t | parted_self_fk
20362036
part3_self_fk | parted_self_fk_id_abc_fkey | f | t | parted_self_fk_id_abc_fkey | t | parted_self_fk
20372037
parted_self_fk | parted_self_fk_id_abc_fkey | f | t | | | parted_self_fk
@@ -2060,7 +2060,7 @@ ORDER BY co.contype, cr.relname, co.conname, p.conname;
20602060
----------------+----------------------------+---------+--------------+----------------------------+--------------+----------------
20612061
part1_self_fk | parted_self_fk_id_abc_fkey | f | t | parted_self_fk_id_abc_fkey | t | parted_self_fk
20622062
part2_self_fk | parted_self_fk_id_abc_fkey | f | t | parted_self_fk_id_abc_fkey | t | parted_self_fk
2063-
part32_self_fk | parted_self_fk_id_abc_fkey | f | f | parted_self_fk_id_abc_fkey | t | parted_self_fk
2063+
part32_self_fk | parted_self_fk_id_abc_fkey | f | t | parted_self_fk_id_abc_fkey | t | parted_self_fk
20642064
part33_self_fk | parted_self_fk_id_abc_fkey | f | t | parted_self_fk_id_abc_fkey | t | parted_self_fk
20652065
part3_self_fk | parted_self_fk_id_abc_fkey | f | t | parted_self_fk_id_abc_fkey | t | parted_self_fk
20662066
parted_self_fk | parted_self_fk_id_abc_fkey | f | t | | | parted_self_fk

0 commit comments

Comments
 (0)