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

Commit7fd4782

Browse files
committed
Fix aggregates on inherited tables.
1 parent1783963 commit7fd4782

File tree

6 files changed

+193
-99
lines changed

6 files changed

+193
-99
lines changed

‎src/backend/optimizer/plan/planmain.c

Lines changed: 3 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.11 1997/12/18 12:54:09 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.12 1997/12/20 07:59:25 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -41,7 +41,7 @@
4141
staticPlan*subplanner(Query*root,List*flat_tlist,List*qual);
4242
staticResult*make_result(List*tlist,Node*resconstantqual,Plan*subplan);
4343

44-
staticPlan*
44+
externPlan*
4545
make_groupPlan(List**tlist,booltuplePerGroup,
4646
List*groupClause,Plan*subplan);
4747

@@ -72,7 +72,6 @@ query_planner(Query *root,
7272
List*flattened_tlist=NIL;
7373
List*level_tlist=NIL;
7474
Plan*subplan= (Plan*)NULL;
75-
Agg*aggplan=NULL;
7675

7776
/*
7877
* A command without a target list or qualification is an error,
@@ -174,49 +173,6 @@ query_planner(Query *root,
174173

175174
set_tlist_references(subplan);
176175

177-
/*
178-
* If we have a GROUP BY clause, insert a group node (with the
179-
* appropriate sort node.)
180-
*/
181-
if (root->groupClause!=NULL)
182-
{
183-
booltuplePerGroup;
184-
185-
/*
186-
* decide whether how many tuples per group the Group node needs
187-
* to return. (Needs only one tuple per group if no aggregate is
188-
* present. Otherwise, need every tuple from the group to do the
189-
* aggregation.)
190-
*/
191-
tuplePerGroup= (root->qry_aggs) ? TRUE : FALSE;
192-
193-
subplan=
194-
make_groupPlan(&tlist,tuplePerGroup,root->groupClause,subplan);
195-
196-
}
197-
198-
/*
199-
* If aggregate is present, insert the agg node
200-
*/
201-
if (root->qry_aggs)
202-
{
203-
aggplan=make_agg(tlist,root->qry_numAgg,root->qry_aggs,subplan);
204-
205-
/*
206-
* set the varno/attno entries to the appropriate references to
207-
* the result tuple of the subplans. (We need to set those in the
208-
* array of aggreg's in the Agg node also. Even though they're
209-
* pointers, after a few dozen's of copying, they're not the same
210-
* as those in the target list.)
211-
*/
212-
set_agg_tlist_references(aggplan);
213-
set_agg_agglist_references(aggplan);
214-
215-
subplan= (Plan*)aggplan;
216-
217-
tlist=aggplan->plan.targetlist;
218-
}
219-
220176
/*
221177
* Build a result node linking the plan if we have constant quals
222178
*/
@@ -236,25 +192,6 @@ query_planner(Query *root,
236192
return (plan);
237193
}
238194

239-
/*
240-
* fix up the flattened target list of the plan root node so that
241-
* expressions are evaluated. this forces expression evaluations that
242-
* may involve expensive function calls to be delayed to the very last
243-
* stage of query execution. this could be bad. but it is joey's
244-
* responsibility to optimally push these expressions down the plan
245-
* tree. -- Wei
246-
*
247-
* But now nothing to do if there are GroupBy and/or Aggregates: 1.
248-
* make_groupPlan fixes tlist; 2. flatten_tlist_vars does nothing with
249-
* aggregates fixing only other entries (i.e. - GroupBy-ed and so
250-
* fixed by make_groupPlan). - vadim 04/05/97
251-
*/
252-
if (root->groupClause==NULL&&aggplan==NULL)
253-
{
254-
subplan->targetlist=flatten_tlist_vars(tlist,
255-
subplan->targetlist);
256-
}
257-
258195
/*
259196
* Destructively modify the query plan's targetlist to add fjoin lists
260197
* to flatten functions that return sets of base types
@@ -380,7 +317,7 @@ make_result(List *tlist,
380317
*
381318
*****************************************************************************/
382319

383-
staticPlan*
320+
Plan*
384321
make_groupPlan(List**tlist,
385322
booltuplePerGroup,
386323
List*groupClause,

‎src/backend/optimizer/plan/planner.c

Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.13 1997/12/18 19:41:44 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.14 1997/12/20 07:59:27 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -47,6 +47,8 @@
4747
#include"executor/executor.h"
4848

4949
staticPlan*make_sortplan(List*tlist,List*sortcls,Plan*plannode);
50+
externPlan*make_groupPlan(List**tlist,booltuplePerGroup,
51+
List*groupClause,Plan*subplan);
5052

5153
/*****************************************************************************
5254
*
@@ -72,42 +74,110 @@ planner(Query *parse)
7274
List*rangetable=parse->rtable;
7375
char*uniqueflag=parse->uniqueFlag;
7476
List*sortclause=parse->sortClause;
75-
Plan*special_plans= (Plan*)NULL;
77+
Agg*aggplan=NULL;
7678

7779
Plan*result_plan= (Plan*)NULL;
7880

79-
List*preprocessed_tlist=NIL;
8081
List*primary_qual;
8182
intrt_index;
83+
8284

8385
/*
8486
* plan inheritance
8587
*/
8688
rt_index=first_matching_rt_entry(rangetable,INHERITS_FLAG);
8789
if (rt_index!=-1)
8890
{
89-
special_plans= (Plan*)plan_union_queries((Index)rt_index,
91+
result_plan= (Plan*)plan_union_queries((Index)rt_index,
9092
parse,
9193
INHERITS_FLAG);
94+
/* XXX do we need to do this? bjm 12/19/97 */
95+
tlist=preprocess_targetlist(tlist,
96+
parse->commandType,
97+
parse->resultRelation,
98+
parse->rtable);
9299
}
93-
94-
if (special_plans)
95-
result_plan=special_plans;
96100
else
97101
{
98-
preprocessed_tlist=preprocess_targetlist(tlist,
99-
parse->commandType,
100-
parse->resultRelation,
101-
parse->rtable);
102+
tlist=preprocess_targetlist(tlist,
103+
parse->commandType,
104+
parse->resultRelation,
105+
parse->rtable);
102106

103107
primary_qual=cnfify((Expr*)parse->qual, true);
104108

105109
result_plan=query_planner(parse,
106110
parse->commandType,
107-
preprocessed_tlist,
111+
tlist,
108112
primary_qual);
109113
}
110114

115+
/*
116+
* If we have a GROUP BY clause, insert a group node (with the
117+
* appropriate sort node.)
118+
*/
119+
if (parse->groupClause!=NULL)
120+
{
121+
booltuplePerGroup;
122+
123+
/*
124+
* decide whether how many tuples per group the Group node needs
125+
* to return. (Needs only one tuple per group if no aggregate is
126+
* present. Otherwise, need every tuple from the group to do the
127+
* aggregation.)
128+
*/
129+
tuplePerGroup= (parse->qry_aggs) ? TRUE : FALSE;
130+
131+
result_plan=
132+
make_groupPlan(&tlist,
133+
tuplePerGroup,
134+
parse->groupClause,
135+
result_plan);
136+
137+
}
138+
139+
/*
140+
* If aggregate is present, insert the agg node
141+
*/
142+
if (parse->qry_aggs)
143+
{
144+
aggplan=make_agg(tlist,
145+
parse->qry_numAgg,
146+
parse->qry_aggs,
147+
result_plan);
148+
149+
/*
150+
* set the varno/attno entries to the appropriate references to
151+
* the result tuple of the subplans. (We need to set those in the
152+
* array of aggreg's in the Agg node also. Even though they're
153+
* pointers, after a few dozen's of copying, they're not the same
154+
* as those in the target list.)
155+
*/
156+
set_agg_tlist_references(aggplan);
157+
set_agg_agglist_references(aggplan);
158+
159+
result_plan= (Plan*)aggplan;
160+
}
161+
162+
/*
163+
* fix up the flattened target list of the plan root node so that
164+
* expressions are evaluated. this forces expression evaluations that
165+
* may involve expensive function calls to be delayed to the very last
166+
* stage of query execution. this could be bad. but it is joey's
167+
* responsibility to optimally push these expressions down the plan
168+
* tree. -- Wei
169+
*
170+
* But now nothing to do if there are GroupBy and/or Aggregates: 1.
171+
* make_groupPlan fixes tlist; 2. flatten_tlist_vars does nothing with
172+
* aggregates fixing only other entries (i.e. - GroupBy-ed and so
173+
* fixed by make_groupPlan). - vadim 04/05/97
174+
*/
175+
if (parse->groupClause==NULL&&aggplan==NULL)
176+
{
177+
result_plan->targetlist=flatten_tlist_vars(tlist,
178+
result_plan->targetlist);
179+
}
180+
111181
/*
112182
* For now, before we hand back the plan, check to see if there is a
113183
* user-specified sort that needs to be done. Eventually, this will

‎src/backend/optimizer/plan/setrefs.c

Lines changed: 95 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/plan/setrefs.c,v 1.8 1997/09/08 21:45:28 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.9 1997/12/20 07:59:28 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -47,6 +47,7 @@ static List *tlist_temp_references(Oid tempid, List *tlist);
4747
staticvoidreplace_result_clause(List*clause,List*subplanTargetList);
4848
staticboolOperandIsInner(Node*opnd,intinner_relid);
4949
staticvoidreplace_agg_clause(Node*expr,List*targetlist);
50+
staticNode*del_agg_clause(Node*clause);
5051

5152
/*****************************************************************************
5253
*
@@ -803,3 +804,96 @@ replace_agg_clause(Node *clause, List *subplanTargetList)
803804
}
804805

805806
}
807+
808+
/*
809+
* del_agg_tlist_references
810+
* Remove the Agg nodes from the target list
811+
* We do this so inheritance only does aggregates in the upper node
812+
*/
813+
voiddel_agg_tlist_references(List*tlist)
814+
{
815+
List*tl;
816+
817+
foreach(tl,tlist)
818+
{
819+
TargetEntry*tle=lfirst(tl);
820+
821+
tle->expr=del_agg_clause(tle->expr);
822+
}
823+
}
824+
825+
staticNode*
826+
del_agg_clause(Node*clause)
827+
{
828+
List*t;
829+
830+
if (IsA(clause,Var))
831+
{
832+
returnclause;
833+
}
834+
elseif (is_funcclause(clause))
835+
{
836+
/*
837+
* This is a function. Recursively call this routine for its
838+
* arguments...
839+
*/
840+
foreach(t, ((Expr*)clause)->args)
841+
{
842+
lfirst(t)=del_agg_clause(lfirst(t));
843+
}
844+
}
845+
elseif (IsA(clause,Aggreg))
846+
{
847+
848+
/* here is the real action, to remove the Agg node */
849+
returndel_agg_clause(((Aggreg*)clause)->target);
850+
851+
}
852+
elseif (IsA(clause,ArrayRef))
853+
{
854+
ArrayRef*aref= (ArrayRef*)clause;
855+
856+
/*
857+
* This is an arrayref. Recursively call this routine for its
858+
* expression and its index expression...
859+
*/
860+
foreach(t,aref->refupperindexpr)
861+
{
862+
lfirst(t)=del_agg_clause(lfirst(t));
863+
}
864+
foreach(t,aref->reflowerindexpr)
865+
{
866+
lfirst(t)=del_agg_clause(lfirst(t));
867+
}
868+
aref->refexpr=del_agg_clause(aref->refexpr);
869+
aref->refassgnexpr=del_agg_clause(aref->refassgnexpr);
870+
}
871+
elseif (is_opclause(clause))
872+
{
873+
874+
/*
875+
* This is an operator. Recursively call this routine for both its
876+
* left and right operands
877+
*/
878+
Node*left= (Node*)get_leftop((Expr*)clause);
879+
Node*right= (Node*)get_rightop((Expr*)clause);
880+
881+
if (left!= (Node*)NULL)
882+
left=del_agg_clause(left);
883+
if (right!= (Node*)NULL)
884+
right=del_agg_clause(right);
885+
}
886+
elseif (IsA(clause,Param)||IsA(clause,Const))
887+
{
888+
returnclause;
889+
}
890+
else
891+
{
892+
893+
/*
894+
* Ooops! we can not handle that!
895+
*/
896+
elog(WARN,"del_agg_clause: Can not handle this tlist!\n");
897+
}
898+
returnNULL;
899+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp