While fooling with the transition-tables bug, I noticed a problem
in trigger.c that has been there a very long time.  AfterTriggerEndQuery
correctly notes

     * ... Be careful here: firing a
     * trigger could result in query_stack being repalloc'd, so we can't save
     * its address across afterTriggerInvokeEvents calls.

However, it then proceeds to pass the address of a query_stack item to
afterTriggerInvokeEvents, so that if such a repalloc occurs,
afterTriggerInvokeEvents is already working with an obsolete dangling
pointer while it scans the rest of the events.

This isn't very trivial to fix.  I thought of making a local copy of
the events pointer struct, but that's problematic because data can
pass in a couple of directions here.  Queuing of additional trigger
events would modify the events list from "outside", while
afterTriggerInvokeEvents occasionally wants to do

                        if (chunk == events->tail)
                                events->tailfree = chunk->freeptr;

which has to be in sync with the real state of the events list
including any subsequent additions.

I think possibly the best solution is to change the query_stack
data structure enough so that pre-existing entries don't get
moved during an enlargement.  Or maybe we can fix it so the
"active" events list has a static location and the items in the
query_stack are only valid for levels below the top.

Given the lack of reports traceable to this, this doesn't seem
super urgent to fix, so I'm not going to try to address it while
hacking the transition table business.  But we'll need to return
to it later.  Whatever we do about it has to be back-patched
further than v10, anyway.

                        regards, tom lane

Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:

Reply via email to