aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/portalcmds.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c
index 3ea30bcbc99..b8590d422b6 100644
--- a/src/backend/commands/portalcmds.c
+++ b/src/backend/commands/portalcmds.c
@@ -358,6 +358,8 @@ PersistHoldablePortal(Portal portal)
savePortalContext = PortalContext;
PG_TRY();
{
+ ScanDirection direction = ForwardScanDirection;
+
ActivePortal = portal;
if (portal->resowner)
CurrentResourceOwner = portal->resowner;
@@ -380,10 +382,20 @@ PersistHoldablePortal(Portal portal)
}
else
{
- /* We must reset the cursor state as though at start of query */
+ /* Disallow moving backwards from here */
portal->atStart = true;
- portal->atEnd = false;
portal->portalPos = 0;
+
+ /*
+ * If we already reached end-of-query, set the direction to
+ * NoMovement to avoid trying to fetch any tuples. (This check
+ * exists because not all plan node types are robust about being
+ * called again if they've already returned NULL once.) We'll
+ * still set up an empty tuplestore, though, to keep this from
+ * being a special case later.
+ */
+ if (portal->atEnd)
+ direction = NoMovementScanDirection;
}
/*
@@ -400,7 +412,7 @@ PersistHoldablePortal(Portal portal)
NULL);
/* Fetch the result set into the tuplestore */
- ExecutorRun(queryDesc, ForwardScanDirection, 0L, false);
+ ExecutorRun(queryDesc, direction, 0L, false);
queryDesc->dest->rDestroy(queryDesc->dest);
queryDesc->dest = NULL;