]> granicus.if.org Git - postgresql/commitdiff
Prohibit shutting down resources if there is a possibility of back up.
authorAmit Kapila <akapila@postgresql.org>
Mon, 13 Aug 2018 02:52:18 +0000 (08:22 +0530)
committerAmit Kapila <akapila@postgresql.org>
Mon, 13 Aug 2018 02:52:18 +0000 (08:22 +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 b797d064b7e046aa3c3ffff4aac73d7266be349d..c583e020a0e1673ed594ecfce180c8063f0d412d 100644 (file)
@@ -1726,8 +1726,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;
                }
 
@@ -1773,8 +1777,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 66ea6aa3c35215965e558f9c6f1601c9df67cc79..bb28cf7d1db8f219b96afd57e416a5ae5a9a7671 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;
                                }