mirror of
https://github.com/postgres/postgres.git
synced 2025-11-25 12:03:53 +03:00
Repair incorrect checking of grouped/ungrouped variables in the presence
of unnamed joins; per pghackers discussion 31-Mar-03.
This commit is contained in:
@@ -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);
|
||||
@@ -169,12 +172,39 @@ parseCheckAggregates(ParseState *pstate, Query *qry, Node *qual)
|
||||
groupClauses = lcons(expr, groupClauses);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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((Node *) groupClauses,
|
||||
pstate->p_rtable,
|
||||
true);
|
||||
|
||||
/*
|
||||
* Check the targetlist and HAVING clause for ungrouped variables.
|
||||
*/
|
||||
check_ungrouped_columns((Node *) qry->targetList, pstate, groupClauses);
|
||||
check_ungrouped_columns((Node *) qry->havingQual, pstate, groupClauses);
|
||||
clause = (Node *) qry->targetList;
|
||||
if (hasJoinRTEs)
|
||||
clause = flatten_join_alias_vars(clause, pstate->p_rtable, true);
|
||||
check_ungrouped_columns(clause, pstate, groupClauses);
|
||||
|
||||
/* Release the list storage (but not the pointed-to expressions!) */
|
||||
freeList(groupClauses);
|
||||
clause = (Node *) qry->havingQual;
|
||||
if (hasJoinRTEs)
|
||||
clause = flatten_join_alias_vars(clause, pstate->p_rtable, true);
|
||||
check_ungrouped_columns(clause, pstate, groupClauses);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user