Do not allow Unique nodes to be scanned backwards. The code claimed that it
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 5 Aug 2008 21:28:42 +0000 (21:28 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 5 Aug 2008 21:28:42 +0000 (21:28 +0000)
would work, but in fact it didn't return the same rows when moving backwards
as when moving forwards.  This would have no visible effect in a DISTINCT
query (at least assuming the column datatypes use a strong definition of
equality), but it gave entirely wrong answers for DISTINCT ON queries.

src/backend/executor/execAmi.c
src/backend/executor/nodeUnique.c

index 99149f964ef02eb3d14fde75a23b96210eb70f68..2ff3c5363c008831dfdc4e7259aef988bffed21f 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.89.2.2 2008/07/10 01:17:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.89.2.3 2008/08/05 21:28:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -413,9 +413,6 @@ ExecSupportsBackwardScan(Plan *node)
        case T_Sort:
            return true;
 
-       case T_Unique:
-           return ExecSupportsBackwardScan(outerPlan(node));
-
        case T_Limit:
            return ExecSupportsBackwardScan(outerPlan(node));
 
index ce4995c0a424f30348f4a30530662dab56b15730..c5ad6e889c2ae9045d542840f53c6a0ecac9ece9 100644 (file)
@@ -8,14 +8,14 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/executor/nodeUnique.c,v 1.53 2006/07/14 14:52:19 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/executor/nodeUnique.c,v 1.53.2.1 2008/08/05 21:28:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 /*
  * INTERFACE ROUTINES
  *     ExecUnique      - generate a unique'd temporary relation
- *     ExecInitUnique  - initialize node and subnodes..
+ *     ExecInitUnique  - initialize node and subnodes
  *     ExecEndUnique   - shutdown node and subnodes
  *
  * NOTES
@@ -32,9 +32,6 @@
 
 /* ----------------------------------------------------------------
  *     ExecUnique
- *
- *     This is a very simple node which filters out duplicate
- *     tuples from a stream of sorted tuples from a subplan.
  * ----------------------------------------------------------------
  */
 TupleTableSlot *               /* return: a tuple or NULL */
@@ -54,11 +51,7 @@ ExecUnique(UniqueState *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 the result slot so that we correctly return the
-    * first/last tuple when reversing direction.
+    * The first tuple of each group is returned.
     */
    for (;;)
    {
@@ -68,13 +61,13 @@ ExecUnique(UniqueState *node)
        slot = ExecProcNode(outerPlan);
        if (TupIsNull(slot))
        {
-           /* end of subplan; reset in case we change direction */
+           /* end of subplan, so we're done */
            ExecClearTuple(resultTupleSlot);
            return NULL;
        }
 
        /*
-        * Always return the first/last tuple from the subplan.
+        * Always return the first tuple from the subplan.
         */
        if (TupIsNull(resultTupleSlot))
            break;
@@ -113,7 +106,7 @@ ExecInitUnique(Unique *node, EState *estate, int eflags)
    UniqueState *uniquestate;
 
    /* check for unsupported flags */
-   Assert(!(eflags & EXEC_FLAG_MARK));
+   Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
 
    /*
     * create state structure