diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index b9e123d8e63e87d3649d8174f5783efa69f5f7e5..1b5533cded4a06d6a628552383efd5ae767c64dd 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.106 2006/04/28 20:57:49 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.107 2006/05/03 00:24:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -912,9 +912,11 @@ process_sublinks_mutator(Node *node, bool *isTopQual)
 void
 SS_finalize_plan(Plan *plan, List *rtable)
 {
-	Bitmapset  *outer_params = NULL;
-	Bitmapset  *valid_params = NULL;
-	Cost		initplan_cost = 0;
+	Bitmapset  *outer_params,
+			   *valid_params,
+			   *initExtParam,
+			   *initSetParam;
+	Cost		initplan_cost;
 	int			paramid;
 	ListCell   *l;
 
@@ -923,6 +925,7 @@ SS_finalize_plan(Plan *plan, List *rtable)
 	 * available from outer query levels and my own query level. We do this
 	 * once to save time in the per-plan recursion steps.
 	 */
+	outer_params = valid_params = NULL;
 	paramid = 0;
 	foreach(l, PlannerParamList)
 	{
@@ -954,7 +957,11 @@ SS_finalize_plan(Plan *plan, List *rtable)
 
 	/*
 	 * Finally, attach any initPlans to the topmost plan node, and add their
-	 * extParams to the topmost node's, too.
+	 * extParams to the topmost node's, too.  However, any setParams of the
+	 * initPlans should not be present in the topmost node's extParams, only
+	 * in its allParams.  (As of PG 8.1, it's possible that some initPlans
+	 * have extParams that are setParams of other initPlans, so we have to
+	 * take care of this situation explicitly.)
 	 *
 	 * We also add the total_cost of each initPlan to the startup cost of the
 	 * top node.  This is a conservative overestimate, since in fact each
@@ -963,17 +970,29 @@ SS_finalize_plan(Plan *plan, List *rtable)
 	plan->initPlan = PlannerInitPlan;
 	PlannerInitPlan = NIL;		/* make sure they're not attached twice */
 
+	initExtParam = initSetParam = NULL;
+	initplan_cost = 0;
 	foreach(l, plan->initPlan)
 	{
 		SubPlan    *initplan = (SubPlan *) lfirst(l);
+		ListCell   *l2;
 
-		plan->extParam = bms_add_members(plan->extParam,
-										 initplan->plan->extParam);
-		/* allParam must include all members of extParam */
-		plan->allParam = bms_add_members(plan->allParam,
-										 plan->extParam);
+		initExtParam = bms_add_members(initExtParam,
+									   initplan->plan->extParam);
+		foreach(l2, initplan->setParam)
+		{
+			initSetParam = bms_add_member(initSetParam, lfirst_int(l2));
+		}
 		initplan_cost += initplan->plan->total_cost;
 	}
+	/* allParam must include all these params */
+	plan->allParam = bms_add_members(plan->allParam, initExtParam);
+	plan->allParam = bms_add_members(plan->allParam, initSetParam);
+	/* but extParam shouldn't include any setParams */
+	initExtParam = bms_del_members(initExtParam, initSetParam);
+	/* empty test ensures extParam is exactly NULL if it's empty */
+	if (!bms_is_empty(initExtParam))
+		plan->extParam = bms_join(plan->extParam, initExtParam);
 
 	plan->startup_cost += initplan_cost;
 	plan->total_cost += initplan_cost;