mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08: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:
parent
cdbd298b3a
commit
906dce0464
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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/clauses.h"
|
||||||
#include "optimizer/tlist.h"
|
#include "optimizer/tlist.h"
|
||||||
|
#include "optimizer/var.h"
|
||||||
#include "parser/parse_agg.h"
|
#include "parser/parse_agg.h"
|
||||||
#include "parser/parsetree.h"
|
#include "parser/parsetree.h"
|
||||||
|
|
||||||
@ -179,7 +180,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
|
|||||||
{
|
{
|
||||||
List *groupClauses = NIL;
|
List *groupClauses = NIL;
|
||||||
bool have_non_var_grouping = false;
|
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 */
|
/* This should only be called if we found aggregates, GROUP, or HAVING */
|
||||||
Assert(pstate->p_hasAggs || qry->groupClause || qry->havingQual);
|
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...).
|
* repeated scans of the targetlist within the recursive routine...).
|
||||||
* And detect whether any of the expressions aren't simple Vars.
|
* 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;
|
Node *expr;
|
||||||
|
|
||||||
expr = get_sortgroupclause_expr(grpcl, qry->targetList);
|
expr = get_sortgroupclause_expr(grpcl, qry->targetList);
|
||||||
@ -220,14 +223,40 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
|
|||||||
have_non_var_grouping = true;
|
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 the targetlist and HAVING clause for ungrouped variables.
|
||||||
*/
|
*/
|
||||||
check_ungrouped_columns((Node *) qry->targetList, pstate,
|
clause = (Node *) qry->targetList;
|
||||||
groupClauses, have_non_var_grouping);
|
if (hasJoinRTEs)
|
||||||
check_ungrouped_columns((Node *) qry->havingQual, pstate,
|
clause = flatten_join_alias_vars(qry, clause);
|
||||||
|
check_ungrouped_columns(clause, pstate,
|
||||||
groupClauses, have_non_var_grouping);
|
groupClauses, have_non_var_grouping);
|
||||||
|
|
||||||
/* Release the list storage (but not the pointed-to expressions!) */
|
clause = (Node *) qry->havingQual;
|
||||||
freeList(groupClauses);
|
if (hasJoinRTEs)
|
||||||
|
clause = flatten_join_alias_vars(qry, clause);
|
||||||
|
check_ungrouped_columns(clause, pstate,
|
||||||
|
groupClauses, have_non_var_grouping);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user