Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf0a9e64

Browse files
committed
As someone asked for this feature - patch for 1.09 follows.
Now You can do queries likeselect sum(some_func(x)) from ...select min(table1.x + table2.y) from table1, table2 where ...and so on.Vadim
1 parent8735272 commitf0a9e64

File tree

3 files changed

+52
-14
lines changed

3 files changed

+52
-14
lines changed

‎src/backend/executor/nodeAgg.c

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -259,16 +259,33 @@ ExecAgg(Agg *node)
259259
DatumnewVal;
260260
AggFuncInfo*aggfns=&aggFuncInfo[i];
261261
Datumargs[2];
262-
263-
newVal=aggGetAttr(outerslot,
262+
Node*tagnode;
263+
264+
switch(nodeTag(aggregates[i]->target))
265+
{
266+
caseT_Var:
267+
tagnode=NULL;
268+
newVal=aggGetAttr(outerslot,
264269
aggregates[i],
265270
&isNull);
271+
break;
272+
caseT_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+
}
266281

267282
if (isNull)
268283
continue;/* ignore this tuple for this agg */
269284

270285
if (aggfns->xfn1) {
271286
if (noInitValue[i]) {
287+
intbyVal;
288+
272289
/*
273290
* value1 and value2 has not been initialized. This
274291
* is the first non-NULL value. We use it as the
@@ -278,17 +295,32 @@ ExecAgg(Agg *node)
278295
to make a copy of it since the tuple from which
279296
it came will be freed on the next iteration
280297
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+
FunctionCachePtrfcache_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+
}
283315
if (attlen==-1) {
284-
/* variable length */
316+
/* variable length */
285317
attlen=VARSIZE((structvarlena*)newVal);
286318
}
287319
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);
292324
/* value1[i] = newVal; */
293325
noInitValue[i]=0;
294326
nulls[i]=0;

‎src/backend/optimizer/util/clauses.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.4 1996/11/06 09:29:22 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.5 1996/11/30 17:48:52 momjian Exp $
1111
*
1212
* HISTORY
1313
* AUTHORDATEMAJOR EVENT
@@ -521,6 +521,9 @@ fix_opid(Node *clause)
521521
fix_opid((Node*)get_leftop((Expr*)clause));
522522
fix_opid((Node*)get_rightop((Expr*)clause));
523523
}
524+
elseif (agg_clause (clause)) {
525+
fix_opid (((Aggreg*)clause)->target);
526+
}
524527

525528
}
526529

‎src/backend/parser/parser.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*
88
* IDENTIFICATION
9-
* $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.12 1996/11/25 03:03:48 momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.13 1996/11/30 17:49:02 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -434,13 +434,16 @@ ParseAgg(char *aggname, Oid basetype, Node *target)
434434
fintype=aggform->aggfinaltype;
435435
xfn1=aggform->aggtransfn1;
436436

437-
if (nodeTag(target)!=T_Var)
438-
elog(WARN,"parser: aggregate can only be applied on an attribute");
437+
if (nodeTag(target)!=T_Var&&nodeTag(target)!=T_Expr)
438+
elog(WARN,"parser: aggregate can only be applied on an attribute or expression");
439439

440440
/* only aggregates with transfn1 need a base type */
441441
if (OidIsValid(xfn1)) {
442442
basetype=aggform->aggbasetype;
443-
vartype= ((Var*)target)->vartype;
443+
if (nodeTag(target)==T_Var)
444+
vartype= ((Var*)target)->vartype;
445+
else
446+
vartype= ((Expr*)target)->typeOid;
444447

445448
if (basetype!=vartype) {
446449
Typetp1,tp2,get_id_type();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp