From aab9979c5c8fed679e8f1240aae8cfd4e6432100 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 5 Aug 2008 21:28:42 +0000 Subject: [PATCH] Do not allow Unique nodes to be scanned backwards. The code claimed that it 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 | 5 +---- src/backend/executor/nodeUnique.c | 19 ++++++------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index 99149f964ef..2ff3c5363c0 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -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)); diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c index ce4995c0a42..c5ad6e889c2 100644 --- a/src/backend/executor/nodeUnique.c +++ b/src/backend/executor/nodeUnique.c @@ -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