8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
15
15
#include "postgres.h"
16
16
17
17
#include "optimizer/clauses.h"
18
18
#include "optimizer/tlist.h"
19
+ #include "optimizer/var.h"
19
20
#include "parser/parse_agg.h"
20
21
#include "parser/parsetree.h"
21
22
@@ -179,7 +180,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
179
180
{
180
181
List * groupClauses = NIL ;
181
182
bool have_non_var_grouping = false;
182
- List * tl ;
183
+ List * lst ;
184
+ bool hasJoinRTEs ;
185
+ Node * clause ;
183
186
184
187
/* This should only be called if we found aggregates, GROUP, or HAVING */
185
188
Assert (pstate -> p_hasAggs || qry -> groupClause || qry -> havingQual );
@@ -205,9 +208,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
205
208
* repeated scans of the targetlist within the recursive routine...).
206
209
* And detect whether any of the expressions aren't simple Vars.
207
210
*/
208
- foreach (tl ,qry -> groupClause )
211
+ foreach (lst ,qry -> groupClause )
209
212
{
210
- GroupClause * grpcl = lfirst (tl );
213
+ GroupClause * grpcl = ( GroupClause * ) lfirst (lst );
211
214
Node * expr ;
212
215
213
216
expr = get_sortgroupclause_expr (grpcl ,qry -> targetList );
@@ -220,14 +223,40 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
220
223
have_non_var_grouping = true;
221
224
}
222
225
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
+
223
248
/*
224
249
* Check the targetlist and HAVING clause for ungrouped variables.
225
250
*/
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 ,
229
255
groupClauses ,have_non_var_grouping );
230
256
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 );
233
262
}