diff options
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r-- | src/backend/tcop/postgres.c | 54 |
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. */ |