Aggregate functions didn't work on subscripted array references.
Things are better now.
This commit is contained in:
parent
970583ab4f
commit
fd31563777
|
@ -275,34 +275,21 @@ ExecAgg(Agg *node)
|
||||||
foreach(alist, node->aggs)
|
foreach(alist, node->aggs)
|
||||||
{
|
{
|
||||||
Aggref *aggref = lfirst(alist);
|
Aggref *aggref = lfirst(alist);
|
||||||
AttrNumber attnum;
|
|
||||||
Datum newVal = (Datum) NULL;
|
|
||||||
AggFuncInfo *aggfns = &aggFuncInfo[++aggno];
|
AggFuncInfo *aggfns = &aggFuncInfo[++aggno];
|
||||||
|
Datum newVal;
|
||||||
Datum args[2];
|
Datum args[2];
|
||||||
Node *tagnode = NULL;
|
|
||||||
|
|
||||||
switch (nodeTag(aggref->target))
|
/* Do we really need the special case for Var here? */
|
||||||
|
if (IsA(aggref->target, Var))
|
||||||
{
|
{
|
||||||
case T_Var:
|
newVal = aggGetAttr(outerslot, aggref,
|
||||||
tagnode = NULL;
|
&isNull);
|
||||||
newVal = aggGetAttr(outerslot,
|
}
|
||||||
aggref,
|
else
|
||||||
&isNull);
|
{
|
||||||
break;
|
econtext->ecxt_scantuple = outerslot;
|
||||||
case T_Expr:
|
newVal = ExecEvalExpr(aggref->target, econtext,
|
||||||
tagnode = ((Expr *) aggref->target)->oper;
|
&isNull, &isDone);
|
||||||
econtext->ecxt_scantuple = outerslot;
|
|
||||||
newVal = ExecEvalExpr(aggref->target, econtext,
|
|
||||||
&isNull, &isDone);
|
|
||||||
break;
|
|
||||||
case T_Const:
|
|
||||||
tagnode = NULL;
|
|
||||||
econtext->ecxt_scantuple = outerslot;
|
|
||||||
newVal = ExecEvalExpr(aggref->target, econtext,
|
|
||||||
&isNull, &isDone);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", aggno);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNull && !aggref->usenulls)
|
if (isNull && !aggref->usenulls)
|
||||||
|
@ -312,50 +299,22 @@ ExecAgg(Agg *node)
|
||||||
{
|
{
|
||||||
if (noInitValue[aggno])
|
if (noInitValue[aggno])
|
||||||
{
|
{
|
||||||
int attlen = 0;
|
|
||||||
int byVal = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* value1 and value2 has not been initialized.
|
* value1 has not been initialized.
|
||||||
* This is the first non-NULL value. We use it as
|
* This is the first non-NULL input value.
|
||||||
* the initial value.
|
* We use it as the initial value for value1.
|
||||||
*/
|
*
|
||||||
|
* But we can't just use it straight, we have to
|
||||||
/*
|
|
||||||
* but we can't just use it straight, we have to
|
|
||||||
* make a copy of it since the tuple from which it
|
* make a copy of it since the tuple from which it
|
||||||
* came will be freed on the next iteration of the
|
* came will be freed on the next iteration of the
|
||||||
* scan
|
* scan. This requires finding out how to copy
|
||||||
|
* the Datum. We assume the datum is of the agg's
|
||||||
|
* basetype, or at least binary compatible with it.
|
||||||
*/
|
*/
|
||||||
switch (nodeTag(aggref->target))
|
Type aggBaseType = typeidType(aggref->basetype);
|
||||||
{
|
int attlen = typeLen(aggBaseType);
|
||||||
case T_Var:
|
bool byVal = typeByVal(aggBaseType);
|
||||||
attnum = ((Var *) aggref->target)->varattno;
|
|
||||||
attlen = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attlen;
|
|
||||||
byVal = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attbyval;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case T_Expr:
|
|
||||||
{
|
|
||||||
FunctionCachePtr fcache_ptr;
|
|
||||||
|
|
||||||
if (nodeTag(tagnode) == T_Func)
|
|
||||||
fcache_ptr = ((Func *) tagnode)->func_fcache;
|
|
||||||
else
|
|
||||||
fcache_ptr = ((Oper *) tagnode)->op_fcache;
|
|
||||||
attlen = fcache_ptr->typlen;
|
|
||||||
byVal = fcache_ptr->typbyval;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
case T_Const:
|
|
||||||
attlen = ((Const *) aggref->target)->constlen;
|
|
||||||
byVal = ((Const *) aggref->target)->constbyval;
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", aggno);
|
|
||||||
}
|
|
||||||
if (byVal)
|
if (byVal)
|
||||||
value1[aggno] = newVal;
|
value1[aggno] = newVal;
|
||||||
else
|
else
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.17 1999/02/13 23:17:06 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.18 1999/04/29 01:13:13 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -305,11 +305,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
|
||||||
if (OidIsValid(xfn1))
|
if (OidIsValid(xfn1))
|
||||||
{
|
{
|
||||||
basetype = aggform->aggbasetype;
|
basetype = aggform->aggbasetype;
|
||||||
if (nodeTag(lfirst(target)) == T_Var)
|
vartype = exprType(lfirst(target));
|
||||||
vartype = ((Var *) lfirst(target))->vartype;
|
|
||||||
else
|
|
||||||
vartype = ((Expr *) lfirst(target))->typeOid;
|
|
||||||
|
|
||||||
if ((basetype != vartype)
|
if ((basetype != vartype)
|
||||||
&& (! IS_BINARY_COMPATIBLE(basetype, vartype)))
|
&& (! IS_BINARY_COMPATIBLE(basetype, vartype)))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue