From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Alvaro Herrera <alvherre(at)commandprompt(dot)com> |
Cc: | pgsql-hackers(at)postgresql(dot)org |
Subject: | Re: So, why shouldn't SET CONSTRAINTS set a transaction snapshot? |
Date: | 2008-12-12 23:09:50 |
Message-ID: | 12759.1229123390@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Alvaro Herrera <alvherre(at)commandprompt(dot)com> writes:
> Tom Lane wrote:
>> 1. Always set a snapshot for SET CONSTRAINTS. This is a minus-one-liner
>> --- just remove it from the exclusion list in PortalRunUtility.
>>
>> 2. Have it set a snapshot only if it finds pending trigger events to
>> fire. This would only require another half dozen lines of code, but
>> it's certainly more complicated than choice #1.
> It seems to me there is room for a backwards compatibility argument
> here. How about doing #2 for 8.3 and back, and #1 for 8.4?
Well, if you think there's a real backwards compatibility issue, we
should just do #2 and be done with it. It's not like it's enough code
to really matter in the big scheme of things.
Index: src/backend/commands/trigger.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/trigger.c,v
retrieving revision 1.241
diff -c -r1.241 trigger.c
*** src/backend/commands/trigger.c 21 Nov 2008 20:14:27 -0000 1.241
--- src/backend/commands/trigger.c 12 Dec 2008 23:08:41 -0000
***************
*** 3716,3727 ****
--- 3716,3743 ----
if (!stmt->deferred)
{
AfterTriggerEventList *events = &afterTriggers->events;
+ bool snapshot_set = false;
while (afterTriggerMarkEvents(events, NULL, true))
{
CommandId firing_id = afterTriggers->firing_counter++;
/*
+ * Make sure a snapshot has been established in case trigger
+ * functions need one. Note that we avoid setting a snapshot if
+ * we don't find at least one trigger that has to be fired now.
+ * This is so that BEGIN; SET CONSTRAINTS ...; SET TRANSACTION
+ * ISOLATION LEVEL SERIALIZABLE; ... works properly. (If we are
+ * at the start of a transaction it's not possible for any trigger
+ * events to be queued yet.)
+ */
+ if (!snapshot_set)
+ {
+ PushActiveSnapshot(GetTransactionSnapshot());
+ snapshot_set = true;
+ }
+
+ /*
* We can delete fired events if we are at top transaction level,
* but we'd better not if inside a subtransaction, since the
* subtransaction could later get rolled back.
***************
*** 3730,3735 ****
--- 3746,3754 ----
!IsSubTransaction()))
break; /* all fired */
}
+
+ if (snapshot_set)
+ PopActiveSnapshot();
}
}
regards, tom lane
From | Date | Subject | |
---|---|---|---|
Next Message | KaiGai Kohei | 2008-12-13 02:24:51 | Re: Updates of SE-PostgreSQL 8.4devel patches (r1268) |
Previous Message | Markus Wanner | 2008-12-12 23:00:07 | Re: Sync Rep: First Thoughts on Code |