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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers