Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 2190cf2

Browse files
committed
Repair bug reported by ldm@apartia.com: Append nodes, which don't
actually use their targetlist, are given a targetlist that is just a pointer to the first appended plan's targetlist. This is OK, but what is not OK is that any sub-select expressions in said tlist were being entered in the subPlan lists of both the Append and the first appended plan. That led to two startup and two shutdown calls for the same plan node at exec time, which led to crashes. Fix is to not generate a list of subPlans for an Append node. Same problem and fix apply to other node types that don't have a real, functioning targetlist: Material, Sort, Unique, Hash.
1 parent 54bce38 commit 2190cf2

File tree

1 file changed

+52
-39
lines changed

1 file changed

+52
-39
lines changed

src/backend/optimizer/plan/setrefs.c

+52-39
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.63 2000/05/30 00:49:47 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.64 2000/06/04 20:50:50 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -35,6 +35,7 @@ typedef struct
3535
List *subplanTargetList;
3636
} replace_vars_with_subplan_refs_context;
3737

38+
static void fix_expr_references(Plan *plan, Node *node);
3839
static void set_join_references(Join *join);
3940
static void set_uppernode_references(Plan *plan, Index subvarno);
4041
static Node *join_references_mutator(Node *node,
@@ -86,34 +87,39 @@ set_plan_references(Plan *plan)
8687
switch (nodeTag(plan))
8788
{
8889
case T_SeqScan:
89-
/* nothing special */
90+
fix_expr_references(plan, (Node *) plan->targetlist);
91+
fix_expr_references(plan, (Node *) plan->qual);
9092
break;
9193
case T_IndexScan:
92-
fix_opids((Node *) ((IndexScan *) plan)->indxqual);
93-
fix_opids((Node *) ((IndexScan *) plan)->indxqualorig);
94-
plan->subPlan =
95-
nconc(plan->subPlan,
96-
pull_subplans((Node *) ((IndexScan *) plan)->indxqual));
97-
plan->subPlan =
98-
nconc(plan->subPlan,
99-
pull_subplans((Node *) ((IndexScan *) plan)->indxqualorig));
94+
fix_expr_references(plan, (Node *) plan->targetlist);
95+
fix_expr_references(plan, (Node *) plan->qual);
96+
fix_expr_references(plan,
97+
(Node *) ((IndexScan *) plan)->indxqual);
98+
fix_expr_references(plan,
99+
(Node *) ((IndexScan *) plan)->indxqualorig);
100+
break;
101+
case T_TidScan:
102+
fix_expr_references(plan, (Node *) plan->targetlist);
103+
fix_expr_references(plan, (Node *) plan->qual);
100104
break;
101105
case T_NestLoop:
102106
set_join_references((Join *) plan);
107+
fix_expr_references(plan, (Node *) plan->targetlist);
108+
fix_expr_references(plan, (Node *) plan->qual);
103109
break;
104110
case T_MergeJoin:
105111
set_join_references((Join *) plan);
106-
fix_opids((Node *) ((MergeJoin *) plan)->mergeclauses);
107-
plan->subPlan =
108-
nconc(plan->subPlan,
109-
pull_subplans((Node *) ((MergeJoin *) plan)->mergeclauses));
112+
fix_expr_references(plan, (Node *) plan->targetlist);
113+
fix_expr_references(plan, (Node *) plan->qual);
114+
fix_expr_references(plan,
115+
(Node *) ((MergeJoin *) plan)->mergeclauses);
110116
break;
111117
case T_HashJoin:
112118
set_join_references((Join *) plan);
113-
fix_opids((Node *) ((HashJoin *) plan)->hashclauses);
114-
plan->subPlan =
115-
nconc(plan->subPlan,
116-
pull_subplans((Node *) ((HashJoin *) plan)->hashclauses));
119+
fix_expr_references(plan, (Node *) plan->targetlist);
120+
fix_expr_references(plan, (Node *) plan->qual);
121+
fix_expr_references(plan,
122+
(Node *) ((HashJoin *) plan)->hashclauses);
117123
break;
118124
case T_Material:
119125
case T_Sort:
@@ -125,12 +131,17 @@ set_plan_references(Plan *plan)
125131
* targetlists or quals (because they just return their
126132
* unmodified input tuples). The optimizer is lazy about
127133
* creating really valid targetlists for them. Best to just
128-
* leave the targetlist alone.
134+
* leave the targetlist alone. In particular, we do not want
135+
* to pull a subplan list for them, since we will likely end
136+
* up with duplicate list entries for subplans that also appear
137+
* in lower levels of the plan tree!
129138
*/
130139
break;
131140
case T_Agg:
132141
case T_Group:
133142
set_uppernode_references(plan, (Index) 0);
143+
fix_expr_references(plan, (Node *) plan->targetlist);
144+
fix_expr_references(plan, (Node *) plan->qual);
134145
break;
135146
case T_Result:
136147

@@ -142,37 +153,25 @@ set_plan_references(Plan *plan)
142153
*/
143154
if (plan->lefttree != NULL)
144155
set_uppernode_references(plan, (Index) OUTER);
145-
fix_opids(((Result *) plan)->resconstantqual);
146-
plan->subPlan =
147-
nconc(plan->subPlan,
148-
pull_subplans(((Result *) plan)->resconstantqual));
156+
fix_expr_references(plan, (Node *) plan->targetlist);
157+
fix_expr_references(plan, (Node *) plan->qual);
158+
fix_expr_references(plan, ((Result *) plan)->resconstantqual);
149159
break;
150160
case T_Append:
161+
/*
162+
* Append, like Sort et al, doesn't actually evaluate its
163+
* targetlist or quals, and we haven't bothered to give it
164+
* its own tlist copy. So, don't fix targetlist/qual.
165+
*/
151166
foreach(pl, ((Append *) plan)->appendplans)
152167
set_plan_references((Plan *) lfirst(pl));
153168
break;
154-
case T_TidScan:
155-
/* nothing special */
156-
break;
157169
default:
158170
elog(ERROR, "set_plan_references: unknown plan type %d",
159171
nodeTag(plan));
160172
break;
161173
}
162174

163-
/*
164-
* For all plan types, fix operators in targetlist and qual
165-
* expressions, and find subplans therein.
166-
*/
167-
fix_opids((Node *) plan->targetlist);
168-
fix_opids((Node *) plan->qual);
169-
plan->subPlan =
170-
nconc(plan->subPlan,
171-
pull_subplans((Node *) plan->targetlist));
172-
plan->subPlan =
173-
nconc(plan->subPlan,
174-
pull_subplans((Node *) plan->qual));
175-
176175
/*
177176
* Now recurse into subplans, if any
178177
*
@@ -200,6 +199,20 @@ set_plan_references(Plan *plan)
200199
}
201200
}
202201

202+
/*
203+
* fix_expr_references
204+
* Do final cleanup on expressions (targetlists or quals).
205+
*
206+
* This consists of looking up operator opcode info for Oper nodes
207+
* and adding subplans to the Plan node's list of contained subplans.
208+
*/
209+
static void
210+
fix_expr_references(Plan *plan, Node *node)
211+
{
212+
fix_opids(node);
213+
plan->subPlan = nconc(plan->subPlan, pull_subplans(node));
214+
}
215+
203216
/*
204217
* set_join_references
205218
* Modifies the target list of a join node to reference its subplans,

0 commit comments

Comments
 (0)