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

Commit6302fe6

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 parent87be73e commit6302fe6

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
@@ -73,6 +73,9 @@ ExecSubPlan(SubPlanState *node,
7373
ExprDoneCond*isDone)
7474
{
7575
SubPlan*subplan= (SubPlan*)node->xprstate.expr;
76+
EState*estate=node->planstate->state;
77+
ScanDirectiondir=estate->es_direction;
78+
Datumretval;
7679

7780
/* Set default values for result flags: non-null, not a set result */
7881
*isNull= false;
@@ -85,11 +88,19 @@ ExecSubPlan(SubPlanState *node,
8588
if (subplan->setParam!=NIL&&subplan->subLinkType!=MULTIEXPR_SUBLINK)
8689
elog(ERROR,"cannot set parent params from subquery");
8790

91+
/* Force forward-scan mode for evaluation */
92+
estate->es_direction=ForwardScanDirection;
93+
8894
/* Select appropriate evaluation strategy */
8995
if (subplan->useHashTable)
90-
returnExecHashSubPlan(node,econtext,isNull);
96+
retval=ExecHashSubPlan(node,econtext,isNull);
9197
else
92-
returnExecScanSubPlan(node,econtext,isNull);
98+
retval=ExecScanSubPlan(node,econtext,isNull);
99+
100+
/* restore scan direction */
101+
estate->es_direction=dir;
102+
103+
returnretval;
93104
}
94105

95106
/*
@@ -944,6 +955,8 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
944955
SubPlan*subplan= (SubPlan*)node->xprstate.expr;
945956
PlanState*planstate=node->planstate;
946957
SubLinkTypesubLinkType=subplan->subLinkType;
958+
EState*estate=planstate->state;
959+
ScanDirectiondir=estate->es_direction;
947960
MemoryContextoldcontext;
948961
TupleTableSlot*slot;
949962
ListCell*pvar;
@@ -957,6 +970,12 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
957970
if (subLinkType==CTE_SUBLINK)
958971
elog(ERROR,"CTE subplans should not be executed via ExecSetParamPlan");
959972

973+
/*
974+
* Enforce forward scan direction regardless of caller. It's hard but not
975+
* impossible to get here in backward scan, so make it work anyway.
976+
*/
977+
estate->es_direction=ForwardScanDirection;
978+
960979
/* Initialize ArrayBuildStateAny in caller's context, if needed */
961980
if (subLinkType==ARRAY_SUBLINK)
962981
astate=initArrayResultAny(subplan->firstColType,
@@ -1110,6 +1129,9 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
11101129
}
11111130

11121131
MemoryContextSwitchTo(oldcontext);
1132+
1133+
/* restore scan direction */
1134+
estate->es_direction=dir;
11131135
}
11141136

11151137
/*

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,3 +933,20 @@ select nextval('ts1');
933933
11
934934
(1 row)
935935

936+
--
937+
-- Ensure that backward scan direction isn't propagated into
938+
-- expression subqueries (bug #15336)
939+
--
940+
begin;
941+
declare c1 scroll cursor for
942+
select * from generate_series(1,4) i
943+
where i <> all (values (2),(3));
944+
move forward all in c1;
945+
fetch backward all in c1;
946+
i
947+
---
948+
4
949+
1
950+
(2 rows)
951+
952+
commit;

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,3 +496,19 @@ select * from
496496
order by1;
497497

498498
select nextval('ts1');
499+
500+
--
501+
-- Ensure that backward scan direction isn't propagated into
502+
-- expression subqueries (bug #15336)
503+
--
504+
505+
begin;
506+
507+
declare c1 scroll cursor for
508+
select*from generate_series(1,4) i
509+
where i<> all (values (2),(3));
510+
511+
move forward allin c1;
512+
fetch backward allin c1;
513+
514+
commit;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp