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

Commit51fd22a

Browse files
committed
Change set_plan_references and join_references to take an rtable List
rather than a Query node; this allows set_plan_references to recurseinto subplans correctly. Fixes core dump on full outer joins insubplans. Also, invoke preprocess_expression on function RTEs'function expressions. This seems to fix the planner's problems withouter-level Vars in function RTEs.
1 parent0a75715 commit51fd22a

File tree

7 files changed

+78
-57
lines changed

7 files changed

+78
-57
lines changed

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.114 2002/05/12 20:10:03 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.115 2002/05/18 02:25:49 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -671,19 +671,19 @@ create_nestloop_plan(Query *root,
671671

672672
/* only refs to outer vars get changed in the inner indexqual */
673673
innerscan->indxqualorig=join_references(indxqualorig,
674-
root,
674+
root->rtable,
675675
outer_tlist,
676676
NIL,
677677
innerrel);
678678
innerscan->indxqual=join_references(innerscan->indxqual,
679-
root,
679+
root->rtable,
680680
outer_tlist,
681681
NIL,
682682
innerrel);
683683
/* fix the inner qpqual too, if it has join clauses */
684684
if (NumRelids((Node*)inner_plan->qual)>1)
685685
inner_plan->qual=join_references(inner_plan->qual,
686-
root,
686+
root->rtable,
687687
outer_tlist,
688688
NIL,
689689
innerrel);
@@ -694,7 +694,7 @@ create_nestloop_plan(Query *root,
694694
TidScan*innerscan= (TidScan*)inner_plan;
695695

696696
innerscan->tideval=join_references(innerscan->tideval,
697-
root,
697+
root->rtable,
698698
outer_tlist,
699699
inner_tlist,
700700
innerscan->scan.scanrelid);
@@ -716,12 +716,12 @@ create_nestloop_plan(Query *root,
716716
* Set quals to contain INNER/OUTER var references.
717717
*/
718718
joinclauses=join_references(joinclauses,
719-
root,
719+
root->rtable,
720720
outer_tlist,
721721
inner_tlist,
722722
(Index)0);
723723
otherclauses=join_references(otherclauses,
724-
root,
724+
root->rtable,
725725
outer_tlist,
726726
inner_tlist,
727727
(Index)0);
@@ -760,7 +760,7 @@ create_mergejoin_plan(Query *root,
760760
* clauses to contain INNER/OUTER var references.
761761
*/
762762
joinclauses=join_references(set_difference(joinclauses,mergeclauses),
763-
root,
763+
root->rtable,
764764
outer_tlist,
765765
inner_tlist,
766766
(Index)0);
@@ -769,7 +769,7 @@ create_mergejoin_plan(Query *root,
769769
* Fix the additional qpquals too.
770770
*/
771771
otherclauses=join_references(otherclauses,
772-
root,
772+
root->rtable,
773773
outer_tlist,
774774
inner_tlist,
775775
(Index)0);
@@ -779,7 +779,7 @@ create_mergejoin_plan(Query *root,
779779
* that the outer variable is always on the left.
780780
*/
781781
mergeclauses=switch_outer(join_references(mergeclauses,
782-
root,
782+
root->rtable,
783783
outer_tlist,
784784
inner_tlist,
785785
(Index)0));
@@ -886,7 +886,7 @@ create_hashjoin_plan(Query *root,
886886
* clauses to contain INNER/OUTER var references.
887887
*/
888888
joinclauses=join_references(set_difference(joinclauses,hashclauses),
889-
root,
889+
root->rtable,
890890
outer_tlist,
891891
inner_tlist,
892892
(Index)0);
@@ -895,7 +895,7 @@ create_hashjoin_plan(Query *root,
895895
* Fix the additional qpquals too.
896896
*/
897897
otherclauses=join_references(otherclauses,
898-
root,
898+
root->rtable,
899899
outer_tlist,
900900
inner_tlist,
901901
(Index)0);
@@ -905,7 +905,7 @@ create_hashjoin_plan(Query *root,
905905
* that the outer variable is always on the left.
906906
*/
907907
hashclauses=switch_outer(join_references(hashclauses,
908-
root,
908+
root->rtable,
909909
outer_tlist,
910910
inner_tlist,
911911
(Index)0));

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.71 2002/05/17 22:35:12 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.72 2002/05/18 02:25:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -177,7 +177,7 @@ add_vars_to_targetlist(Query *root, List *vars)
177177
List*varsused;
178178

179179
expansion=flatten_join_alias_vars((Node*)var,
180-
root, true);
180+
root->rtable, true);
181181
varsused=pull_var_clause(expansion, false);
182182
add_vars_to_targetlist(root,varsused);
183183
freeList(varsused);

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.117 2002/05/12 23:43:03 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.118 2002/05/18 02:25:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -101,7 +101,7 @@ planner(Query *parse)
101101
result_plan->nParamExec=length(PlannerParamVar);
102102

103103
/* final cleanup of the plan */
104-
set_plan_references(parse,result_plan);
104+
set_plan_references(result_plan,parse->rtable);
105105

106106
/* restore state for outer planner, if any */
107107
PlannerQueryLevel=save_PlannerQueryLevel;
@@ -175,6 +175,17 @@ subquery_planner(Query *parse, double tuple_fraction)
175175
parse->havingQual=preprocess_expression(parse,parse->havingQual,
176176
EXPRKIND_HAVING);
177177

178+
/* Also need to preprocess expressions for function RTEs */
179+
foreach(lst,parse->rtable)
180+
{
181+
RangeTblEntry*rte= (RangeTblEntry*)lfirst(lst);
182+
183+
if (rte->rtekind==RTE_FUNCTION)
184+
rte->funcexpr=preprocess_expression(parse,rte->funcexpr,
185+
EXPRKIND_TARGET);
186+
/* These are not targetlist items, but close enough... */
187+
}
188+
178189
/*
179190
* Check for ungrouped variables passed to subplans in targetlist and
180191
* HAVING clause (but not in WHERE or JOIN/ON clauses, since those are
@@ -737,7 +748,7 @@ preprocess_expression(Query *parse, Node *expr, int kind)
737748
}
738749
}
739750
if (has_join_rtes)
740-
expr=flatten_join_alias_vars(expr,parse, false);
751+
expr=flatten_join_alias_vars(expr,parse->rtable, false);
741752

742753
returnexpr;
743754
}

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

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.77 2002/05/1800:42:55 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.78 2002/05/1802:25:50 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -28,7 +28,7 @@
2828

2929
typedefstruct
3030
{
31-
Query*root;
31+
List*rtable;
3232
List*outer_tlist;
3333
List*inner_tlist;
3434
Indexacceptable_rel;
@@ -42,7 +42,7 @@ typedef struct
4242
}replace_vars_with_subplan_refs_context;
4343

4444
staticvoidfix_expr_references(Plan*plan,Node*node);
45-
staticvoidset_join_references(Query*root,Join*join);
45+
staticvoidset_join_references(Join*join,List*rtable);
4646
staticvoidset_uppernode_references(Plan*plan,Indexsubvarno);
4747
staticNode*join_references_mutator(Node*node,
4848
join_references_context*context);
@@ -75,7 +75,7 @@ static bool fix_opids_walker(Node *node, void *context);
7575
* Returns nothing of interest, but modifies internal fields of nodes.
7676
*/
7777
void
78-
set_plan_references(Query*root,Plan*plan)
78+
set_plan_references(Plan*plan,List*rtable)
7979
{
8080
List*pl;
8181

@@ -110,16 +110,24 @@ set_plan_references(Query *root, Plan *plan)
110110
fix_expr_references(plan, (Node*)plan->qual);
111111
break;
112112
caseT_SubqueryScan:
113+
{
114+
RangeTblEntry*rte;
113115

114-
/*
115-
* We do not do set_uppernode_references() here, because a
116-
* SubqueryScan will always have been created with correct
117-
* references to its subplan's outputs to begin with.
118-
*/
119-
fix_expr_references(plan, (Node*)plan->targetlist);
120-
fix_expr_references(plan, (Node*)plan->qual);
121-
/* Recurse into subplan too */
122-
set_plan_references(root, ((SubqueryScan*)plan)->subplan);
116+
/*
117+
* We do not do set_uppernode_references() here, because a
118+
* SubqueryScan will always have been created with correct
119+
* references to its subplan's outputs to begin with.
120+
*/
121+
fix_expr_references(plan, (Node*)plan->targetlist);
122+
fix_expr_references(plan, (Node*)plan->qual);
123+
124+
/* Recurse into subplan too */
125+
rte=rt_fetch(((SubqueryScan*)plan)->scan.scanrelid,
126+
rtable);
127+
Assert(rte->rtekind==RTE_SUBQUERY);
128+
set_plan_references(((SubqueryScan*)plan)->subplan,
129+
rte->subquery->rtable);
130+
}
123131
break;
124132
caseT_FunctionScan:
125133
{
@@ -128,27 +136,27 @@ set_plan_references(Query *root, Plan *plan)
128136
fix_expr_references(plan, (Node*)plan->targetlist);
129137
fix_expr_references(plan, (Node*)plan->qual);
130138
rte=rt_fetch(((FunctionScan*)plan)->scan.scanrelid,
131-
root->rtable);
139+
rtable);
132140
Assert(rte->rtekind==RTE_FUNCTION);
133141
fix_expr_references(plan,rte->funcexpr);
134142
}
135143
break;
136144
caseT_NestLoop:
137-
set_join_references(root,(Join*)plan);
145+
set_join_references((Join*)plan,rtable);
138146
fix_expr_references(plan, (Node*)plan->targetlist);
139147
fix_expr_references(plan, (Node*)plan->qual);
140148
fix_expr_references(plan, (Node*) ((Join*)plan)->joinqual);
141149
break;
142150
caseT_MergeJoin:
143-
set_join_references(root,(Join*)plan);
151+
set_join_references((Join*)plan,rtable);
144152
fix_expr_references(plan, (Node*)plan->targetlist);
145153
fix_expr_references(plan, (Node*)plan->qual);
146154
fix_expr_references(plan, (Node*) ((Join*)plan)->joinqual);
147155
fix_expr_references(plan,
148156
(Node*) ((MergeJoin*)plan)->mergeclauses);
149157
break;
150158
caseT_HashJoin:
151-
set_join_references(root,(Join*)plan);
159+
set_join_references((Join*)plan,rtable);
152160
fix_expr_references(plan, (Node*)plan->targetlist);
153161
fix_expr_references(plan, (Node*)plan->qual);
154162
fix_expr_references(plan, (Node*) ((Join*)plan)->joinqual);
@@ -202,7 +210,7 @@ set_plan_references(Query *root, Plan *plan)
202210
* recurse into subplans.
203211
*/
204212
foreach(pl, ((Append*)plan)->appendplans)
205-
set_plan_references(root,(Plan*)lfirst(pl));
213+
set_plan_references((Plan*)lfirst(pl),rtable);
206214
break;
207215
default:
208216
elog(ERROR,"set_plan_references: unknown plan type %d",
@@ -219,21 +227,21 @@ set_plan_references(Query *root, Plan *plan)
219227
* plan's var nodes against the already-modified nodes of the
220228
* subplans.
221229
*/
222-
set_plan_references(root,plan->lefttree);
223-
set_plan_references(root,plan->righttree);
230+
set_plan_references(plan->lefttree,rtable);
231+
set_plan_references(plan->righttree,rtable);
224232
foreach(pl,plan->initPlan)
225233
{
226234
SubPlan*sp= (SubPlan*)lfirst(pl);
227235

228236
Assert(IsA(sp,SubPlan));
229-
set_plan_references(root,sp->plan);
237+
set_plan_references(sp->plan,sp->rtable);
230238
}
231239
foreach(pl,plan->subPlan)
232240
{
233241
SubPlan*sp= (SubPlan*)lfirst(pl);
234242

235243
Assert(IsA(sp,SubPlan));
236-
set_plan_references(root,sp->plan);
244+
set_plan_references(sp->plan,sp->rtable);
237245
}
238246
}
239247

@@ -269,18 +277,19 @@ fix_expr_references(Plan *plan, Node *node)
269277
* creation of a plan node by createplan.c and its fixing by this module.
270278
* Fortunately, there doesn't seem to be any need to do that.
271279
*
272-
* 'join' is a join plan node
280+
*'join' is a join plan node
281+
*'rtable' is the associated range table
273282
*/
274283
staticvoid
275-
set_join_references(Query*root,Join*join)
284+
set_join_references(Join*join,List*rtable)
276285
{
277286
Plan*outer=join->plan.lefttree;
278287
Plan*inner=join->plan.righttree;
279288
List*outer_tlist= ((outer==NULL) ?NIL :outer->targetlist);
280289
List*inner_tlist= ((inner==NULL) ?NIL :inner->targetlist);
281290

282291
join->plan.targetlist=join_references(join->plan.targetlist,
283-
root,
292+
rtable,
284293
outer_tlist,
285294
inner_tlist,
286295
(Index)0);
@@ -374,6 +383,7 @@ set_uppernode_references(Plan *plan, Index subvarno)
374383
* pass inner_tlist = NIL and acceptable_rel = the ID of the inner relation.
375384
*
376385
* 'clauses' is the targetlist or list of join clauses
386+
* 'rtable' is the current range table
377387
* 'outer_tlist' is the target list of the outer join relation
378388
* 'inner_tlist' is the target list of the inner join relation, or NIL
379389
* 'acceptable_rel' is either zero or the rangetable index of a relation
@@ -384,14 +394,14 @@ set_uppernode_references(Plan *plan, Index subvarno)
384394
*/
385395
List*
386396
join_references(List*clauses,
387-
Query*root,
397+
List*rtable,
388398
List*outer_tlist,
389399
List*inner_tlist,
390400
Indexacceptable_rel)
391401
{
392402
join_references_contextcontext;
393403

394-
context.root=root;
404+
context.rtable=rtable;
395405
context.outer_tlist=outer_tlist;
396406
context.inner_tlist=inner_tlist;
397407
context.acceptable_rel=acceptable_rel;
@@ -432,7 +442,7 @@ join_references_mutator(Node *node,
432442

433443
/* Perhaps it's a join alias that can be resolved to input vars? */
434444
newnode=flatten_join_alias_vars((Node*)var,
435-
context->root,
445+
context->rtable,
436446
true);
437447
if (!equal(newnode, (Node*)var))
438448
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp