]> 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:09 +0000 (18:04 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 3 Apr 2003 18:04:09 +0000 (18:04 +0000)
of unnamed joins; per pghackers discussion 31-Mar-03.

src/backend/parser/parse_agg.c

index f980d52f2b0e72e2fbee05a4f094227dcc2aa367..92ea3b9bd9e4b54198c802e78cc11fdbb11988f1 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.51 2003/01/17 03:25:04 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.52 2003/04/03 18:04:09 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"
 
@@ -179,7 +180,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
 {
        List       *groupClauses = NIL;
        bool            have_non_var_grouping = false;
-       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);
@@ -205,9 +208,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
         * repeated scans of the targetlist within the recursive routine...).
         * And detect whether any of the expressions aren't simple Vars.
         */
-       foreach(tl, qry->groupClause)
+       foreach(lst, qry->groupClause)
        {
-               GroupClause *grpcl = lfirst(tl);
+               GroupClause *grpcl = (GroupClause *) lfirst(lst);
                Node       *expr;
 
                expr = get_sortgroupclause_expr(grpcl, qry->targetList);
@@ -220,14 +223,40 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
                        have_non_var_grouping = true;
        }
 
+       /*
+        * 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.
+        */
+       hasJoinRTEs = false;
+       foreach(lst, pstate->p_rtable)
+       {
+               RangeTblEntry *rte = (RangeTblEntry *) lfirst(lst);
+
+               if (rte->rtekind == RTE_JOIN)
+               {
+                       hasJoinRTEs = true;
+                       break;
+               }
+       }
+
+       if (hasJoinRTEs)
+               groupClauses = (List *) flatten_join_alias_vars(qry,
+                                                                                                               (Node *) groupClauses);
+
        /*
         * Check the targetlist and HAVING clause for ungrouped variables.
         */
-       check_ungrouped_columns((Node *) qry->targetList, pstate,
-                                                       groupClauses, have_non_var_grouping);
-       check_ungrouped_columns((Node *) qry->havingQual, pstate,
+       clause = (Node *) qry->targetList;
+       if (hasJoinRTEs)
+               clause = flatten_join_alias_vars(qry, clause);
+       check_ungrouped_columns(clause, pstate,
                                                        groupClauses, have_non_var_grouping);
 
-       /* Release the list storage (but not the pointed-to expressions!) */
-       freeList(groupClauses);
+       clause = (Node *) qry->havingQual;
+       if (hasJoinRTEs)
+               clause = flatten_join_alias_vars(qry, clause);
+       check_ungrouped_columns(clause, pstate,
+                                                       groupClauses, have_non_var_grouping);
 }