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

Commitb4210ae

Browse files
committed
Fix problems with grouping/aggregation in queries that use
inheritance ... basically it was completely busted :-(
1 parent08abe0a commitb4210ae

File tree

5 files changed

+87
-131
lines changed

5 files changed

+87
-131
lines changed

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

Lines changed: 27 additions & 5 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.54 1999/05/25 16:09:37 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.55 1999/06/06 17:38:10 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -122,14 +122,36 @@ union_planner(Query *parse)
122122
}
123123
elseif ((rt_index=first_inherit_rt_entry(rangetable))!=-1)
124124
{
125-
if (parse->rowMark!=NULL)
126-
elog(ERROR,"SELECT FOR UPDATE is not supported for inherit queries");
127-
result_plan= (Plan*)plan_inherit_queries(parse,rt_index);
128-
/* XXX do we need to do this? bjm 12/19/97 */
125+
List*sub_tlist;
126+
127+
/*
128+
* Generate appropriate target list for subplan; may be different
129+
* from tlist if grouping or aggregation is needed.
130+
*/
131+
sub_tlist=make_subplanTargetList(parse,tlist,&groupColIdx);
132+
133+
/*
134+
* Recursively plan the subqueries needed for inheritance
135+
*/
136+
result_plan= (Plan*)plan_inherit_queries(parse,sub_tlist,
137+
rt_index);
138+
139+
/*
140+
* Fix up outer target list. NOTE: unlike the case for non-inherited
141+
* query, we pass the unfixed tlist to subplans, which do their own
142+
* fixing. But we still want to fix the outer target list afterwards.
143+
* I *think* this is correct --- doing the fix before recursing is
144+
* definitely wrong, because preprocess_targetlist() will do the
145+
* wrong thing if invoked twice on the same list. Maybe that is a bug?
146+
* tgl 6/6/99
147+
*/
129148
tlist=preprocess_targetlist(tlist,
130149
parse->commandType,
131150
parse->resultRelation,
132151
parse->rtable);
152+
153+
if (parse->rowMark!=NULL)
154+
elog(ERROR,"SELECT FOR UPDATE is not supported for inherit queries");
133155
}
134156
else
135157
{

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

Lines changed: 1 addition & 90 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/setrefs.c,v 1.49 1999/05/26 12:55:28 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.50 1999/06/06 17:38:10 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -45,7 +45,6 @@ static Var *replace_joinvar_refs(Var *var,
4545
staticList*tlist_noname_references(Oidnonameid,List*tlist);
4646
staticboolOperandIsInner(Node*opnd,intinner_relid);
4747
staticList*pull_agg_clause(Node*clause);
48-
staticNode*del_agg_clause(Node*clause);
4948
staticvoidset_result_tlist_references(Result*resultNode);
5049
staticvoidreplace_vars_with_subplan_refs(Node*clause,
5150
Indexsubvarno,
@@ -874,94 +873,6 @@ pull_agg_clause(Node *clause)
874873
}
875874

876875

877-
/*
878-
* del_agg_tlist_references
879-
* Remove the Agg nodes from the target list
880-
* We do this so inheritance only does aggregates in the upper node
881-
*/
882-
void
883-
del_agg_tlist_references(List*tlist)
884-
{
885-
List*tl;
886-
887-
foreach(tl,tlist)
888-
{
889-
TargetEntry*tle=lfirst(tl);
890-
891-
tle->expr=del_agg_clause(tle->expr);
892-
}
893-
}
894-
895-
staticNode*
896-
del_agg_clause(Node*clause)
897-
{
898-
List*t;
899-
900-
if (clause==NULL)
901-
returnclause;
902-
903-
if (IsA(clause,Var))
904-
returnclause;
905-
elseif (is_funcclause(clause))
906-
{
907-
908-
/*
909-
* This is a function. Recursively call this routine for its
910-
* arguments...
911-
*/
912-
foreach(t, ((Expr*)clause)->args)
913-
lfirst(t)=del_agg_clause(lfirst(t));
914-
}
915-
elseif (IsA(clause,Aggref))
916-
{
917-
918-
/* here is the real action, to remove the Agg node */
919-
returndel_agg_clause(((Aggref*)clause)->target);
920-
921-
}
922-
elseif (IsA(clause,ArrayRef))
923-
{
924-
ArrayRef*aref= (ArrayRef*)clause;
925-
926-
/*
927-
* This is an arrayref. Recursively call this routine for its
928-
* expression and its index expression...
929-
*/
930-
foreach(t,aref->refupperindexpr)
931-
lfirst(t)=del_agg_clause(lfirst(t));
932-
foreach(t,aref->reflowerindexpr)
933-
lfirst(t)=del_agg_clause(lfirst(t));
934-
aref->refexpr=del_agg_clause(aref->refexpr);
935-
aref->refassgnexpr=del_agg_clause(aref->refassgnexpr);
936-
}
937-
elseif (is_opclause(clause))
938-
{
939-
940-
/*
941-
* This is an operator. Recursively call this routine for both its
942-
* left and right operands
943-
*/
944-
Node*left= (Node*)get_leftop((Expr*)clause);
945-
Node*right= (Node*)get_rightop((Expr*)clause);
946-
947-
if (left!= (Node*)NULL)
948-
left=del_agg_clause(left);
949-
if (right!= (Node*)NULL)
950-
right=del_agg_clause(right);
951-
}
952-
elseif (IsA(clause,Param)||IsA(clause,Const))
953-
returnclause;
954-
else
955-
{
956-
957-
/*
958-
* Ooops! we can not handle that!
959-
*/
960-
elog(ERROR,"del_agg_clause: Can not handle this tlist!\n");
961-
}
962-
returnNULL;
963-
}
964-
965876
/*
966877
* check_having_for_ungrouped_vars takes the havingQual and the list of
967878
* GROUP BY clauses and checks for subplans in the havingQual that are being

‎src/backend/optimizer/prep/prepunion.c

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.31 1999/05/25 16:09:47 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.32 1999/06/06 17:38:11 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -35,7 +35,7 @@
3535
#include"optimizer/planmain.h"
3636

3737
staticList*plan_inherit_query(Relidsrelids,Indexrt_index,
38-
RangeTblEntry*rt_entry,Query*parse,
38+
RangeTblEntry*rt_entry,Query*parse,List*tlist,
3939
List**union_rtentriesPtr);
4040
staticRangeTblEntry*new_rangetable_entry(Oidnew_relid,
4141
RangeTblEntry*old_entry);
@@ -208,32 +208,46 @@ plan_union_queries(Query *parse)
208208
*
209209
* Plans the queries for a given parent relation.
210210
*
211-
* Returns a list containing a list of plans and a list of rangetable
212-
* entries to be inserted into an APPEND node.
213-
* XXX - what exactly does this mean, look for make_append
211+
* Inputs:
212+
*parse = parent parse tree
213+
*tlist = target list for inheritance subqueries (not same as parent's!)
214+
*rt_index = rangetable index for current inheritance item
215+
*
216+
* Returns an APPEND node that forms the result of performing the given
217+
* query for each member relation of the inheritance group.
218+
*
219+
* If grouping, aggregation, or sorting is specified in the parent plan,
220+
* the subplans should not do any of those steps --- we must do those
221+
* operations just once above the APPEND node. The given tlist has been
222+
* modified appropriately to remove group/aggregate expressions, but the
223+
* Query node still has the relevant fields set. We remove them in the
224+
* copies used for subplans (see plan_inherit_query).
225+
*
226+
* NOTE: this can be invoked recursively if more than one inheritance wildcard
227+
* is present. At each level of recursion, the first wildcard remaining in
228+
* the rangetable is expanded.
214229
*/
215230
Append*
216-
plan_inherit_queries(Query*parse,Indexrt_index)
231+
plan_inherit_queries(Query*parse,List*tlist,Indexrt_index)
217232
{
218-
List*union_plans=NIL;
219-
220233
List*rangetable=parse->rtable;
221234
RangeTblEntry*rt_entry=rt_fetch(rt_index,rangetable);
222235
List*inheritrtable=NIL;
223-
List*union_relids=NIL;
236+
List*union_relids;
237+
List*union_plans;
224238

225239
union_relids=find_all_inheritors(lconsi(rt_entry->relid,
226240
NIL),
227241
NIL);
228242

229243
/*
230244
* Remove the flag for this relation, since we're about to handle it
231-
* (do it before recursing!). XXX destructive parse tree change
245+
* (do it before recursing!). XXX destructivechange to parentparse tree
232246
*/
233-
rt_fetch(rt_index,rangetable)->inh= false;
247+
rt_entry->inh= false;
234248

235249
union_plans=plan_inherit_query(union_relids,rt_index,rt_entry,
236-
parse,&inheritrtable);
250+
parse,tlist,&inheritrtable);
237251

238252
return (make_append(union_plans,
239253
NULL,
@@ -252,11 +266,12 @@ plan_inherit_query(Relids relids,
252266
Indexrt_index,
253267
RangeTblEntry*rt_entry,
254268
Query*root,
269+
List*tlist,
255270
List**union_rtentriesPtr)
256271
{
257-
List*i;
258272
List*union_plans=NIL;
259273
List*union_rtentries=NIL;
274+
List*i;
260275

261276
foreach(i,relids)
262277
{
@@ -268,19 +283,21 @@ plan_inherit_query(Relids relids,
268283
new_rt_entry);
269284

270285
/*
271-
* reset the uniqueflag and sortclause in parse tree root, so that
272-
* sorting will only be done once after append
286+
* Insert the desired simplified tlist into the subquery
287+
*/
288+
new_root->targetList=copyObject(tlist);
289+
290+
/*
291+
* Clear the sorting and grouping qualifications in the subquery,
292+
* so that sorting will only be done once after append
273293
*/
274294
new_root->uniqueFlag=NULL;
275295
new_root->sortClause=NULL;
276296
new_root->groupClause=NULL;
277297
new_root->havingQual=NULL;
298+
new_root->hasAggs= false;/* shouldn't be any left ... */
278299

279-
if (new_root->hasAggs)
280-
{
281-
new_root->hasAggs= false;
282-
del_agg_tlist_references(new_root->targetList);
283-
}
300+
/* Fix attribute numbers as necessary */
284301
fix_parsetree_attnums(rt_index,
285302
rt_entry->relid,
286303
relid,
@@ -346,7 +363,7 @@ int
346363
first_inherit_rt_entry(List*rangetable)
347364
{
348365
intcount=0;
349-
List*temp=NIL;
366+
List*temp;
350367

351368
foreach(temp,rangetable)
352369
{
@@ -393,8 +410,8 @@ static Query *
393410
subst_rangetable(Query*root,Indexindex,RangeTblEntry*new_entry)
394411
{
395412
Query*new_root=copyObject(root);
396-
List*temp=NIL;
397-
inti=0;
413+
List*temp;
414+
inti;
398415

399416
for (temp=new_root->rtable,i=1;i<index;temp=lnext(temp),i++)
400417
;
@@ -403,6 +420,15 @@ subst_rangetable(Query *root, Index index, RangeTblEntry *new_entry)
403420
returnnew_root;
404421
}
405422

423+
/*
424+
* Adjust varnos for child tables. This routine makes it possible for
425+
* child tables to have different column positions for the "same" attribute
426+
* as a parent, which helps ALTER TABLE ADD COLUMN. Unfortunately this isn't
427+
* nearly enough to make it work transparently; there are other places where
428+
* things fall down if children and parents don't have the same column numbers
429+
* for inherited attributes. It'd be better to rip this code out and fix
430+
* ALTER TABLE...
431+
*/
406432
staticvoid
407433
fix_parsetree_attnums_nodes(Indexrt_index,
408434
Oidold_relid,
@@ -433,16 +459,11 @@ fix_parsetree_attnums_nodes(Index rt_index,
433459
caseT_Var:
434460
{
435461
Var*var= (Var*)node;
436-
Oidold_typeid,
437-
new_typeid;
438-
439-
old_typeid=old_relid;
440-
new_typeid=new_relid;
441462

442463
if (var->varno==rt_index&&var->varattno!=0)
443464
{
444-
var->varattno=get_attnum(new_typeid,
445-
get_attname(old_typeid,var->varattno));
465+
var->varattno=get_attnum(new_relid,
466+
get_attname(old_relid,var->varattno));
446467
}
447468
}
448469
break;

‎src/include/optimizer/planmain.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: planmain.h,v 1.27 1999/05/26 12:56:36 momjian Exp $
9+
* $Id: planmain.h,v 1.28 1999/06/06 17:38:09 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -58,7 +58,6 @@ extern void replace_tlist_with_subplan_refs(List *tlist,
5858
Indexsubvarno,
5959
List*subplanTargetList);
6060
externboolset_agg_tlist_references(Agg*aggNode);
61-
externvoiddel_agg_tlist_references(List*tlist);
6261
externvoidcheck_having_for_ungrouped_vars(Node*clause,
6362
List*groupClause,
6463
List*targetList);

‎src/include/optimizer/prep.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: prep.h,v 1.14 1999/02/13 23:21:52 momjian Exp $
9+
* $Id: prep.h,v 1.15 1999/06/06 17:38:10 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -17,20 +17,23 @@
1717
#include<nodes/parsenodes.h>
1818

1919
/*
20-
* prototypes for prepqual.h
20+
* prototypes for prepqual.c
2121
*/
2222
externList*cnfify(Expr*qual,boolremoveAndFlag);
2323

2424
/*
25-
* prototypes for preptlist.h
25+
* prototypes for preptlist.c
2626
*/
2727
externList*preprocess_targetlist(List*tlist,intcommand_type,
2828
Indexresult_relation,List*range_table);
2929

30+
/*
31+
* prototypes for prepunion.c
32+
*/
3033
externList*find_all_inheritors(List*unexamined_relids,
3134
List*examined_relids);
3235
externintfirst_inherit_rt_entry(List*rangetable);
3336
externAppend*plan_union_queries(Query*parse);
34-
externAppend*plan_inherit_queries(Query*parse,Indexrt_index);
37+
externAppend*plan_inherit_queries(Query*parse,List*tlist,Indexrt_index);
3538

3639
#endif/* PREP_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp