summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-02-02 19:09:08 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-02-02 19:09:08 +0000
commite59750d68467c91a2d85c21fda04aef18f4d7de1 (patch)
treed9018fd312a7ef83be7af518eb5a3101762f38c7
parentd77c6396bbd84429c3bdf773c76c7b25c23734a2 (diff)
downloadpostgresql-e59750d68467c91a2d85c21fda04aef18f4d7de1.tar.gz
Fix nodeUnique to behave correctly when reversing direction after reaching
either end of subplan results. This prevents misbehavior of cursors on SELECT DISTINCT ... queries. Per bug report 1-Feb-02.
-rw-r--r--src/backend/executor/nodeUnique.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c
index b71403de0b..e571c2263f 100644
--- a/src/backend/executor/nodeUnique.c
+++ b/src/backend/executor/nodeUnique.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.34 2002/06/20 20:29:28 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.34.2.1 2003/02/02 19:09:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -58,6 +58,11 @@ ExecUnique(Unique *node)
/*
* now loop, returning only non-duplicate tuples. We assume that the
* tuples arrive in sorted order so we can detect duplicates easily.
+ *
+ * We return the first tuple from each group of duplicates (or the
+ * last tuple of each group, when moving backwards). At either end
+ * of the subplan, clear priorTuple so that we correctly return the
+ * first/last tuple when reversing direction.
*/
for (;;)
{
@@ -66,10 +71,16 @@ ExecUnique(Unique *node)
*/
slot = ExecProcNode(outerPlan, (Plan *) node);
if (TupIsNull(slot))
+ {
+ /* end of subplan; reset in case we change direction */
+ if (uniquestate->priorTuple != NULL)
+ heap_freetuple(uniquestate->priorTuple);
+ uniquestate->priorTuple = NULL;
return NULL;
+ }
/*
- * Always return the first tuple from the subplan.
+ * Always return the first/last tuple from the subplan.
*/
if (uniquestate->priorTuple == NULL)
break;