Skip to content

Commit 906dce0

Browse files
committed
Repair incorrect checking of grouped/ungrouped variables in the presence
of unnamed joins; per pghackers discussion 31-Mar-03.
1 parent cdbd298 commit 906dce0

File tree

1 file changed

+38
-9
lines changed

1 file changed

+38
-9
lines changed

src/backend/parser/parse_agg.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.51 2003/01/17 03:25:04 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.52 2003/04/03 18:04:09 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include "postgres.h"
1616

1717
#include "optimizer/clauses.h"
1818
#include "optimizer/tlist.h"
19+
#include "optimizer/var.h"
1920
#include "parser/parse_agg.h"
2021
#include "parser/parsetree.h"
2122

@@ -179,7 +180,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
179180
{
180181
List *groupClauses = NIL;
181182
bool have_non_var_grouping = false;
182-
List *tl;
183+
List *lst;
184+
bool hasJoinRTEs;
185+
Node *clause;
183186

184187
/* This should only be called if we found aggregates, GROUP, or HAVING */
185188
Assert(pstate->p_hasAggs || qry->groupClause || qry->havingQual);
@@ -205,9 +208,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
205208
* repeated scans of the targetlist within the recursive routine...).
206209
* And detect whether any of the expressions aren't simple Vars.
207210
*/
208-
foreach(tl, qry->groupClause)
211+
foreach(lst, qry->groupClause)
209212
{
210-
GroupClause *grpcl = lfirst(tl);
213+
GroupClause *grpcl = (GroupClause *) lfirst(lst);
211214
Node *expr;
212215

213216
expr = get_sortgroupclause_expr(grpcl, qry->targetList);
@@ -220,14 +223,40 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
220223
have_non_var_grouping = true;
221224
}
222225

226+
/*
227+
* If there are join alias vars involved, we have to flatten them
228+
* to the underlying vars, so that aliased and unaliased vars will be
229+
* correctly taken as equal. We can skip the expense of doing this
230+
* if no rangetable entries are RTE_JOIN kind.
231+
*/
232+
hasJoinRTEs = false;
233+
foreach(lst, pstate->p_rtable)
234+
{
235+
RangeTblEntry *rte = (RangeTblEntry *) lfirst(lst);
236+
237+
if (rte->rtekind == RTE_JOIN)
238+
{
239+
hasJoinRTEs = true;
240+
break;
241+
}
242+
}
243+
244+
if (hasJoinRTEs)
245+
groupClauses = (List *) flatten_join_alias_vars(qry,
246+
(Node *) groupClauses);
247+
223248
/*
224249
* Check the targetlist and HAVING clause for ungrouped variables.
225250
*/
226-
check_ungrouped_columns((Node *) qry->targetList, pstate,
227-
groupClauses, have_non_var_grouping);
228-
check_ungrouped_columns((Node *) qry->havingQual, pstate,
251+
clause = (Node *) qry->targetList;
252+
if (hasJoinRTEs)
253+
clause = flatten_join_alias_vars(qry, clause);
254+
check_ungrouped_columns(clause, pstate,
229255
groupClauses, have_non_var_grouping);
230256

231-
/* Release the list storage (but not the pointed-to expressions!) */
232-
freeList(groupClauses);
257+
clause = (Node *) qry->havingQual;
258+
if (hasJoinRTEs)
259+
clause = flatten_join_alias_vars(qry, clause);
260+
check_ungrouped_columns(clause, pstate,
261+
groupClauses, have_non_var_grouping);
233262
}

0 commit comments

Comments
 (0)