Re: [BUG] wrong FK constraint name when colliding name on ATTACH
Amit Langote <amitlangote09@gmail.com>
From: Amit Langote <amitlangote09@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Andres Freund <andres@anarazel.de>,
Alvaro Herrera <alvherre@alvh.no-ip.org>, Jehan-Guillaume de Rorthais <jgdr@dalibo.com>,
pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2022-09-09T07:16:09Z
Lists: pgsql-hackers
Attachments
- action-check-trigger-filter.patch (application/octet-stream) patch
On Fri, Sep 9, 2022 at 4:54 AM Tom Lane <tgl@sss.pgh.pa.us> wrote: > Andres Freund <andres@anarazel.de> writes: > > Something here doesn't look to be quite right. Starting with this commit CI > > [1] started to fail on freebsd (stack trace [2]), and in the meson branch I've > > also seen the crash on windows (CI run[3], stack trace [4]). > > The crash seems 100% reproducible if I remove the early-exit optimization > from GetForeignKeyActionTriggers: Indeed, reproduced here. > diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c > index 53b0f3a9c1..112ca77d97 100644 > --- a/src/backend/commands/tablecmds.c > +++ b/src/backend/commands/tablecmds.c > @@ -10591,8 +10591,6 @@ GetForeignKeyActionTriggers(Relation trigrel, > Assert(*updateTriggerOid == InvalidOid); > *updateTriggerOid = trgform->oid; > } > - if (OidIsValid(*deleteTriggerOid) && OidIsValid(*updateTriggerOid)) > - break; > } > > if (!OidIsValid(*deleteTriggerOid)) > > With that in place, it's probabilistic whether the Asserts notice anything > wrong, and mostly they don't. But there are multiple matching triggers: > > regression=# select oid, tgconstraint, tgrelid,tgconstrrelid, tgtype, tgname from pg_trigger where tgconstraint = 104301; > oid | tgconstraint | tgrelid | tgconstrrelid | tgtype | tgname > --------+--------------+---------+---------------+--------+------------------------------- > 104302 | 104301 | 104294 | 104294 | 9 | RI_ConstraintTrigger_a_104302 > 104303 | 104301 | 104294 | 104294 | 17 | RI_ConstraintTrigger_a_104303 > 104304 | 104301 | 104294 | 104294 | 5 | RI_ConstraintTrigger_c_104304 > 104305 | 104301 | 104294 | 104294 | 17 | RI_ConstraintTrigger_c_104305 > (4 rows) > > I suspect that the filter conditions being applied are inadequate > for the case of a self-referential FK, which this evidently is > given that tgrelid and tgconstrrelid are equal. Yes, the loop in GetForeignKeyActionTriggers() needs this: + /* Only ever look at "action" triggers on the PK side. */ + if (RI_FKey_trigger_type(trgform->tgfoid) != RI_TRIGGER_PK) + continue; Likewise, GetForeignKeyActionTriggers() needs this: + /* Only ever look at "check" triggers on the FK side. */ + if (RI_FKey_trigger_type(trgform->tgfoid) != RI_TRIGGER_FK) + continue; We evidently missed this in f4566345cf40b0. > I'd counsel dropping the early-exit optimization; it doesn't > save much I expect, and it evidently hides bugs. Or maybe > make it conditional on !USE_ASSERT_CHECKING. While neither of these functions are called in hot paths, I am inclined to keep the early-exit bit in non-assert builds. Attached a patch. -- Thanks, Amit Langote EDB: http://www.enterprisedb.com
Commits
-
Create FKs properly when attaching table as partition
- c301e1c0c09c 15.1 landed
- b0284bfb1db5 16.0 landed
- ab70b3a52fde 12.13 landed
- 41b6e7c9a32e 13.9 landed
- 18865f4df9ca 14.6 landed
-
Fix self-referencing foreign keys with partitioned tables
- 7d520e68ea1e 13.9 landed
- 669803af04e6 12.13 landed
- 614a406b4ff1 16.0 landed
- 6083132abdd4 15.0 landed
- 483d26930b4c 14.6 landed
-
Fix GetForeignKey*Triggers for self-referential FKs
- 8c848cd4b8e9 16.0 landed
- 68b0da67794e 15.0 landed
-
Choose FK name correctly during partition attachment
- e7936f8b3e57 16.0 landed
- ade2409b18e9 15.0 landed
- 80ef25b1adb1 13.9 landed
- 640c20d6266d 14.6 landed
- 562e100aeeaf 12.13 landed
-
Update SQL features
- 7e367924e33e 15.0 cited
-
Restore the previous semantics of get_constraint_index().
- 641f3dffcdf1 15.0 cited