1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-05 07:21:24 +03:00

Fix failure to set ActiveSnapshot while rewinding a cursor.

ActiveSnapshot needs to be set when we call ExecutorRewind because some
plan node types may execute user-defined functions during their ReScan
calls (nodeLimit.c does so, at least).  The wisdom of that is somewhat
debatable, perhaps, but for now the simplest fix is to make sure the
required context is valid.  Failure to do this typically led to a
null-pointer-dereference core dump, though it's possible that in more
complex cases a function could be executed with the wrong snapshot
leading to very subtle misbehavior.

Per report from Leif Jensen.  It's been broken for a long time, so
back-patch to all active branches.
This commit is contained in:
Tom Lane
2014-05-07 14:25:11 -04:00
parent e2ce9aa27b
commit 04e5025be8
3 changed files with 47 additions and 2 deletions

View File

@ -1661,6 +1661,9 @@ DoPortalRunFetch(Portal portal,
static void
DoPortalRewind(Portal portal)
{
QueryDesc *queryDesc;
/* Rewind holdStore, if we have one */
if (portal->holdStore)
{
MemoryContext oldcontext;
@ -1669,8 +1672,15 @@ DoPortalRewind(Portal portal)
tuplestore_rescan(portal->holdStore);
MemoryContextSwitchTo(oldcontext);
}
if (PortalGetQueryDesc(portal))
ExecutorRewind(PortalGetQueryDesc(portal));
/* Rewind executor, if active */
queryDesc = PortalGetQueryDesc(portal);
if (queryDesc)
{
PushActiveSnapshot(queryDesc->snapshot);
ExecutorRewind(queryDesc);
PopActiveSnapshot();
}
portal->atStart = true;
portal->atEnd = false;