mirror of
https://github.com/postgres/postgres.git
synced 2025-07-20 05:03:10 +03:00
Remove Query->qry_aggs and qry_numaggs and replace with Query->hasAggs.
Pass List* of Aggregs into executor, and create needed array there. No longer need to double-processs Aggregs with second copy in Query. Fix crash when doing: select sum(x+1) from test where 1 > 0;
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.64 1998/01/11 03:41:35 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.65 1998/01/15 18:59:56 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -219,7 +219,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
|
||||
qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
|
||||
|
||||
/* make sure we don't have aggregates in the where clause */
|
||||
if (pstate->p_numAgg > 0)
|
||||
if (pstate->p_hasAggs)
|
||||
parseCheckAggregates(pstate, qry);
|
||||
|
||||
return (Query *) qry;
|
||||
@ -334,7 +334,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
|
||||
qry->targetList,
|
||||
qry->uniqueFlag);
|
||||
|
||||
if (pstate->p_numAgg > 0)
|
||||
if (pstate->p_hasAggs)
|
||||
finalizeAggregates(pstate, qry);
|
||||
|
||||
qry->unionall = stmt->unionall; /* in child, so unionClause may be false */
|
||||
@ -796,8 +796,7 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
|
||||
|
||||
pstate->p_last_resno = 1;
|
||||
pstate->p_is_rule = true; /* for expand all */
|
||||
pstate->p_numAgg = 0;
|
||||
pstate->p_aggs = NULL;
|
||||
pstate->p_hasAggs = false;
|
||||
|
||||
lfirst(actions) = transformStmt(pstate, lfirst(actions));
|
||||
actions = lnext(actions);
|
||||
@ -853,7 +852,7 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
qry->targetList);
|
||||
qry->rtable = pstate->p_rtable;
|
||||
|
||||
if (pstate->p_numAgg > 0)
|
||||
if (pstate->p_hasAggs)
|
||||
finalizeAggregates(pstate, qry);
|
||||
|
||||
qry->unionall = stmt->unionall; /* in child, so unionClause may be false */
|
||||
@ -890,11 +889,11 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
|
||||
qry->rtable = pstate->p_rtable;
|
||||
qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
|
||||
|
||||
if (pstate->p_numAgg > 0)
|
||||
if (pstate->p_hasAggs)
|
||||
finalizeAggregates(pstate, qry);
|
||||
|
||||
/* make sure we don't have aggregates in the where clause */
|
||||
if (pstate->p_numAgg > 0)
|
||||
if (pstate->p_hasAggs)
|
||||
parseCheckAggregates(pstate, qry);
|
||||
|
||||
return (Query *) qry;
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.6 1998/01/05 03:32:25 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.7 1998/01/15 18:59:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -34,64 +34,17 @@ static bool contain_agg_clause(Node *clause);
|
||||
static bool exprIsAggOrGroupCol(Node *expr, List *groupClause);
|
||||
static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause);
|
||||
|
||||
/*
|
||||
* AddAggToParseState -
|
||||
* add the aggregate to the list of unique aggregates in pstate.
|
||||
*
|
||||
* SIDE EFFECT: aggno in target list entry will be modified
|
||||
*/
|
||||
void
|
||||
AddAggToParseState(ParseState *pstate, Aggreg *aggreg)
|
||||
{
|
||||
List *ag;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* see if we have the aggregate already (we only need to record the
|
||||
* aggregate once)
|
||||
*/
|
||||
i = 0;
|
||||
foreach(ag, pstate->p_aggs)
|
||||
{
|
||||
Aggreg *a = lfirst(ag);
|
||||
|
||||
if (!strcmp(a->aggname, aggreg->aggname) &&
|
||||
equal(a->target, aggreg->target))
|
||||
{
|
||||
|
||||
/* fill in the aggno and we're done */
|
||||
aggreg->aggno = i;
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
/* not found, new aggregate */
|
||||
aggreg->aggno = i;
|
||||
pstate->p_numAgg++;
|
||||
pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* finalizeAggregates -
|
||||
* fill in qry_aggs from pstate. Also checks to make sure that aggregates
|
||||
* fill in hasAggs from pstate. Also checks to make sure that aggregates
|
||||
* are used in the proper place.
|
||||
*/
|
||||
void
|
||||
finalizeAggregates(ParseState *pstate, Query *qry)
|
||||
{
|
||||
List *l;
|
||||
int i;
|
||||
|
||||
parseCheckAggregates(pstate, qry);
|
||||
|
||||
qry->qry_numAgg = pstate->p_numAgg;
|
||||
qry->qry_aggs =
|
||||
(Aggreg **) palloc(sizeof(Aggreg *) * qry->qry_numAgg);
|
||||
i = 0;
|
||||
foreach(l, pstate->p_aggs)
|
||||
qry->qry_aggs[i++] = (Aggreg *) lfirst(l);
|
||||
qry->hasAggs = pstate->p_hasAggs;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -240,7 +193,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
|
||||
{
|
||||
List *tl;
|
||||
|
||||
Assert(pstate->p_numAgg > 0);
|
||||
Assert(pstate->p_hasAggs);
|
||||
|
||||
/*
|
||||
* aggregates never appear in WHERE clauses. (we have to check where
|
||||
@ -393,6 +346,8 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
|
||||
if (usenulls)
|
||||
aggreg->usenulls = true;
|
||||
|
||||
pstate->p_hasAggs = true;
|
||||
|
||||
return aggreg;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.5 1998/01/05 03:32:28 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.6 1998/01/15 19:00:02 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -221,13 +221,8 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs,
|
||||
PointerGetDatum(funcname),
|
||||
ObjectIdGetDatum(basetype),
|
||||
0, 0))
|
||||
{
|
||||
Aggreg *aggreg = ParseAgg(pstate, funcname, basetype,
|
||||
return (Node *)ParseAgg(pstate, funcname, basetype,
|
||||
fargs, precedence);
|
||||
|
||||
AddAggToParseState(pstate, aggreg);
|
||||
return (Node *) aggreg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.5 1998/01/05 03:32:29 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.6 1998/01/15 19:00:04 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -49,8 +49,7 @@ make_parsestate(void)
|
||||
pstate = palloc(sizeof(ParseState));
|
||||
pstate->p_last_resno = 1;
|
||||
pstate->p_rtable = NIL;
|
||||
pstate->p_numAgg = 0;
|
||||
pstate->p_aggs = NIL;
|
||||
pstate->p_hasAggs = false;
|
||||
pstate->p_is_insert = false;
|
||||
pstate->p_insert_columns = NIL;
|
||||
pstate->p_is_update = false;
|
||||
|
Reference in New Issue
Block a user