Aggregate functions didn't work on subscripted array references.

Things are better now.
This commit is contained in:
Tom Lane 1999-04-29 01:13:13 +00:00
parent 970583ab4f
commit fd31563777
2 changed files with 24 additions and 69 deletions

View File

@ -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

View File

@ -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)))
{ {