Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gwQB2-00064M-5p for pgsql-hackers@arkaria.postgresql.org; Wed, 20 Feb 2019 11:36:36 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gwQB0-0006ig-Tr for pgsql-hackers@arkaria.postgresql.org; Wed, 20 Feb 2019 11:36:34 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gwQB0-0006iZ-Iz for pgsql-hackers@lists.postgresql.org; Wed, 20 Feb 2019 11:36:34 +0000 Received: from mx1.mailbox.org ([80.241.60.212]) by makus.postgresql.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gwQAw-00046O-Vt for pgsql-hackers@postgresql.org; Wed, 20 Feb 2019 11:36:33 +0000 Received: from smtp2.mailbox.org (smtp2.mailbox.org [IPv6:2001:67c:2050:105:465:1:2:0]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mx1.mailbox.org (Postfix) with ESMTPS id 9E8214B763; Wed, 20 Feb 2019 12:36:26 +0100 (CET) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp2.mailbox.org ([80.241.60.241]) by spamfilter03.heinlein-hosting.de (spamfilter03.heinlein-hosting.de [80.241.56.117]) (amavisd-new, port 10030) with ESMTP id V_VefqKMjtsM; Wed, 20 Feb 2019 12:36:10 +0100 (CET) From: Antonin Houska To: Corey Huinker cc: emre@hasegeli.com, Adam Brusselback , Pavel Stehule , Alvaro Herrera , PostgreSQL Hackers Subject: Re: Referential Integrity Checks with Statement-level Triggers In-reply-to: References: <20181217172729.mjfkflaelii2boaj@alvherre.pgsql> Comments: In-reply-to Corey Huinker message dated "Wed, 23 Jan 2019 12:16:14 -0500." MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <17099.1550662686.1@localhost> Content-Transfer-Encoding: quoted-printable Date: Wed, 20 Feb 2019 12:38:06 +0100 Message-ID: <17100.1550662686@localhost> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Corey Huinker wrote: > Attached is a patch that refactors DELETE triggers to fire at the statem= ent level. > = > I chose delete triggers partly out of simplicity, and partly because the= re > some before/after row linkage in the ON UPDATE CASCADE cases where state= ment > level triggers might not be feasible as we have currently implemented th= em. I tried to review this patch, also with the intention to learn more about AFTER triggers internals. As for the code, I understood your idea and it really seems like low hanging fruit. However in trigger.c I noticed a comm= ent that transition table is not supported for deferred constraints. Of course= I tried to use this information to test your patch: CREATE TABLE t_pk(i int PRIMARY KEY); CREATE TABLE t_fk(i int REFERENCES t_pk ON DELETE NO ACTION DEFERRABLE); INSERT INTO t_pk(i) VALUES (1); INSERT INTO t_fk(i) VALUES (1); BEGIN; SET CONSTRAINTS t_fk_i_fkey DEFERRED; DELETE FROM t_pk; COMMIT; server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request. The connection to the server was lost. Attempting reset: Failed. Missing transition table really appears to be the problem: #0 0x0000000000a8c2a8 in tuplestore_tuple_count (state=3D0x7f7f7f7f7f7f7f= 7f) at tuplestore.c:548 #1 0x00000000009b0e58 in ri_on_delete_restrict (trigdata=3D0x7ffe800c2890= , is_no_action=3Dtrue) at ri_triggers.c:720 #2 0x00000000009b0d3f in RI_FKey_noaction_del (fcinfo=3D0x7ffe800c27a0) a= t ri_triggers.c:607 #3 0x00000000006b8768 in ExecCallTriggerFunc (trigdata=3D0x7ffe800c2890, = tgindx=3D0, finfo=3D0x1f08c10, instr=3D0x0, per_tuple_context=3D0x1f30690)= at trigger.c:2412 #4 0x00000000006bbb86 in AfterTriggerExecute (event=3D0x1f0ab10, rel=3D0x= 7fc71306ea70, trigdesc=3D0x1f089f8, finfo=3D0x1f08c10, instr=3D0x0, per_tu= ple_context=3D0x1f30690, trig_tuple_slot1=3D0x0, trig_tuple_slot2=3D0x0) at trigger.c:4367 #5 0x00000000006bbf9e in afterTriggerInvokeEvents (events=3D0xf97950 , firing_id=3D1, estate=3D0x1f086c8, delete_ok=3Dtrue) at tr= igger.c:4560 #6 0x00000000006bc844 in AfterTriggerFireDeferred () at trigger.c:4996 #7 0x000000000055c989 in CommitTransaction () at xact.c:1987 #8 0x000000000055d6a4 in CommitTransactionCommand () at xact.c:2832 While the idea to use the transition table is good, this approach probably requires the trigger engine (trigger.c) to be adjusted, and that in a non-trivial way. I'm also not sure if it's o.k. that performance related patch potentially makes performance worse in some cases. If FK violations are checked at statement boundary, the wasted effort / time can (at least in theory) be h= igh if early rows violate the FK. Have you considered bulk processing of individual rows by row-level trigge= r? For IMMEDIATE constraints we'd have to ensure that the trigger is notified that the current row is the last one from the current query, but that migh= t not be difficult. -- = Antonin Houska https://www.cybertec-postgresql.com