diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index f76c778998b26c111b362e77bce57a68fa26cbbb..d1eb29691a06c648f38a93633efc6296986dc216 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -54,7 +54,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.185 2007/06/11 01:16:22 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.186 2007/09/22 21:36:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2049,9 +2049,10 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
 		{
 			/*
 			 * Otherwise we will be rescanning the subplan output on each
-			 * evaluation.	We need to estimate how much of the output we will
-			 * actually need to scan.  NOTE: this logic should agree with the
-			 * estimates used by make_subplan() in plan/subselect.c.
+			 * evaluation.  We need to estimate how much of the output we will
+			 * actually need to scan.  NOTE: this logic should agree with
+			 * get_initplan_cost, below, and with the estimates used by
+			 * make_subplan() in plan/subselect.c.
 			 */
 			Cost		plan_run_cost = plan->total_cost - plan->startup_cost;
 
@@ -2097,6 +2098,43 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
 }
 
 
+/*
+ * get_initplan_cost
+ *		Get the expected cost of evaluating an initPlan.
+ *
+ * Keep this in sync with cost_qual_eval_walker's handling of subplans, above,
+ * and with the estimates used by make_subplan() in plan/subselect.c.
+ */
+Cost
+get_initplan_cost(PlannerInfo *root, SubPlan *subplan)
+{
+	Cost		result;
+	Plan	   *plan = planner_subplan_get_plan(root, subplan);
+
+	/* initPlans never use hashtables */
+	Assert(!subplan->useHashTable);
+	/* they are never ALL or ANY, either */
+	Assert(!(subplan->subLinkType == ALL_SUBLINK ||
+			 subplan->subLinkType == ANY_SUBLINK));
+
+	if (subplan->subLinkType == EXISTS_SUBLINK)
+	{
+		/* we only need to fetch 1 tuple */
+		Cost		plan_run_cost = plan->total_cost - plan->startup_cost;
+
+		result = plan->startup_cost;
+		result += plan_run_cost / plan->plan_rows;
+	}
+	else
+	{
+		/* assume we need all tuples */
+		result = plan->total_cost;
+	}
+
+	return result;
+}
+
+
 /*
  * approx_selectivity
  *		Quick-and-dirty estimation of clause selectivities.
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 8b739e16d4464b05146f0555c07882e967c78a78..76d80bfce0f0cd5cb26c28f5c3fef54f08f7acbf 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.124 2007/08/26 21:44:25 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.125 2007/09/22 21:36:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,6 +18,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "optimizer/clauses.h"
+#include "optimizer/cost.h"
 #include "optimizer/planmain.h"
 #include "optimizer/planner.h"
 #include "optimizer/subselect.h"
@@ -266,7 +267,7 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
 	 * (we're only expecting one row out, anyway).
 	 *
 	 * NOTE: if you change these numbers, also change cost_qual_eval_walker()
-	 * in path/costsize.c.
+	 * and get_initplan_cost() in path/costsize.c.
 	 *
 	 * XXX If an ALL/ANY subplan is uncorrelated, we may decide to hash or
 	 * materialize its result below.  In that case it would've been better to
@@ -1021,7 +1022,7 @@ SS_finalize_plan(PlannerInfo *root, Plan *plan)
 	 * 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
+	 * We also add the eval cost of each initPlan to the startup cost of the
 	 * top node.  This is a conservative overestimate, since in fact each
 	 * initPlan might be executed later than plan startup, or even not at all.
 	 */
@@ -1041,7 +1042,7 @@ SS_finalize_plan(PlannerInfo *root, Plan *plan)
 		{
 			initSetParam = bms_add_member(initSetParam, lfirst_int(l2));
 		}
-		initplan_cost += initplan->total_cost;
+		initplan_cost += get_initplan_cost(root, initsubplan);
 	}
 	/* allParam must include all these params */
 	plan->allParam = bms_add_members(plan->allParam, initExtParam);
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index dc052dcf55fac42769e83fff173d36f43c1b2cf3..22034850148e0f59abb33cc6a16cb33612e8d3a8 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/optimizer/cost.h,v 1.88 2007/07/25 12:22:53 mha Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/cost.h,v 1.89 2007/09/22 21:36:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -92,6 +92,7 @@ extern void cost_mergejoin(MergePath *path, PlannerInfo *root);
 extern void cost_hashjoin(HashPath *path, PlannerInfo *root);
 extern void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root);
 extern void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root);
+extern Cost get_initplan_cost(PlannerInfo *root, SubPlan *subplan);
 extern void set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel);
 extern void set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel,
 						   RelOptInfo *outer_rel,