Skip to content
Snippets Groups Projects
Commit 022b5f2b authored by Tom Lane's avatar Tom Lane
Browse files

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.
parent dfac804a
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
......@@ -1257,3 +1257,27 @@ FETCH ALL FROM c1;
COMMIT;
DROP TABLE cursor;
-- Check rewinding a cursor containing a stable function in LIMIT,
-- per bug report in 8336843.9833.1399385291498.JavaMail.root@quick
begin;
create function nochange(int) returns int
as 'select $1 limit 1' language sql stable;
declare c cursor for select * from int8_tbl limit nochange(3);
fetch all from c;
q1 | q2
------------------+------------------
123 | 456
123 | 4567890123456789
4567890123456789 | 123
(3 rows)
move backward all in c;
fetch all from c;
q1 | q2
------------------+------------------
123 | 456
123 | 4567890123456789
4567890123456789 | 123
(3 rows)
rollback;
......@@ -470,3 +470,14 @@ UPDATE cursor SET a = 2;
FETCH ALL FROM c1;
COMMIT;
DROP TABLE cursor;
-- Check rewinding a cursor containing a stable function in LIMIT,
-- per bug report in 8336843.9833.1399385291498.JavaMail.root@quick
begin;
create function nochange(int) returns int
as 'select $1 limit 1' language sql stable;
declare c cursor for select * from int8_tbl limit nochange(3);
fetch all from c;
move backward all in c;
fetch all from c;
rollback;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment