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

Commit520acab

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 parent9bed827 commit520acab

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
/*
@@ -1006,6 +1017,8 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
10061017
SubPlan*subplan=node->subplan;
10071018
PlanState*planstate=node->planstate;
10081019
SubLinkTypesubLinkType=subplan->subLinkType;
1020+
EState*estate=planstate->state;
1021+
ScanDirectiondir=estate->es_direction;
10091022
MemoryContextoldcontext;
10101023
TupleTableSlot*slot;
10111024
ListCell*pvar;
@@ -1019,6 +1032,12 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
10191032
if (subLinkType==CTE_SUBLINK)
10201033
elog(ERROR,"CTE subplans should not be executed via ExecSetParamPlan");
10211034

1035+
/*
1036+
* Enforce forward scan direction regardless of caller. It's hard but not
1037+
* impossible to get here in backward scan, so make it work anyway.
1038+
*/
1039+
estate->es_direction=ForwardScanDirection;
1040+
10221041
/* Initialize ArrayBuildStateAny in caller's context, if needed */
10231042
if (subLinkType==ARRAY_SUBLINK)
10241043
astate=initArrayResultAny(subplan->firstColType,
@@ -1171,6 +1190,9 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
11711190
}
11721191

11731192
MemoryContextSwitchTo(oldcontext);
1193+
1194+
/* restore scan direction */
1195+
estate->es_direction=dir;
11741196
}
11751197

11761198
/*

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,3 +1137,20 @@ select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3;
11371137

11381138
drop function explain_sq_limit();
11391139
drop table sq_limit;
1140+
--
1141+
-- Ensure that backward scan direction isn't propagated into
1142+
-- expression subqueries (bug #15336)
1143+
--
1144+
begin;
1145+
declare c1 scroll cursor for
1146+
select * from generate_series(1,4) i
1147+
where i <> all (values (2),(3));
1148+
move forward all in c1;
1149+
fetch backward all in c1;
1150+
i
1151+
---
1152+
4
1153+
1
1154+
(2 rows)
1155+
1156+
commit;

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,3 +609,19 @@ select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3;
609609
dropfunction explain_sq_limit();
610610

611611
droptable sq_limit;
612+
613+
--
614+
-- Ensure that backward scan direction isn't propagated into
615+
-- expression subqueries (bug #15336)
616+
--
617+
618+
begin;
619+
620+
declare c1 scroll cursor for
621+
select*from generate_series(1,4) i
622+
where i<> all (values (2),(3));
623+
624+
move forward allin c1;
625+
fetch backward allin c1;
626+
627+
commit;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp