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

Commitd31ebbf

Browse files
committed
Set scan direction appropriately for SubPlans (bug #15336)
When executing a SubPlan in an expression, the EState's directionfield was left alone, resulting in an attempt to execute the subplanbackwards if it was encountered during a backwards scan of a cursor.Also, though much less likely, it was possible to reach the executionof an InitPlan while in backwards-scan state.Repair by saving/restoring estate->es_direction and forcing forwardscan mode in the relevant places.Backpatch all the way, since this has been broken since 8.3 (prior tocommitc7ff766, SubPlans had their own EStates rather than sharingthe parent plan's, so there was no confusion over scan direction).Per bug #15336 reported by Vladimir Baranoff; analysis and patch byme, review by Tom Lane.Discussion:https://postgr.es/m/153449812167.1304.1741624125628126322@wrigleys.postgresql.org
1 parentbd30f51 commitd31ebbf

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

‎src/backend/executor/nodeSubplan.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ ExecSubPlan(SubPlanState *node,
6565
bool*isNull)
6666
{
6767
SubPlan*subplan=node->subplan;
68+
EState*estate=node->planstate->state;
69+
ScanDirectiondir=estate->es_direction;
70+
Datumretval;
6871

6972
CHECK_FOR_INTERRUPTS();
7073

@@ -77,11 +80,19 @@ ExecSubPlan(SubPlanState *node,
7780
if (subplan->setParam!=NIL&&subplan->subLinkType!=MULTIEXPR_SUBLINK)
7881
elog(ERROR,"cannot set parent params from subquery");
7982

83+
/* Force forward-scan mode for evaluation */
84+
estate->es_direction=ForwardScanDirection;
85+
8086
/* Select appropriate evaluation strategy */
8187
if (subplan->useHashTable)
82-
returnExecHashSubPlan(node,econtext,isNull);
88+
retval=ExecHashSubPlan(node,econtext,isNull);
8389
else
84-
returnExecScanSubPlan(node,econtext,isNull);
90+
retval=ExecScanSubPlan(node,econtext,isNull);
91+
92+
/* restore scan direction */
93+
estate->es_direction=dir;
94+
95+
returnretval;
8596
}
8697

8798
/*
@@ -918,6 +929,8 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
918929
SubPlan*subplan=node->subplan;
919930
PlanState*planstate=node->planstate;
920931
SubLinkTypesubLinkType=subplan->subLinkType;
932+
EState*estate=planstate->state;
933+
ScanDirectiondir=estate->es_direction;
921934
MemoryContextoldcontext;
922935
TupleTableSlot*slot;
923936
ListCell*pvar;
@@ -931,6 +944,12 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
931944
if (subLinkType==CTE_SUBLINK)
932945
elog(ERROR,"CTE subplans should not be executed via ExecSetParamPlan");
933946

947+
/*
948+
* Enforce forward scan direction regardless of caller. It's hard but not
949+
* impossible to get here in backward scan, so make it work anyway.
950+
*/
951+
estate->es_direction=ForwardScanDirection;
952+
934953
/* Initialize ArrayBuildStateAny in caller's context, if needed */
935954
if (subLinkType==ARRAY_SUBLINK)
936955
astate=initArrayResultAny(subplan->firstColType,
@@ -1083,6 +1102,9 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
10831102
}
10841103

10851104
MemoryContextSwitchTo(oldcontext);
1105+
1106+
/* restore scan direction */
1107+
estate->es_direction=dir;
10861108
}
10871109

10881110
/*

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,3 +1085,20 @@ NOTICE: x = 9, y = 13
10851085
(3 rows)
10861086

10871087
drop function tattle(x int, y int);
1088+
--
1089+
-- Ensure that backward scan direction isn't propagated into
1090+
-- expression subqueries (bug #15336)
1091+
--
1092+
begin;
1093+
declare c1 scroll cursor for
1094+
select * from generate_series(1,4) i
1095+
where i <> all (values (2),(3));
1096+
move forward all in c1;
1097+
fetch backward all in c1;
1098+
i
1099+
---
1100+
4
1101+
1
1102+
(2 rows)
1103+
1104+
commit;

‎src/test/regress/sql/subselect.sql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,3 +568,19 @@ select * from
568568
where tattle(x, u);
569569

570570
dropfunction tattle(xint, yint);
571+
572+
--
573+
-- Ensure that backward scan direction isn't propagated into
574+
-- expression subqueries (bug #15336)
575+
--
576+
577+
begin;
578+
579+
declare c1 scroll cursor for
580+
select*from generate_series(1,4) i
581+
where i<> all (values (2),(3));
582+
583+
move forward allin c1;
584+
fetch backward allin c1;
585+
586+
commit;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp