99 *
1010 *
1111 * IDENTIFICATION
12- * $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.113 2005/09/0517:25:01 tgl Exp $
12+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.114 2005/09/0518:59:38 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -130,7 +130,6 @@ static void set_sa_opfuncid(ScalarArrayOpExpr *opexpr);
130130Plan *
131131set_plan_references (Plan * plan ,List * rtable )
132132{
133- bool copy_lefttree_tlist = false;
134133ListCell * l ;
135134
136135if (plan == NULL )
@@ -219,13 +218,14 @@ set_plan_references(Plan *plan, List *rtable)
219218
220219/*
221220 * These plan types don't actually bother to evaluate their
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- /*
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+ *
229229 * Since these plan types don't check quals either, we should
230230 * not find any qual expression attached to them.
231231 */
@@ -238,7 +238,6 @@ 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;
242241Assert (plan -> qual == NIL );
243242fix_expr_references (plan , ((Limit * )plan )-> limitOffset );
244243fix_expr_references (plan , ((Limit * )plan )-> limitCount );
@@ -267,10 +266,9 @@ set_plan_references(Plan *plan, List *rtable)
267266
268267/*
269268 * Append, like Sort et al, doesn't actually evaluate its
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.)
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.
274272 */
275273Assert (plan -> qual == NIL );
276274foreach (l , ((Append * )plan )-> appendplans )
@@ -317,20 +315,6 @@ set_plan_references(Plan *plan, List *rtable)
317315sp -> plan = set_plan_references (sp -> plan ,sp -> rtable );
318316}
319317
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-
334318return plan ;
335319}
336320
@@ -430,6 +414,10 @@ trivial_subqueryscan(SubqueryScan *plan)
430414if (plan -> scan .plan .qual != NIL )
431415return false;
432416
417+ if (list_length (plan -> scan .plan .targetlist )!=
418+ list_length (plan -> subplan -> targetlist ))
419+ return false;/* tlists not same length */
420+
433421attrno = 1 ;
434422forboth (lp ,plan -> scan .plan .targetlist ,lc ,plan -> subplan -> targetlist )
435423{
@@ -448,18 +436,6 @@ trivial_subqueryscan(SubqueryScan *plan)
448436attrno ++ ;
449437}
450438
451- if (lp )
452- return false;/* parent tlist longer than child */
453-
454- /* extra child items are OK only if all are resjunk */
455- for_each_cell (lc ,lc )
456- {
457- TargetEntry * ctle = (TargetEntry * )lfirst (lc );
458-
459- if (!ctle -> resjunk )
460- return false;
461- }
462-
463439return true;
464440}
465441