]> granicus.if.org Git - postgresql/commitdiff
Repair incorrect checking of grouped/ungrouped variables in the presence
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Apr 2003 18:04:17 +0000 (18:04 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Apr 2003 18:04:17 +0000 (18:04 +0000)
of unnamed joins; per pghackers discussion 31-Mar-03.

src/backend/parser/parse_agg.c

index 127abdc2de8567fa2aeeb93a2d29eab385f52acf..6a4f01c77f76949dbeffa221053a87eb3b21b24e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.50 2002/06/20 20:29:32 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.50.2.1 2003/04/03 18:04:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,6 +16,7 @@
 
 #include "optimizer/clauses.h"
 #include "optimizer/tlist.h"
+#include "optimizer/var.h"
 #include "parser/parse_agg.h"
 #include "parser/parsetree.h"
 
@@ -133,7 +134,9 @@ void
 parseCheckAggregates(ParseState *pstate, Query *qry, Node *qual)
 {
        List       *groupClauses = NIL;
-       List       *tl;
+       List       *lst;
+       bool            hasJoinRTEs;
+       Node       *clause;
 
        /* This should only be called if we found aggregates, GROUP, or HAVING */
        Assert(pstate->p_hasAggs || qry->groupClause || qry->havingQual);
@@ -158,9 +161,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry, Node *qual)
         * expressions for use by check_ungrouped_columns() (this avoids
         * repeated scans of the targetlist within the recursive routine...)
         */
-       foreach(tl, qry->groupClause)
+       foreach(lst, qry->groupClause)
        {
-               GroupClause *grpcl = lfirst(tl);
+               GroupClause *grpcl = lfirst(lst);
                Node       *expr;
 
                expr = get_sortgroupclause_expr(grpcl, qry->targetList);
@@ -170,11 +173,38 @@ parseCheckAggregates(ParseState *pstate, Query *qry, Node *qual)
        }
 
        /*
-        * Check the targetlist and HAVING clause for ungrouped variables.
+        * If there are join alias vars involved, we have to flatten them
+        * to the underlying vars, so that aliased and unaliased vars will be
+        * correctly taken as equal.  We can skip the expense of doing this
+        * if no rangetable entries are RTE_JOIN kind.
         */
-       check_ungrouped_columns((Node *) qry->targetList, pstate, groupClauses);
-       check_ungrouped_columns((Node *) qry->havingQual, pstate, groupClauses);
+       hasJoinRTEs = false;
+       foreach(lst, pstate->p_rtable)
+       {
+               RangeTblEntry *rte = (RangeTblEntry *) lfirst(lst);
+
+               if (rte->rtekind == RTE_JOIN)
+               {
+                       hasJoinRTEs = true;
+                       break;
+               }
+       }
 
-       /* Release the list storage (but not the pointed-to expressions!) */
-       freeList(groupClauses);
+       if (hasJoinRTEs)
+               groupClauses = (List *) flatten_join_alias_vars((Node *) groupClauses,
+                                                                                                               pstate->p_rtable,
+                                                                                                               true);
+
+       /*
+        * Check the targetlist and HAVING clause for ungrouped variables.
+        */
+       clause = (Node *) qry->targetList;
+       if (hasJoinRTEs)
+               clause = flatten_join_alias_vars(clause, pstate->p_rtable, true);
+       check_ungrouped_columns(clause, pstate, groupClauses);
+
+       clause = (Node *) qry->havingQual;
+       if (hasJoinRTEs)
+               clause = flatten_join_alias_vars(clause, pstate->p_rtable, true);
+       check_ungrouped_columns(clause, pstate, groupClauses);
 }