Re: delta relations in AFTER triggers
Noah Misch <noah@leadboat.com>
From: Noah Misch <noah@leadboat.com>
To: Kevin Grittner <kgrittn@gmail.com>
Cc: Neha Sharma <neha.sharma@enterprisedb.com>, Thomas Munro <thomas.munro@enterprisedb.com>, Prabhat Sahu <prabhat.sahu@enterprisedb.com>, Tom Lane <tgl@sss.pgh.pa.us>, Robert Haas <robertmhaas@gmail.com>, Haribabu Kommi <kommi.haribabu@gmail.com>, Jim Nasby <Jim.Nasby@bluetreble.com>, Craig Ringer <craig@2ndquadrant.com>, Michael Paquier <michael.paquier@gmail.com>, David Fetter <david@fetter.org>, Kevin Grittner <kgrittn@ymail.com>, Amit Khandekar <amit.khandekar@enterprisedb.com>, Alvaro Herrera <alvherre@2ndquadrant.com>, Pg Hackers <pgsql-hackers@postgresql.org>, Corey Huinker <corey.huinker@gmail.com>
Date: 2017-05-06T05:34:46Z
Lists: pgsql-hackers
On Fri, May 05, 2017 at 08:23:33AM +1200, Thomas Munro wrote: > On Fri, May 5, 2017 at 12:39 AM, Neha Sharma > <neha.sharma@enterprisedb.com> wrote: > > While testing the feature we encountered one more crash,below is the > > scenario to reproduce. > > > > create table t1 ( a int); > > create table t2 ( a int); > > insert into t1 values (11),(12),(13); > > > > create or replace function my_trig() returns trigger > > language plpgsql as $my_trig$ > > begin > > insert into t2(select a from new_table); > > RETURN NEW; > > end; > > $my_trig$; > > > > create trigger my_trigger > > after truncate or update on t1 > > referencing new table as new_table old table as oldtab > > for each statement > > execute procedure my_trig(); > > > > truncate t1; > > 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. > > Thanks. Reproduced here. The stack looks like this: > > frame #3: 0x0000000103e5e8b0 > postgres`ExceptionalCondition(conditionName="!((((((trigdata->tg_event) > & 0x00000003) == 0x00000000) || (((trigdata->tg_event) & 0x00000003) > == 0x00000002) || (((trigdata->tg_event) & 0x00000003) == 0x00000001)) > && (((trigdata->tg_event) & 0x00000018) == 0x00000000) && > !(trigdata->tg_event & 0x00000020) && !(trigdata->tg_event & > 0x00000040)) || (trigdata->tg_oldtable == ((void*)0) && > trigdata->tg_newtable == ((void*)0)))", errorType="FailedAssertion", > fileName="trigger.c", lineNumber=2045) + 128 at assert.c:54 > frame #4: 0x0000000103a6f542 > postgres`ExecCallTriggerFunc(trigdata=0x00007fff5c40bad0, tgindx=0, > finfo=0x00007fd8ba0817b8, instr=0x0000000000000000, > per_tuple_context=0x00007fd8b906f928) + 258 at trigger.c:2039 > frame #5: 0x0000000103a754ed > postgres`AfterTriggerExecute(event=0x00007fd8ba092460, > rel=0x00000001043fd9c0, trigdesc=0x00007fd8ba068758, > finfo=0x00007fd8ba0817b8, instr=0x0000000000000000, > per_tuple_context=0x00007fd8b906f928, > trig_tuple_slot1=0x0000000000000000, > trig_tuple_slot2=0x0000000000000000) + 1469 at trigger.c:3860 > frame #6: 0x0000000103a73080 > postgres`afterTriggerInvokeEvents(events=0x00007fd8ba07fb00, > firing_id=1, estate=0x00007fd8ba090440, delete_ok='\x01') + 592 at > trigger.c:4051 > frame #7: 0x0000000103a72b7b > postgres`AfterTriggerEndQuery(estate=0x00007fd8ba090440) + 203 at > trigger.c:4227 > frame #8: 0x0000000103a498aa > postgres`ExecuteTruncate(stmt=0x00007fd8ba059f40) + 2026 at > tablecmds.c:1485 > > There's an assertion that it's (one of INSERT, UPDATE, DELETE, an > AFTER trigger, not deferred) *or* there are no transition tables. > Here it's TRUNCATE and there are transition tables, so it fails: > > /* > * Protect against code paths that may fail to initialize transition table > * info. > */ > Assert(((TRIGGER_FIRED_BY_INSERT(trigdata->tg_event) || > TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event) || > TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) && > TRIGGER_FIRED_AFTER(trigdata->tg_event) && > !(trigdata->tg_event & AFTER_TRIGGER_DEFERRABLE) && > !(trigdata->tg_event & AFTER_TRIGGER_INITDEFERRED)) || > (trigdata->tg_oldtable == NULL && trigdata->tg_newtable == NULL)); > > > We can't possibly support transition tables on TRUNCATE (the whole > point of TRUNCATE is not to inspect all the rows so we can't collect > them), and we already reject ROW triggers on TRUNCATE, so we should > reject transition tables on STATEMENT triggers for TRUNCATE at > creation time too. See attached. Thoughts? [Action required within three days. This is a generic notification.] The above-described topic is currently a PostgreSQL 10 open item. Kevin, since you committed the patch believed to have created it, you own this open item. If some other commit is more relevant or if this does not belong as a v10 open item, please let us know. Otherwise, please observe the policy on open item ownership[1] and send a status update within three calendar days of this message. Include a date for your subsequent status update. Testers may discover new open items at any time, and I want to plan to get them all fixed well in advance of shipping v10. Consequently, I will appreciate your efforts toward speedy resolution. Thanks. [1] https://www.postgresql.org/message-id/20170404140717.GA2675809%40tornado.leadboat.com
Commits
-
Don't permit transition tables with TRUNCATE triggers.
- 29fd3d9da0ff 10.0 landed
-
Pass EXEC_FLAG_REWIND when initializing a tuplestore scan.
- 304007d9f1f6 10.0 landed
-
Faster expression evaluation and targetlist projection.
- b8d7f053c5c2 10.0 cited
-
Remove obsoleted code relating to targetlist SRF evaluation.
- ea15e18677fc 10.0 cited
-
Implement syntax for transition tables in AFTER triggers.
- 8c48375e5f43 10.0 cited