Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2a527ba

Browse files
committed
Fix failure to set ActiveSnapshot while rewinding a cursor.
ActiveSnapshot needs to be set when we call ExecutorRewind because someplan node types may execute user-defined functions during their ReScancalls (nodeLimit.c does so, at least). The wisdom of that is somewhatdebatable, perhaps, but for now the simplest fix is to make sure therequired context is valid. Failure to do this typically led to anull-pointer-dereference core dump, though it's possible that in morecomplex cases a function could be executed with the wrong snapshotleading to very subtle misbehavior.Per report from Leif Jensen. It's been broken for a long time, soback-patch to all active branches.
1 parentbd4c76a commit2a527ba

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

‎src/backend/tcop/pquery.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,6 +1623,9 @@ DoPortalRunFetch(Portal portal,
16231623
staticvoid
16241624
DoPortalRewind(Portalportal)
16251625
{
1626+
QueryDesc*queryDesc;
1627+
1628+
/* Rewind holdStore, if we have one */
16261629
if (portal->holdStore)
16271630
{
16281631
MemoryContextoldcontext;
@@ -1631,8 +1634,15 @@ DoPortalRewind(Portal portal)
16311634
tuplestore_rescan(portal->holdStore);
16321635
MemoryContextSwitchTo(oldcontext);
16331636
}
1634-
if (PortalGetQueryDesc(portal))
1635-
ExecutorRewind(PortalGetQueryDesc(portal));
1637+
1638+
/* Rewind executor, if active */
1639+
queryDesc=PortalGetQueryDesc(portal);
1640+
if (queryDesc)
1641+
{
1642+
PushActiveSnapshot(queryDesc->snapshot);
1643+
ExecutorRewind(queryDesc);
1644+
PopActiveSnapshot();
1645+
}
16361646

16371647
portal->atStart= true;
16381648
portal->atEnd= false;

‎src/test/regress/expected/portals.out

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,3 +1257,27 @@ FETCH ALL FROM c1;
12571257

12581258
COMMIT;
12591259
DROP TABLE cursor;
1260+
-- Check rewinding a cursor containing a stable function in LIMIT,
1261+
-- per bug report in 8336843.9833.1399385291498.JavaMail.root@quick
1262+
begin;
1263+
create function nochange(int) returns int
1264+
as 'select $1 limit 1' language sql stable;
1265+
declare c cursor for select * from int8_tbl limit nochange(3);
1266+
fetch all from c;
1267+
q1 | q2
1268+
------------------+------------------
1269+
123 | 456
1270+
123 | 4567890123456789
1271+
4567890123456789 | 123
1272+
(3 rows)
1273+
1274+
move backward all in c;
1275+
fetch all from c;
1276+
q1 | q2
1277+
------------------+------------------
1278+
123 | 456
1279+
123 | 4567890123456789
1280+
4567890123456789 | 123
1281+
(3 rows)
1282+
1283+
rollback;

‎src/test/regress/sql/portals.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,3 +470,14 @@ UPDATE cursor SET a = 2;
470470
FETCH ALLFROM c1;
471471
COMMIT;
472472
DROPTABLE cursor;
473+
474+
-- Check rewinding a cursor containing a stable function in LIMIT,
475+
-- per bug report in 8336843.9833.1399385291498.JavaMail.root@quick
476+
begin;
477+
createfunctionnochange(int) returnsint
478+
as'select $1 limit 1' language sql stable;
479+
declare c cursor forselect*from int8_tbllimit nochange(3);
480+
fetch allfrom c;
481+
move backward allin c;
482+
fetch allfrom c;
483+
rollback;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp