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

Commit 0372894

Browse files
committed
For non-projecting plan node types such as Limit, set_plan_references
has to recopy the input plan node's targetlist if it removes a SubqueryScan node just below the non-projecting node. For simplicity I made it recopy always. Per bug report from Allan Wang and Michael Fuhr.
1 parent 2739e1d commit 0372894

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

src/backend/optimizer/plan/setrefs.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.112 2005/08/27 18:04:49 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.113 2005/09/05 17:25:01 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -130,6 +130,7 @@ static void set_sa_opfuncid(ScalarArrayOpExpr *opexpr);
130130
Plan *
131131
set_plan_references(Plan *plan, List *rtable)
132132
{
133+
bool copy_lefttree_tlist = false;
133134
ListCell *l;
134135

135136
if (plan == NULL)
@@ -218,14 +219,13 @@ set_plan_references(Plan *plan, List *rtable)
218219

219220
/*
220221
* These plan types don't actually bother to evaluate their
221-
* targetlists (because they just return their unmodified
222-
* input tuples). The optimizer is lazy about creating really
223-
* valid targetlists for them --- it tends to just put in a
224-
* pointer to the child plan node's tlist. Hence, we leave
225-
* the tlist alone. In particular, we do not want to process
226-
* subplans in the tlist, since we will likely end up reprocessing
227-
* subplans that also appear in lower levels of the plan tree!
228-
*
222+
* targetlists, because they just return their unmodified
223+
* input tuples; so their targetlists should just be copies
224+
* of their input plan nodes' targetlists. The actual copying
225+
* has to be done after we've finalized the input node.
226+
*/
227+
copy_lefttree_tlist = true;
228+
/*
229229
* Since these plan types don't check quals either, we should
230230
* not find any qual expression attached to them.
231231
*/
@@ -238,6 +238,7 @@ set_plan_references(Plan *plan, List *rtable)
238238
* or quals. It does have live expressions for limit/offset,
239239
* however.
240240
*/
241+
copy_lefttree_tlist = true;
241242
Assert(plan->qual == NIL);
242243
fix_expr_references(plan, ((Limit *) plan)->limitOffset);
243244
fix_expr_references(plan, ((Limit *) plan)->limitCount);
@@ -266,9 +267,10 @@ set_plan_references(Plan *plan, List *rtable)
266267

267268
/*
268269
* Append, like Sort et al, doesn't actually evaluate its
269-
* targetlist or check quals, and we haven't bothered to give it
270-
* its own tlist copy. So, don't fix targetlist/qual. But do
271-
* recurse into child plans.
270+
* targetlist or check quals, so don't fix targetlist/qual.
271+
* But do recurse into child plans. (Unlike Sort et al, the
272+
* correct tlist was made by createplan.c and we shouldn't
273+
* replace it.)
272274
*/
273275
Assert(plan->qual == NIL);
274276
foreach(l, ((Append *) plan)->appendplans)
@@ -315,6 +317,20 @@ set_plan_references(Plan *plan, List *rtable)
315317
sp->plan = set_plan_references(sp->plan, sp->rtable);
316318
}
317319

320+
/*
321+
* If this is a non-projecting plan node, create a minimally valid
322+
* targetlist for it. Someday we might need to make this look really
323+
* real, with Vars referencing the input node's outputs, but for now
324+
* the executor only cares that the tlist has the right TargetEntry
325+
* fields (resname, resjunk etc) and exprType results. So we can
326+
* get away with just copying the input node's tlist. (Note:
327+
* createplan.c already did copy the input, but we have to do it
328+
* over in case we removed a SubqueryScan node: the new input plan
329+
* node might have extra resjunk fields.)
330+
*/
331+
if (copy_lefttree_tlist)
332+
plan->targetlist = copyObject(plan->lefttree->targetlist);
333+
318334
return plan;
319335
}
320336

0 commit comments

Comments
 (0)