OSDN Git Service

Aggregate functions didn't work on subscripted array references.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 29 Apr 1999 01:13:13 +0000 (01:13 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
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 82d7ffd..a3f4f12 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 a27c00c..1b2eb21 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)))
                {