mirror of
https://github.com/postgres/postgres.git
synced 2026-05-28 04:35:45 -04:00
Fix pg_plan_queries() to restore the previous setting of ActiveSnapshot
(probably NULL) before exiting. Up to now it's just left the variable as it set it, which means that after we're done processing the current client message, ActiveSnapshot is probably pointing at garbage (because this function is typically run in MessageContext which will get reset). There doesn't seem to have been any code path in which that mattered before 8.3, but now the plancache module might try to use the stale value if the next client message is a Bind for a prepared statement that is in need of replanning. Per report from Alex Hunsaker.
This commit is contained in:
parent
0d540b097c
commit
da6a707c29
1 changed files with 35 additions and 17 deletions
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.544 2008/03/10 12:55:13 mha Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.545 2008/03/12 23:58:27 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* this is the "main" module of the postgres backend and
|
||||
|
|
@ -730,31 +730,49 @@ List *
|
|||
pg_plan_queries(List *querytrees, int cursorOptions, ParamListInfo boundParams,
|
||||
bool needSnapshot)
|
||||
{
|
||||
List *stmt_list = NIL;
|
||||
ListCell *query_list;
|
||||
List * volatile stmt_list = NIL;
|
||||
Snapshot saveActiveSnapshot = ActiveSnapshot;
|
||||
|
||||
foreach(query_list, querytrees)
|
||||
/* PG_TRY to ensure previous ActiveSnapshot is restored on error */
|
||||
PG_TRY();
|
||||
{
|
||||
Query *query = (Query *) lfirst(query_list);
|
||||
Node *stmt;
|
||||
Snapshot mySnapshot = NULL;
|
||||
ListCell *query_list;
|
||||
|
||||
if (query->commandType == CMD_UTILITY)
|
||||
foreach(query_list, querytrees)
|
||||
{
|
||||
/* Utility commands have no plans. */
|
||||
stmt = query->utilityStmt;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (needSnapshot)
|
||||
Query *query = (Query *) lfirst(query_list);
|
||||
Node *stmt;
|
||||
|
||||
if (query->commandType == CMD_UTILITY)
|
||||
{
|
||||
ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
|
||||
needSnapshot = false;
|
||||
/* Utility commands have no plans. */
|
||||
stmt = query->utilityStmt;
|
||||
}
|
||||
stmt = (Node *) pg_plan_query(query, cursorOptions, boundParams);
|
||||
else
|
||||
{
|
||||
if (needSnapshot && mySnapshot == NULL)
|
||||
{
|
||||
mySnapshot = CopySnapshot(GetTransactionSnapshot());
|
||||
ActiveSnapshot = mySnapshot;
|
||||
}
|
||||
stmt = (Node *) pg_plan_query(query, cursorOptions,
|
||||
boundParams);
|
||||
}
|
||||
|
||||
stmt_list = lappend(stmt_list, stmt);
|
||||
}
|
||||
|
||||
stmt_list = lappend(stmt_list, stmt);
|
||||
if (mySnapshot)
|
||||
FreeSnapshot(mySnapshot);
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
ActiveSnapshot = saveActiveSnapshot;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
ActiveSnapshot = saveActiveSnapshot;
|
||||
|
||||
return stmt_list;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue