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

Commitfd8e580

Browse files
committed
Clean up problems with sublinks + grouping in planner. Not
sure if they are all fixed, because rewriter is now the stumbling block,but at least some cases work that did not work before.
1 parent974bdd9 commitfd8e580

File tree

3 files changed

+85
-76
lines changed

3 files changed

+85
-76
lines changed

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

Lines changed: 10 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/optimizer/plan/planner.c,v 1.56 1999/06/12 19:27:41 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.57 1999/06/21 01:20:57 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -73,10 +73,10 @@ planner(Query *parse)
7373
{
7474
Plan*result_plan;
7575

76+
/* Initialize state for subselects */
7677
PlannerQueryLevel=1;
77-
PlannerVarParam=NULL;
78-
PlannerParamVar=NULL;
7978
PlannerInitPlan=NULL;
79+
PlannerParamVar=NULL;
8080
PlannerPlanId=0;
8181

8282
transformKeySetQuery(parse);
@@ -155,7 +155,6 @@ union_planner(Query *parse)
155155
}
156156
else
157157
{
158-
List**vpm=NULL;
159158
List*sub_tlist;
160159

161160
/* Preprocess targetlist in case we are inside an INSERT/UPDATE. */
@@ -208,19 +207,10 @@ union_planner(Query *parse)
208207
sub_tlist=make_subplanTargetList(parse,tlist,&groupColIdx);
209208

210209
/* Generate the (sub) plan */
211-
if (parse->rtable!=NULL)
212-
{
213-
vpm= (List**)palloc(length(parse->rtable)*sizeof(List*));
214-
memset(vpm,0,length(parse->rtable)*sizeof(List*));
215-
}
216-
PlannerVarParam=lcons(vpm,PlannerVarParam);
217210
result_plan=query_planner(parse,
218211
parse->commandType,
219212
sub_tlist,
220213
(List*)parse->qual);
221-
PlannerVarParam=lnext(PlannerVarParam);
222-
if (vpm!=NULL)
223-
pfree(vpm);
224214
}
225215

226216
/* query_planner returns NULL if it thinks plan is bogus */
@@ -264,34 +254,21 @@ union_planner(Query *parse)
264254
*/
265255
if (parse->havingQual)
266256
{
267-
List**vpm=NULL;
268-
269-
if (parse->rtable!=NULL)
270-
{
271-
vpm= (List**)palloc(length(parse->rtable)*sizeof(List*));
272-
memset(vpm,0,length(parse->rtable)*sizeof(List*));
273-
}
274-
PlannerVarParam=lcons(vpm,PlannerVarParam);
275-
276257
/* convert the havingQual to conjunctive normal form (cnf) */
277258
parse->havingQual= (Node*)cnfify((Expr*)parse->havingQual, true);
278259

279260
if (parse->hasSubLinks)
280261
{
281-
282262
/*
283-
* Thereis a subselect in the havingQual, so we have to
263+
* Theremay be a subselect in the havingQual, so we have to
284264
* process it using the same function as for a subselect in
285265
* 'where'
286266
*/
287-
parse->havingQual=
288-
(Node*)SS_process_sublinks(parse->havingQual);
267+
parse->havingQual=SS_process_sublinks(parse->havingQual);
289268

290269
/*
291270
* Check for ungrouped variables passed to subplans. (Probably
292-
* this should be done by the parser, but right now the parser
293-
* is not smart enough to tell which level the vars belong
294-
* to?)
271+
* this should be done for the targetlist as well???)
295272
*/
296273
check_having_for_ungrouped_vars(parse->havingQual,
297274
parse->groupClause,
@@ -300,10 +277,6 @@ union_planner(Query *parse)
300277

301278
/* Calculate the opfids from the opnos */
302279
parse->havingQual= (Node*)fix_opids((List*)parse->havingQual);
303-
304-
PlannerVarParam=lnext(PlannerVarParam);
305-
if (vpm!=NULL)
306-
pfree(vpm);
307280
}
308281

309282
/*
@@ -325,10 +298,10 @@ union_planner(Query *parse)
325298

326299
/*
327300
* Check that we actually found some aggregates, else executor
328-
* will die unpleasantly. (The rewrite module currently hasbugs
329-
* thatallowhasAggs to be incorrectly set 'true' sometimes. It's
330-
* not easy to recover here, since we've already made decisions
331-
* assuming there will be an Agg node.)
301+
* will die unpleasantly. (This defends against possiblebugs in
302+
*parser or rewritethatmight causehasAggs to be incorrectly
303+
*set 'true'. It'snot easy to recover here, since we've already
304+
*made decisionsassuming there will be an Agg node.)
332305
*/
333306
if (((Agg*)result_plan)->aggs==NIL)
334307
elog(ERROR,"union_planner: query is marked hasAggs, but I don't see any");

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

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
/*-------------------------------------------------------------------------
22
*
33
* subselect.c
4+
* Planning routines for subselects and parameters.
5+
*
6+
* Copyright (c) 1994, Regents of the University of California
7+
*
8+
* IDENTIFICATION
9+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.18 1999/06/21 01:20:57 tgl Exp $
410
*
511
*-------------------------------------------------------------------------
612
*/
713
#include"postgres.h"
814

915
#include"catalog/pg_type.h"
10-
1116
#include"nodes/pg_list.h"
1217
#include"nodes/plannodes.h"
1318
#include"nodes/parsenodes.h"
1419
#include"nodes/relation.h"
1520
#include"nodes/makefuncs.h"
1621
#include"nodes/nodeFuncs.h"
17-
1822
#include"optimizer/subselect.h"
1923
#include"optimizer/planner.h"
2024
#include"optimizer/planmain.h"
@@ -27,12 +31,31 @@
2731
#include"optimizer/cost.h"
2832

2933
intPlannerQueryLevel;/* level of current query */
30-
List*PlannerVarParam;/* correlation Vars to Param mapper */
31-
List*PlannerParamVar;/* to get Var from Param->paramid */
3234
List*PlannerInitPlan;/* init subplans for current query */
33-
intPlannerPlanId;
35+
List*PlannerParamVar;/* to get Var from Param->paramid */
36+
intPlannerPlanId;/* to assign unique ID to subquery plans */
37+
38+
/*--------------------
39+
* PlannerParamVar is a list of Var nodes, wherein the n'th entry
40+
* (n counts from 0) corresponds to Param->paramid = n. The Var nodes
41+
* are ordinary except for one thing: their varlevelsup field does NOT
42+
* have the usual interpretation of "subplan levels out from current".
43+
* Instead, it contains the absolute plan level, with the outermost
44+
* plan being level 1 and nested plans having higher level numbers.
45+
* This nonstandardness is useful because we don't have to run around
46+
* and update the list elements when we enter or exit a subplan
47+
* recursion level. But we must pay attention not to confuse this
48+
* meaning with the normal meaning of varlevelsup.
49+
*--------------------
50+
*/
3451

3552

53+
/*
54+
* Create a new entry in the PlannerParamVar list, and return its index.
55+
*
56+
* var contains the data to be copied, except for varlevelsup which
57+
* is set from the absolute level value given by varlevel.
58+
*/
3659
staticint
3760
_new_param(Var*var,intvarlevel)
3861
{
@@ -61,38 +84,49 @@ _new_param(Var *var, int varlevel)
6184
returni;
6285
}
6386

87+
/*
88+
* Generate a Param node to replace the given Var,
89+
* which is expected to have varlevelsup > 0 (ie, it is not local).
90+
*/
6491
staticParam*
6592
_replace_var(Var*var)
6693
{
67-
List**rt= (List**)nth(var->varlevelsup,PlannerVarParam);
68-
List*vpe=rt[var->varno-1];
94+
List*ppv;
6995
Param*retval;
96+
intvarlevel;
7097
inti;
7198

72-
if (vpe==NULL)
73-
{
74-
vpe=rt[var->varno-1]=makeNode(List);
75-
lfirsti(vpe)=-1;
76-
lnext(vpe)=NULL;
77-
}
99+
Assert(var->varlevelsup>0&&var->varlevelsup<PlannerQueryLevel);
100+
varlevel=PlannerQueryLevel-var->varlevelsup;
78101

79-
for (i=ObjectIdAttributeNumber;;i++)
102+
/*
103+
* If there's already a PlannerParamVar entry for this same Var,
104+
* just use it. NOTE: in situations involving UNION or inheritance,
105+
* it is possible for the same varno/varlevel to refer to different RTEs
106+
* in different parts of the parsetree, so that different fields might
107+
* end up sharing the same Param number. As long as we check the vartype
108+
* as well, I believe that this sort of aliasing will cause no trouble.
109+
* The correct field should get stored into the Param slot at execution
110+
* in each part of the tree.
111+
*/
112+
i=0;
113+
foreach(ppv,PlannerParamVar)
80114
{
81-
if (i==var->varattno)
115+
Var*pvar=lfirst(ppv);
116+
117+
if (pvar->varno==var->varno&&
118+
pvar->varattno==var->varattno&&
119+
pvar->varlevelsup==varlevel&&
120+
pvar->vartype==var->vartype)
82121
break;
83-
if (lnext(vpe)==NULL)
84-
{
85-
lnext(vpe)=makeNode(List);
86-
vpe=lnext(vpe);
87-
lfirsti(vpe)=-1;
88-
lnext(vpe)=NULL;
89-
}
90-
else
91-
vpe=lnext(vpe);
122+
i++;
92123
}
93124

94-
if ((i=lfirsti(vpe))<0)/* parameter is not assigned */
95-
i=_new_param(var,PlannerQueryLevel-var->varlevelsup);
125+
if (!ppv)
126+
{
127+
/* Nope, so make a new one */
128+
i=_new_param(var,varlevel);
129+
}
96130

97131
retval=makeNode(Param);
98132
retval->paramkind=PARAM_EXEC;
@@ -125,7 +159,7 @@ _make_subplan(SubLink *slink)
125159
(void)SS_finalize_plan(plan);
126160
plan->initPlan=PlannerInitPlan;
127161

128-
/*Get extParamfromInitPlan-s */
162+
/*Create extParamlist as union ofInitPlan-s' lists */
129163
foreach(lst,PlannerInitPlan)
130164
{
131165
List*lp;
@@ -146,11 +180,12 @@ _make_subplan(SubLink *slink)
146180
node->sublink=slink;
147181
slink->subselect=NULL;/* cool ?! */
148182

149-
/* make parParam list */
183+
/* make parParam listof params coming from current query level*/
150184
foreach(lst,plan->extParam)
151185
{
152186
Var*var=nth(lfirsti(lst),PlannerParamVar);
153187

188+
/* note varlevelsup is absolute level number */
154189
if (var->varlevelsup==PlannerQueryLevel)
155190
node->parParam=lappendi(node->parParam,lfirsti(lst));
156191
}
@@ -170,7 +205,7 @@ _make_subplan(SubLink *slink)
170205
TargetEntry*te=nth(i,plan->targetlist);
171206
Var*var=makeVar(0,0,te->resdom->restype,
172207
te->resdom->restypmod,
173-
PlannerQueryLevel,0,0);
208+
0,0,0);
174209
Param*prm=makeNode(Param);
175210

176211
prm->paramkind=PARAM_EXEC;
@@ -190,7 +225,7 @@ _make_subplan(SubLink *slink)
190225
}
191226
elseif (node->parParam==NULL&&slink->subLinkType==EXISTS_SUBLINK)
192227
{
193-
Var*var=makeVar(0,0,BOOLOID,-1,PlannerQueryLevel,0,0);
228+
Var*var=makeVar(0,0,BOOLOID,-1,0,0,0);
194229
Param*prm=makeNode(Param);
195230

196231
prm->paramkind=PARAM_EXEC;
@@ -202,10 +237,10 @@ _make_subplan(SubLink *slink)
202237
result= (Node*)prm;
203238
}
204239
else
205-
/* make expression of SUBPLAN type */
206240
{
241+
/* make expression of SUBPLAN type */
207242
Expr*expr=makeNode(Expr);
208-
List*args=NULL;
243+
List*args=NIL;
209244
inti=0;
210245

211246
expr->typeOid=BOOLOID;
@@ -222,6 +257,10 @@ _make_subplan(SubLink *slink)
222257
Var*var=nth(lfirsti(lst),PlannerParamVar);
223258

224259
var= (Var*)copyObject(var);
260+
/* Must fix absolute-level varlevelsup from the
261+
* PlannerParamVar entry. But since var is at current
262+
* subplan level, this is easy:
263+
*/
225264
var->varlevelsup=0;
226265
args=lappend(args,var);
227266
}
@@ -240,7 +279,6 @@ _make_subplan(SubLink *slink)
240279
}
241280

242281
returnresult;
243-
244282
}
245283

246284
staticList*
@@ -305,6 +343,7 @@ _finalize_primnode(void *expr, List **subplan)
305343
{
306344
Var*var=nth(lfirsti(lst),PlannerParamVar);
307345

346+
/* note varlevelsup is absolute level number */
308347
if (var->varlevelsup<PlannerQueryLevel&&
309348
!intMember(lfirsti(lst),result))
310349
result=lappendi(result,lfirsti(lst));
@@ -332,10 +371,7 @@ SS_replace_correlation_vars(Node *expr)
332371
elseif (IsA(expr,Var))
333372
{
334373
if (((Var*)expr)->varlevelsup>0)
335-
{
336-
Assert(((Var*)expr)->varlevelsup<PlannerQueryLevel);
337374
expr= (Node*)_replace_var((Var*)expr);
338-
}
339375
}
340376
elseif (IsA(expr,Iter))
341377
((Iter*)expr)->iterexpr=SS_replace_correlation_vars(((Iter*)expr)->iterexpr);
@@ -480,6 +516,7 @@ SS_finalize_plan(Plan *plan)
480516
{
481517
Var*var=nth(lfirsti(lst),PlannerParamVar);
482518

519+
/* note varlevelsup is absolute level number */
483520
if (var->varlevelsup<PlannerQueryLevel)
484521
extParam=lappendi(extParam,lfirsti(lst));
485522
elseif (var->varlevelsup>PlannerQueryLevel)

‎src/include/optimizer/subselect.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
#defineSUBSELECT_H
99

1010
externintPlannerQueryLevel;/* level of current query */
11-
externList*PlannerVarParam;/* correlation Vars to Param mapper */
12-
externList*PlannerParamVar;/* to get Var from Param->paramid */
1311
externList*PlannerInitPlan;/* init subplans for current query */
14-
externintPlannerPlanId;/* to assigne unique ID to subquery plans */
12+
externList*PlannerParamVar;/* to get Var from Param->paramid */
13+
externintPlannerPlanId;/* to assign unique ID to subquery plans */
1514

1615
externList*SS_finalize_plan(Plan*plan);
1716
externNode*SS_replace_correlation_vars(Node*expr);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp