Re: Nested transactions: deferred triggers - Mailing list pgsql-patches

From Alvaro Herrera
Subject Re: Nested transactions: deferred triggers
Date
Msg-id 20030612034244.GC4027@dcc.uchile.cl
Whole thread Raw
In response to Re: Nested transactions: deferred triggers  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-patches
On Wed, Jun 11, 2003 at 10:33:07PM -0400, Tom Lane wrote:

> My thought would be that TransactionGetDeferredTriggers() ought to be
> called in one place that then passes the list pointer to the other
> subroutines.  I haven't looked at the code in detail to see how this
> fits in ... but I don't like the notion of all these little functions
> independently fetching a pointer from some nontrivial function.  That
> opens you up to interesting problems if different functions manage to
> fetch different results.

Well, I can see it getting into serious trouble if something weird
happens.  However, I don't know a better way to do this.  Code snippets
follow.

typedef struct TransactionSpecialData
{
    void        *deferredTriggers;
    /* some other things... */
} TransactionSpecialData;

typedef struct TransactionStateData
{
    TransactionId   transactionIdData;
    ...
    /* the usual, and the "Special pointer" : */
    TransactionSpecial special;
} TransactionStateData;

The TransactionSpecial is initialized on StartSubTransaction, which is
analogous to StartTransaction but is, of course, only called when a
subtransaction starts.  If there's inconsistency in the management of
this, I don't think we have much way out but elog(PANIC) and such.  I
don't have checks in place for this though.


When the (sub)transaction starts, DeferredTriggersBeginXact() is called
which does the same as in the posted patch plus a call to
TransactionSetDeferredTriggerQueue().  After that, the routines in
backend/commands/trigger.c just call
TransactionGetDeferredTriggerQueue() to get the current queue for
processing.

This routine is defined simply as:
void *
TransactionGetDeferredTriggerQueue(void)
{
    TransactionState s = CurrentTransactionState;
    return s->special->deferredTriggers;
}

and the setter is just the trivial opposite.

If there's a better way to do this I'll gladly rewrite this code.  I
think the complexity of the mechanism I have in place is very close to
the minimum.  One possible idea is to have a global variable that is
changed at subtransaction start... however I think handling that is more
complicated because we need to append some things on subtrans commit but
forget them on subtrans abort, so it's not that trivial.

--
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"Investigación es lo que hago cuando no sé lo que estoy haciendo"
(Wernher von Braun)

pgsql-patches by date:

Previous
From: Rod Taylor
Date:
Subject: Synopsis inconsistencies
Next
From: Bruce Momjian
Date:
Subject: Re: ipv6 patch #3