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

Commita8ae19e

Browse files
committed
aggregate(DISTINCT ...) works, per SQL spec.
Note this forces initdb because of change of Aggref node in stored rules.
1 parentefb36d2 commita8ae19e

File tree

16 files changed

+765
-263
lines changed

16 files changed

+765
-263
lines changed

‎src/backend/executor/nodeAgg.c

Lines changed: 364 additions & 198 deletions
Large diffs are not rendered by default.

‎src/backend/nodes/copyfuncs.c

Lines changed: 3 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/nodes/copyfuncs.c,v 1.97 1999/11/23 20:06:52 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.98 1999/12/13 01:26:53 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -832,6 +832,8 @@ _copyAggref(Aggref *from)
832832
newnode->aggtype=from->aggtype;
833833
Node_Copy(from,newnode,target);
834834
newnode->usenulls=from->usenulls;
835+
newnode->aggstar=from->aggstar;
836+
newnode->aggdistinct=from->aggdistinct;
835837
newnode->aggno=from->aggno;/* probably not needed */
836838

837839
returnnewnode;

‎src/backend/nodes/equalfuncs.c

Lines changed: 5 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/nodes/equalfuncs.c,v 1.52 1999/11/23 20:06:52 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.53 1999/12/13 01:26:53 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -219,6 +219,10 @@ _equalAggref(Aggref *a, Aggref *b)
219219
return false;
220220
if (a->usenulls!=b->usenulls)
221221
return false;
222+
if (a->aggstar!=b->aggstar)
223+
return false;
224+
if (a->aggdistinct!=b->aggdistinct)
225+
return false;
222226
/* ignore aggno, which is only a private field for the executor */
223227
return true;
224228
}

‎src/backend/nodes/outfuncs.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
*$Id: outfuncs.c,v 1.99 1999/12/10 07:37:31 tgl Exp $
8+
*$Id: outfuncs.c,v 1.100 1999/12/13 01:26:53 tgl Exp $
99
*
1010
* NOTES
1111
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -680,14 +680,17 @@ static void
680680
_outAggref(StringInfostr,Aggref*node)
681681
{
682682
appendStringInfo(str,
683-
" AGGREG :aggname %s :basetype %u :aggtype %u :target ",
683+
" AGGREG :aggname %s :basetype %u :aggtype %u :target ",
684684
stringStringInfo(node->aggname),
685685
node->basetype,
686686
node->aggtype);
687687
_outNode(str,node->target);
688688

689-
appendStringInfo(str," :usenulls %s ",
690-
node->usenulls ?"true" :"false");
689+
appendStringInfo(str," :usenulls %s :aggstar %s :aggdistinct %s ",
690+
node->usenulls ?"true" :"false",
691+
node->aggstar ?"true" :"false",
692+
node->aggdistinct ?"true" :"false");
693+
/* aggno is not dumped */
691694
}
692695

693696
/*

‎src/backend/nodes/readfuncs.c

Lines changed: 9 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/nodes/readfuncs.c,v 1.75 1999/11/23 20:06:53 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.76 1999/12/13 01:26:54 tgl Exp $
1111
*
1212
* NOTES
1313
* Most of the read functions for plan nodes are tested. (In fact, they
@@ -1190,6 +1190,14 @@ _readAggref()
11901190
token=lsptok(NULL,&length);/* get usenulls */
11911191
local_node->usenulls= (token[0]=='t') ? true : false;
11921192

1193+
token=lsptok(NULL,&length);/* eat :aggstar */
1194+
token=lsptok(NULL,&length);/* get aggstar */
1195+
local_node->aggstar= (token[0]=='t') ? true : false;
1196+
1197+
token=lsptok(NULL,&length);/* eat :aggdistinct */
1198+
token=lsptok(NULL,&length);/* get aggdistinct */
1199+
local_node->aggdistinct= (token[0]=='t') ? true : false;
1200+
11931201
returnlocal_node;
11941202
}
11951203

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

Lines changed: 35 additions & 3 deletions
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.56 1999/12/09 05:58:53 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.57 1999/12/13 01:26:55 tgl Exp $
1111
*
1212
* HISTORY
1313
* AUTHORDATEMAJOR EVENT
@@ -45,6 +45,7 @@ typedef struct {
4545
List*targetList;
4646
}check_subplans_for_ungrouped_vars_context;
4747

48+
staticboolcontain_agg_clause_walker(Node*node,void*context);
4849
staticboolpull_agg_clause_walker(Node*node,List**listptr);
4950
staticboolcheck_subplans_for_ungrouped_vars_walker(Node*node,
5051
check_subplans_for_ungrouped_vars_context*context);
@@ -393,12 +394,36 @@ pull_constant_clauses(List *quals, List **constantQual)
393394
returnrestqual;
394395
}
395396

397+
/*
398+
* contain_agg_clause
399+
* Recursively search for Aggref nodes within a clause.
400+
*
401+
* Returns true if any aggregate found.
402+
*/
403+
bool
404+
contain_agg_clause(Node*clause)
405+
{
406+
returncontain_agg_clause_walker(clause,NULL);
407+
}
408+
409+
staticbool
410+
contain_agg_clause_walker(Node*node,void*context)
411+
{
412+
if (node==NULL)
413+
return false;
414+
if (IsA(node,Aggref))
415+
return true;/* abort the tree traversal and return true */
416+
returnexpression_tree_walker(node,contain_agg_clause_walker,context);
417+
}
418+
396419
/*
397420
* pull_agg_clause
398421
* Recursively pulls all Aggref nodes from an expression tree.
399422
*
400423
* Returns list of Aggref nodes found. Note the nodes themselves are not
401424
* copied, only referenced.
425+
*
426+
* Note: this also checks for nested aggregates, which are an error.
402427
*/
403428
List*
404429
pull_agg_clause(Node*clause)
@@ -417,9 +442,16 @@ pull_agg_clause_walker(Node *node, List **listptr)
417442
if (IsA(node,Aggref))
418443
{
419444
*listptr=lappend(*listptr,node);
420-
/* continue, to iterate over agg's arg as well (do nested aggregates
421-
* actually work?)
445+
/*
446+
* Complain if the aggregate's argument contains any aggregates;
447+
* nested agg functions are semantically nonsensical.
448+
*/
449+
if (contain_agg_clause(((Aggref*)node)->target))
450+
elog(ERROR,"Aggregate function calls may not be nested");
451+
/*
452+
* Having checked that, we need not recurse into the argument.
422453
*/
454+
return false;
423455
}
424456
returnexpression_tree_walker(node,pull_agg_clause_walker,
425457
(void*)listptr);

‎src/backend/parser/parse_agg.c

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.31 1999/12/10 07:37:35 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.32 1999/12/13 01:26:58 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -28,38 +28,11 @@ typedef struct {
2828
List*groupClauses;
2929
}check_ungrouped_columns_context;
3030

31-
staticboolcontain_agg_clause(Node*clause);
32-
staticboolcontain_agg_clause_walker(Node*node,void*context);
3331
staticvoidcheck_ungrouped_columns(Node*node,ParseState*pstate,
3432
List*groupClauses);
3533
staticboolcheck_ungrouped_columns_walker(Node*node,
3634
check_ungrouped_columns_context*context);
3735

38-
/*
39-
* contain_agg_clause
40-
* Recursively find aggref nodes within a clause.
41-
*
42-
* Returns true if any aggregate found.
43-
*
44-
* NOTE: we assume that the given clause has been transformed suitably for
45-
* parser output. This means we can use the planner's expression_tree_walker.
46-
*/
47-
staticbool
48-
contain_agg_clause(Node*clause)
49-
{
50-
returncontain_agg_clause_walker(clause,NULL);
51-
}
52-
53-
staticbool
54-
contain_agg_clause_walker(Node*node,void*context)
55-
{
56-
if (node==NULL)
57-
return false;
58-
if (IsA(node,Aggref))
59-
return true;/* abort the tree traversal and return true */
60-
returnexpression_tree_walker(node,contain_agg_clause_walker,context);
61-
}
62-
6336
/*
6437
* check_ungrouped_columns -
6538
* Scan the given expression tree for ungrouped variables (variables
@@ -232,7 +205,8 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
232205
* Since "1" never evaluates as null, we currently have no need of
233206
* the "usenulls" flag, but it should be kept around; in fact, we should
234207
* extend the pg_aggregate table to let usenulls be specified as an
235-
* attribute of user-defined aggregates.
208+
* attribute of user-defined aggregates. In the meantime, usenulls
209+
* is just always set to "false".
236210
*/
237211

238212
aggform= (Form_pg_aggregate)GETSTRUCT(theAggTuple);
@@ -264,14 +238,8 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
264238
aggref->aggtype=fintype;
265239
aggref->target=lfirst(args);
266240
aggref->usenulls=usenulls;
267-
268-
/*
269-
* We should store agg_star and agg_distinct into the Aggref node,
270-
* and let downstream processing deal with them. Currently, agg_star
271-
* is ignored and agg_distinct is not implemented...
272-
*/
273-
if (agg_distinct)
274-
elog(ERROR,"aggregate(DISTINCT ...) is not implemented yet");
241+
aggref->aggstar=agg_star;
242+
aggref->aggdistinct=agg_distinct;
275243

276244
pstate->p_hasAggs= true;
277245

‎src/backend/utils/adt/ruleutils.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* out of it's tuple
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.34 1999/12/06 02:37:17 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.35 1999/12/13 01:27:01 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -1352,9 +1352,13 @@ get_rule_expr(Node *node, deparse_context *context)
13521352
{
13531353
Aggref*aggref= (Aggref*)node;
13541354

1355-
appendStringInfo(buf,"%s(",
1356-
quote_identifier(aggref->aggname));
1357-
get_rule_expr(aggref->target,context);
1355+
appendStringInfo(buf,"%s(%s",
1356+
quote_identifier(aggref->aggname),
1357+
aggref->aggdistinct ?"DISTINCT " :"");
1358+
if (aggref->aggstar)
1359+
appendStringInfo(buf,"*");
1360+
else
1361+
get_rule_expr(aggref->target,context);
13581362
appendStringInfo(buf,")");
13591363
}
13601364
break;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp