aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeAgg.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>1999-04-29 01:13:13 +0000
committerTom Lane <tgl@sss.pgh.pa.us>1999-04-29 01:13:13 +0000
commitfd31563777e98882a0869223f67ff33cb61b7108 (patch)
treed7de74c9590a896246c35a624d8ea7c4d7177660 /src/backend/executor/nodeAgg.c
parent970583ab4f9818bc79ef7042eaaa791db8e92057 (diff)
downloadpostgresql-fd31563777e98882a0869223f67ff33cb61b7108.tar.gz
postgresql-fd31563777e98882a0869223f67ff33cb61b7108.zip
Aggregate functions didn't work on subscripted array references.
Things are better now.
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
-rw-r--r--src/backend/executor/nodeAgg.c87
1 files changed, 23 insertions, 64 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 82d7ffd8ce6..a3f4f12570e 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -275,34 +275,21 @@ ExecAgg(Agg *node)
foreach(alist, node->aggs)
{
Aggref *aggref = lfirst(alist);
- AttrNumber attnum;
- Datum newVal = (Datum) NULL;
AggFuncInfo *aggfns = &aggFuncInfo[++aggno];
+ Datum newVal;
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:
- tagnode = NULL;
- newVal = aggGetAttr(outerslot,
- aggref,
- &isNull);
- break;
- case T_Expr:
- tagnode = ((Expr *) aggref->target)->oper;
- 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);
+ newVal = aggGetAttr(outerslot, aggref,
+ &isNull);
+ }
+ else
+ {
+ econtext->ecxt_scantuple = outerslot;
+ newVal = ExecEvalExpr(aggref->target, econtext,
+ &isNull, &isDone);
}
if (isNull && !aggref->usenulls)
@@ -312,50 +299,22 @@ ExecAgg(Agg *node)
{
if (noInitValue[aggno])
{
- int attlen = 0;
- int byVal = 0;
-
- /*
- * value1 and value2 has not been initialized.
- * This is the first non-NULL value. We use it as
- * the initial value.
- */
-
/*
- * but we can't just use it straight, we have to
+ * value1 has not been initialized.
+ * This is the first non-NULL input value.
+ * We use it as the initial value for value1.
+ *
+ * But we can't just use it straight, we have to
* make a copy of it since the tuple from which it
* 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))
- {
- case T_Var:
- 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);
- }
+ Type aggBaseType = typeidType(aggref->basetype);
+ int attlen = typeLen(aggBaseType);
+ bool byVal = typeByVal(aggBaseType);
+
if (byVal)
value1[aggno] = newVal;
else