aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tcop/postgres.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r--src/backend/tcop/postgres.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index bcb116a50e4..1ebcaa482b6 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.518.2.1 2007/01/04 00:58:01 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.518.2.2 2008/12/13 02:00:52 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -655,6 +655,9 @@ pg_plan_query(Query *querytree, ParamListInfo boundParams)
if (querytree->commandType == CMD_UTILITY)
return NULL;
+ /* Planner must have a snapshot in case it calls user-defined functions. */
+ Assert(ActiveSnapshot != NULL);
+
if (log_planner_stats)
ResetUsage();
@@ -823,6 +826,7 @@ exec_simple_query(const char *query_string)
foreach(parsetree_item, parsetree_list)
{
Node *parsetree = (Node *) lfirst(parsetree_item);
+ Snapshot mySnapshot = NULL;
const char *commandTag;
char completionTag[COMPLETION_TAG_BUFSIZE];
List *querytree_list,
@@ -865,6 +869,15 @@ exec_simple_query(const char *query_string)
CHECK_FOR_INTERRUPTS();
/*
+ * Set up a snapshot if parse analysis/planning will need one.
+ */
+ if (analyze_requires_snapshot(parsetree))
+ {
+ mySnapshot = CopySnapshot(GetTransactionSnapshot());
+ ActiveSnapshot = mySnapshot;
+ }
+
+ /*
* OK to analyze, rewrite, and plan this query.
*
* Switch to appropriate context for constructing querytrees (again,
@@ -875,7 +888,12 @@ exec_simple_query(const char *query_string)
querytree_list = pg_analyze_and_rewrite(parsetree, query_string,
NULL, 0);
- plantree_list = pg_plan_queries(querytree_list, NULL, true);
+ plantree_list = pg_plan_queries(querytree_list, NULL, false);
+
+ /* Done with the snapshot used for parsing/planning */
+ ActiveSnapshot = NULL;
+ if (mySnapshot)
+ FreeSnapshot(mySnapshot);
/* If we got a cancel signal in analysis or planning, quit */
CHECK_FOR_INTERRUPTS();
@@ -1127,6 +1145,7 @@ exec_parse_message(const char *query_string, /* string to execute */
if (parsetree_list != NIL)
{
Node *parsetree = (Node *) linitial(parsetree_list);
+ Snapshot mySnapshot = NULL;
int i;
/*
@@ -1150,6 +1169,15 @@ exec_parse_message(const char *query_string, /* string to execute */
"commands ignored until end of transaction block")));
/*
+ * Set up a snapshot if parse analysis/planning will need one.
+ */
+ if (analyze_requires_snapshot(parsetree))
+ {
+ mySnapshot = CopySnapshot(GetTransactionSnapshot());
+ ActiveSnapshot = mySnapshot;
+ }
+
+ /*
* OK to analyze, rewrite, and plan this query. Note that the
* originally specified parameter set is not required to be complete,
* so we have to use parse_analyze_varparams().
@@ -1191,7 +1219,12 @@ exec_parse_message(const char *query_string, /* string to execute */
if (!is_named && numParams > 0)
plantree_list = NIL;
else
- plantree_list = pg_plan_queries(querytree_list, NULL, true);
+ plantree_list = pg_plan_queries(querytree_list, NULL, false);
+
+ /* Done with the snapshot used for parsing/planning */
+ ActiveSnapshot = NULL;
+ if (mySnapshot)
+ FreeSnapshot(mySnapshot);
}
else
{
@@ -1401,10 +1434,18 @@ exec_bind_message(StringInfo input_message)
*/
if (numParams > 0)
{
+ Snapshot mySnapshot;
ListCell *l;
MemoryContext oldContext;
int paramno;
+ /*
+ * Set a snapshot if we have parameters to fetch (since the input
+ * functions might need it).
+ */
+ mySnapshot = CopySnapshot(GetTransactionSnapshot());
+ ActiveSnapshot = mySnapshot;
+
oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
/* sizeof(ParamListInfoData) includes the first array element */
@@ -1536,6 +1577,10 @@ exec_bind_message(StringInfo input_message)
}
MemoryContextSwitchTo(oldContext);
+
+ /* Done with the snapshot used for parameter I/O */
+ ActiveSnapshot = NULL;
+ FreeSnapshot(mySnapshot);
}
else
params = NULL;
@@ -3285,6 +3330,9 @@ PostgresMain(int argc, char *argv[], const char *username)
*/
debug_query_string = NULL;
+ /* No active snapshot any more either */
+ ActiveSnapshot = NULL;
+
/*
* Abort the current transaction in order to recover.
*/