On 9/6/16 12:00 PM, Tom Lane wrote:
On the other hand, if eof_cte is true, then what happened on the last
call is that we tried to fetch forwards, reached EOF on the underlying
query, and returned NULL.  In that case, a backwards fetch *should*
produce the last row in the tuplestore.

Patch attached.
--
Jim Nasby, Data Architect, Blue Treble Consulting, Austin TX
Experts in Analytics, Data Architecture and PostgreSQL
Data in Trouble? Get it in Treble! http://BlueTreble.com
855-TREBLE2 (855-873-2532)   mobile: 512-569-9461
diff --git a/src/backend/executor/nodeCtescan.c 
b/src/backend/executor/nodeCtescan.c
index 3c2f684..64248cb 100644
--- a/src/backend/executor/nodeCtescan.c
+++ b/src/backend/executor/nodeCtescan.c
@@ -53,8 +53,21 @@ CteScanNext(CteScanState *node)
         */
        eof_tuplestore = tuplestore_ateof(tuplestorestate);
 
+       /*
+        * Before fetching, we need to handle a special case: when reversing
+        * direction at the end of the tuplestore, the next
+        * tuplestore_gettupleslot() call will return the last tuple. But since
+        * that tuple was just seen, we want to move past it. This is necessary
+        * because the tuplestore get routines always move the current pointer,
+        * unless they hit the end (or beginning) of the store.
+        */
        if (!forward && eof_tuplestore)
        {
+               /*
+                * However, once we hit the end of the underlying node any call 
while
+                * at the end of the tuplestore will return NULL. In that case, 
we DO
+                * want to return the last row in the tuplestore.
+                */
                if (!node->leader->eof_cte)
                {
                        /*
diff --git a/src/backend/executor/nodeMaterial.c 
b/src/backend/executor/nodeMaterial.c
index 9ab03f3..197b91b 100644
--- a/src/backend/executor/nodeMaterial.c
+++ b/src/backend/executor/nodeMaterial.c
@@ -82,16 +82,23 @@ ExecMaterial(MaterialState *node)
        eof_tuplestore = (tuplestorestate == NULL) ||
                tuplestore_ateof(tuplestorestate);
 
+       /*
+        * Before fetching, we need to handle a special case: when reversing
+        * direction at the end of the tuplestore, the next
+        * tuplestore_gettupleslot() call will return the last tuple. But since
+        * that tuple was just seen, we want to move past it. This is necessary
+        * because the tuplestore get routines always move the current pointer,
+        * unless they hit the end (or beginning) of the store.
+        */
        if (!forward && eof_tuplestore)
        {
+               /*
+                * However, once we hit the end of the underlying node any call 
while
+                * at the end of the tuplestore will return NULL. In that case, 
we DO
+                * want to return the last row in the tuplestore.
+                */
                if (!node->eof_underlying)
                {
-                       /*
-                        * When reversing direction at tuplestore EOF, the first
-                        * gettupleslot call will fetch the last-added tuple; 
but we want
-                        * to return the one before that, if possible. So do an 
extra
-                        * fetch.
-                        */
                        if (!tuplestore_advance(tuplestorestate, forward))
                                return NULL;    /* the tuplestore must be empty 
*/
                }
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to