Aggregate functions didn't work on subscripted array references.
authorTom Lane
Thu, 29 Apr 1999 01:13:13 +0000 (01:13 +0000)
committerTom Lane
Thu, 29 Apr 1999 01:13:13 +0000 (01:13 +0000)
Things are better now.

src/backend/executor/nodeAgg.c
src/backend/parser/parse_agg.c

index 82d7ffd8ce67f886916bda33dd51b7bf6ffc14d0..a3f4f12570eda05ff7149d249f66c40980e5ddda 100644 (file)
@@ -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
index a27c00c56f0baf2002567f7c23d2925cf3ce6a6e..1b2eb21c7cd0b57ce670f47a29ac6450f3fa4222 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * 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))
    {
        basetype = aggform->aggbasetype;
-       if (nodeTag(lfirst(target)) == T_Var)
-           vartype = ((Var *) lfirst(target))->vartype;
-       else
-           vartype = ((Expr *) lfirst(target))->typeOid;
-
+       vartype = exprType(lfirst(target));
        if ((basetype != vartype)
            && (! IS_BINARY_COMPATIBLE(basetype, vartype)))
        {