Prohibit shutting down resources if there is a possibility of back up.
authorAmit Kapila
Mon, 13 Aug 2018 03:13:33 +0000 (08:43 +0530)
committerAmit Kapila
Mon, 13 Aug 2018 03:13:33 +0000 (08:43 +0530)
Currently, we release the asynchronous resources as soon as it is evident
that no more rows will be needed e.g. when a Limit is filled.  This can be
problematic especially for custom and foreign scans where we can scan
backward.  Fix that by disallowing the shutting down of resources in such
cases.

Reported-by: Robert Haas
Analysed-by: Robert Haas and Amit Kapila
Author: Amit Kapila
Reviewed-by: Robert Haas
Backpatch-through: 9.6 where this code was introduced
Discussion: https://postgr.es/m/86137f17-1dfb-42f9-7421-82fd786b04a1@anayrat.info

src/backend/executor/execMain.c
src/backend/executor/nodeLimit.c

index 878e8e9ea13fd509d3007dcdc48d45308ad2b109..6f467c65c101505c97e829ca7d65ab41a914d92a 100644 (file)
@@ -1727,8 +1727,12 @@ ExecutePlan(EState *estate,
         */
        if (TupIsNull(slot))
        {
-           /* Allow nodes to release or shut down resources. */
-           (void) ExecShutdownNode(planstate);
+           /*
+            * If we know we won't need to back up, we can release
+            * resources at this point.
+            */
+           if (!(estate->es_top_eflags & EXEC_FLAG_BACKWARD))
+               (void) ExecShutdownNode(planstate);
            break;
        }
 
@@ -1774,8 +1778,12 @@ ExecutePlan(EState *estate,
        current_tuple_count++;
        if (numberTuples && numberTuples == current_tuple_count)
        {
-           /* Allow nodes to release or shut down resources. */
-           (void) ExecShutdownNode(planstate);
+           /*
+            * If we know we won't need to back up, we can release
+            * resources at this point.
+            */
+           if (!(estate->es_top_eflags & EXEC_FLAG_BACKWARD))
+               (void) ExecShutdownNode(planstate);
            break;
        }
    }
index cf1851e235f9f2f636aeecf09713fce4c622594a..6e74bb23d06acb6282772d8957b1d1694396e9b2 100644 (file)
@@ -134,8 +134,14 @@ ExecLimit(PlanState *pstate)
                    node->position - node->offset >= node->count)
                {
                    node->lstate = LIMIT_WINDOWEND;
-                   /* Allow nodes to release or shut down resources. */
-                   (void) ExecShutdownNode(outerPlan);
+
+                   /*
+                    * If we know we won't need to back up, we can release
+                    * resources at this point.
+                    */
+                   if (!(node->ps.state->es_top_eflags & EXEC_FLAG_BACKWARD))
+                       (void) ExecShutdownNode(outerPlan);
+
                    return NULL;
                }