@@ -259,16 +259,33 @@ ExecAgg(Agg *node)
259
259
Datum newVal ;
260
260
AggFuncInfo * aggfns = & aggFuncInfo [i ];
261
261
Datum args [2 ];
262
-
263
- newVal = aggGetAttr (outerslot ,
262
+ Node * tagnode ;
263
+
264
+ switch (nodeTag (aggregates [i ]-> target ))
265
+ {
266
+ case T_Var :
267
+ tagnode = NULL ;
268
+ newVal = aggGetAttr (outerslot ,
264
269
aggregates [i ],
265
270
& isNull );
271
+ break ;
272
+ case T_Expr :
273
+ tagnode = ((Expr * )aggregates [i ]-> target )-> oper ;
274
+ econtext -> ecxt_scantuple = outerslot ;
275
+ newVal = ExecEvalExpr (aggregates [i ]-> target , econtext ,
276
+ & isNull , NULL );
277
+ break ;
278
+ default :
279
+ elog (WARN , "ExecAgg: Bad Agg->Target for Agg %d" , i );
280
+ }
266
281
267
282
if (isNull )
268
283
continue ; /* ignore this tuple for this agg */
269
284
270
285
if (aggfns -> xfn1 ) {
271
286
if (noInitValue [i ]) {
287
+ int byVal ;
288
+
272
289
/*
273
290
* value1 and value2 has not been initialized. This
274
291
* is the first non-NULL value. We use it as the
@@ -278,17 +295,32 @@ ExecAgg(Agg *node)
278
295
to make a copy of it since the tuple from which
279
296
it came will be freed on the next iteration
280
297
of the scan */
281
- attnum = ((Var * )aggregates [i ]-> target )-> varattno ;
282
- attlen = outerslot -> ttc_tupleDescriptor -> attrs [attnum - 1 ]-> attlen ;
298
+ if ( tagnode != NULL )
299
+ {
300
+ FunctionCachePtr fcache_ptr ;
301
+
302
+ if ( nodeTag (tagnode ) == T_Func )
303
+ fcache_ptr = ((Func * )tagnode )-> func_fcache ;
304
+ else
305
+ fcache_ptr = ((Oper * )tagnode )-> op_fcache ;
306
+ attlen = fcache_ptr -> typlen ;
307
+ byVal = fcache_ptr -> typbyval ;
308
+ }
309
+ else
310
+ {
311
+ attnum = ((Var * )aggregates [i ]-> target )-> varattno ;
312
+ attlen = outerslot -> ttc_tupleDescriptor -> attrs [attnum - 1 ]-> attlen ;
313
+ byVal = outerslot -> ttc_tupleDescriptor -> attrs [attnum - 1 ]-> attbyval ;
314
+ }
283
315
if (attlen == -1 ) {
284
- /* variable length */
316
+ /* variable length */
285
317
attlen = VARSIZE ((struct varlena * ) newVal );
286
318
}
287
319
value1 [i ] = (Datum )palloc (attlen );
288
- if (outerslot -> ttc_tupleDescriptor -> attrs [ attnum - 1 ] -> attbyval )
289
- value1 [i ] = newVal ;
290
- else
291
- memmove ((char * ) (value1 [i ]), (char * ) ( newVal ) , attlen );
320
+ if ( byVal )
321
+ value1 [i ] = newVal ;
322
+ else
323
+ memmove ((char * )(value1 [i ]), (char * )newVal , attlen );
292
324
/* value1[i] = newVal; */
293
325
noInitValue [i ] = 0 ;
294
326
nulls [i ] = 0 ;
0 commit comments