@@ -275,34 +275,21 @@ ExecAgg(Agg *node)
275275foreach (alist ,node -> aggs )
276276{
277277Aggref * aggref = lfirst (alist );
278- AttrNumber attnum ;
279- Datum newVal = (Datum )NULL ;
280278AggFuncInfo * aggfns = & aggFuncInfo [++ aggno ];
279+ Datum newVal ;
281280Datum args [2 ];
282- Node * tagnode = NULL ;
283281
284- switch (nodeTag (aggref -> target ))
282+ /* Do we really need the special case for Var here? */
283+ if (IsA (aggref -> target ,Var ))
285284{
286- case T_Var :
287- tagnode = NULL ;
288- newVal = aggGetAttr (outerslot ,
289- aggref ,
290- & isNull );
291- break ;
292- case T_Expr :
293- tagnode = ((Expr * )aggref -> target )-> oper ;
294- econtext -> ecxt_scantuple = outerslot ;
295- newVal = ExecEvalExpr (aggref -> target ,econtext ,
296- & isNull ,& isDone );
297- break ;
298- case T_Const :
299- tagnode = NULL ;
300- econtext -> ecxt_scantuple = outerslot ;
301- newVal = ExecEvalExpr (aggref -> target ,econtext ,
302- & isNull ,& isDone );
303- break ;
304- default :
305- elog (ERROR ,"ExecAgg: Bad Agg->Target for Agg %d" ,aggno );
285+ newVal = aggGetAttr (outerslot ,aggref ,
286+ & isNull );
287+ }
288+ else
289+ {
290+ econtext -> ecxt_scantuple = outerslot ;
291+ newVal = ExecEvalExpr (aggref -> target ,econtext ,
292+ & isNull ,& isDone );
306293}
307294
308295if (isNull && !aggref -> usenulls )
@@ -312,50 +299,22 @@ ExecAgg(Agg *node)
312299{
313300if (noInitValue [aggno ])
314301{
315- int attlen = 0 ;
316- int byVal = 0 ;
317-
318- /*
319- * value1 and value2 has not been initialized.
320- * This is the first non-NULL value. We use it as
321- * the initial value.
322- */
323-
324302/*
325- * but we can't just use it straight, we have to
303+ * value1 has not been initialized.
304+ * This is the first non-NULL input value.
305+ * We use it as the initial value for value1.
306+ *
307+ * But we can't just use it straight, we have to
326308 * make a copy of it since the tuple from which it
327309 * came will be freed on the next iteration of the
328- * scan
310+ * scan. This requires finding out how to copy
311+ * the Datum. We assume the datum is of the agg's
312+ * basetype, or at least binary compatible with it.
329313 */
330- switch (nodeTag (aggref -> target ))
331- {
332- case T_Var :
333- attnum = ((Var * )aggref -> target )-> varattno ;
334- attlen = outerslot -> ttc_tupleDescriptor -> attrs [attnum - 1 ]-> attlen ;
335- byVal = outerslot -> ttc_tupleDescriptor -> attrs [attnum - 1 ]-> attbyval ;
336- break ;
337-
338- case T_Expr :
339- {
340- FunctionCachePtr fcache_ptr ;
341-
342- if (nodeTag (tagnode )== T_Func )
343- fcache_ptr = ((Func * )tagnode )-> func_fcache ;
344- else
345- fcache_ptr = ((Oper * )tagnode )-> op_fcache ;
346- attlen = fcache_ptr -> typlen ;
347- byVal = fcache_ptr -> typbyval ;
348- break ;
349-
350- }
351- case T_Const :
352- attlen = ((Const * )aggref -> target )-> constlen ;
353- byVal = ((Const * )aggref -> target )-> constbyval ;
354-
355- break ;
356- default :
357- elog (ERROR ,"ExecAgg: Bad Agg->Target for Agg %d" ,aggno );
358- }
314+ Type aggBaseType = typeidType (aggref -> basetype );
315+ int attlen = typeLen (aggBaseType );
316+ bool byVal = typeByVal (aggBaseType );
317+
359318if (byVal )
360319value1 [aggno ]= newVal ;
361320else