bool *isNull)
{
SubPlan *subplan = node->subplan;
+ EState *estate = node->planstate->state;
+ ScanDirection dir = estate->es_direction;
+ Datum retval;
CHECK_FOR_INTERRUPTS();
if (subplan->setParam != NIL && subplan->subLinkType != MULTIEXPR_SUBLINK)
elog(ERROR, "cannot set parent params from subquery");
+ /* Force forward-scan mode for evaluation */
+ estate->es_direction = ForwardScanDirection;
+
/* Select appropriate evaluation strategy */
if (subplan->useHashTable)
- return ExecHashSubPlan(node, econtext, isNull);
+ retval = ExecHashSubPlan(node, econtext, isNull);
else
- return ExecScanSubPlan(node, econtext, isNull);
+ retval = ExecScanSubPlan(node, econtext, isNull);
+
+ /* restore scan direction */
+ estate->es_direction = dir;
+
+ return retval;
}
/*
SubPlan *subplan = node->subplan;
PlanState *planstate = node->planstate;
SubLinkType subLinkType = subplan->subLinkType;
+ EState *estate = planstate->state;
+ ScanDirection dir = estate->es_direction;
MemoryContext oldcontext;
TupleTableSlot *slot;
ListCell *pvar;
if (subLinkType == CTE_SUBLINK)
elog(ERROR, "CTE subplans should not be executed via ExecSetParamPlan");
+ /*
+ * Enforce forward scan direction regardless of caller. It's hard but not
+ * impossible to get here in backward scan, so make it work anyway.
+ */
+ estate->es_direction = ForwardScanDirection;
+
/* Initialize ArrayBuildStateAny in caller's context, if needed */
if (subLinkType == ARRAY_SUBLINK)
astate = initArrayResultAny(subplan->firstColType,
}
MemoryContextSwitchTo(oldcontext);
+
+ /* restore scan direction */
+ estate->es_direction = dir;
}
/*
drop function explain_sq_limit();
drop table sq_limit;
+--
+-- Ensure that backward scan direction isn't propagated into
+-- expression subqueries (bug #15336)
+--
+begin;
+declare c1 scroll cursor for
+ select * from generate_series(1,4) i
+ where i <> all (values (2),(3));
+move forward all in c1;
+fetch backward all in c1;
+ i
+---
+ 4
+ 1
+(2 rows)
+
+commit;
drop function explain_sq_limit();
drop table sq_limit;
+
+--
+-- Ensure that backward scan direction isn't propagated into
+-- expression subqueries (bug #15336)
+--
+
+begin;
+
+declare c1 scroll cursor for
+ select * from generate_series(1,4) i
+ where i <> all (values (2),(3));
+
+move forward all in c1;
+fetch backward all in c1;
+
+commit;