aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-12-13 02:00:20 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-12-13 02:00:20 +0000
commitc98a923786fdd5c297e3cd0165e39102094277d8 (patch)
tree278fae9d3cd52d742cb4c93b52200e6a52ea5e6b /src/backend/utils/cache
parent0f864a63ea532a475490d4259608385ad717280c (diff)
downloadpostgresql-c98a923786fdd5c297e3cd0165e39102094277d8.tar.gz
postgresql-c98a923786fdd5c297e3cd0165e39102094277d8.zip
Fix failure to ensure that a snapshot is available to datatype input functions
when they are invoked by the parser. We had been setting up a snapshot at plan time but really it needs to be done earlier, before parse analysis. Per report from Dmitry Koterov. Also fix two related problems discovered while poking at this one: exec_bind_message called datatype input functions without establishing a snapshot, and SET CONSTRAINTS IMMEDIATE could call trigger functions without establishing a snapshot. Backpatch to 8.2. The underlying problem goes much further back, but it is masked in 8.1 and before because we didn't attempt to invoke domain check constraints within datatype input. It would only be exposed if a C-language datatype input function used the snapshot; which evidently none do, or we'd have heard complaints sooner. Since this code has changed a lot over time, a back-patch is hardly risk-free, and so I'm disinclined to patch further than absolutely necessary.
Diffstat (limited to 'src/backend/utils/cache')
-rw-r--r--src/backend/utils/cache/plancache.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c
index fd535c0090d..88affe67102 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -35,7 +35,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/plancache.c,v 1.23 2008/10/04 21:56:54 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/plancache.c,v 1.24 2008/12/13 02:00:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -463,6 +463,7 @@ RevalidateCachedPlan(CachedPlanSource *plansource, bool useResOwner)
*/
if (!plan)
{
+ bool snapshot_set = false;
List *slist;
TupleDesc resultDesc;
@@ -473,6 +474,19 @@ RevalidateCachedPlan(CachedPlanSource *plansource, bool useResOwner)
PushOverrideSearchPath(plansource->search_path);
/*
+ * If a snapshot is already set (the normal case), we can just use
+ * that for parsing/planning. But if it isn't, install one. Note:
+ * no point in checking whether parse analysis requires a snapshot;
+ * utility commands don't have invalidatable plans, so we'd not get
+ * here for such a command.
+ */
+ if (!ActiveSnapshotSet())
+ {
+ PushActiveSnapshot(GetTransactionSnapshot());
+ snapshot_set = true;
+ }
+
+ /*
* Run parse analysis and rule rewriting. The parser tends to
* scribble on its input, so we must copy the raw parse tree to
* prevent corruption of the cache. Note that we do not use
@@ -488,13 +502,9 @@ RevalidateCachedPlan(CachedPlanSource *plansource, bool useResOwner)
{
/*
* Generate plans for queries.
- *
- * If a snapshot is already set (the normal case), we can just use
- * that for planning. But if it isn't, we have to tell
- * pg_plan_queries to make a snap if it needs one.
*/
slist = pg_plan_queries(slist, plansource->cursor_options,
- NULL, !ActiveSnapshotSet());
+ NULL, false);
}
/*
@@ -525,6 +535,10 @@ RevalidateCachedPlan(CachedPlanSource *plansource, bool useResOwner)
MemoryContextSwitchTo(oldcxt);
}
+ /* Release snapshot if we got one */
+ if (snapshot_set)
+ PopActiveSnapshot();
+
/* Now we can restore current search path */
PopOverrideSearchPath();