diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 34a3aaf1c949b5a17303ee62bd208f3dececc14a..3011f687c593f8130d469fea8115fa914593f1c1 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -49,7 +49,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.109 2003/06/29 23:05:04 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.110 2003/07/14 22:35:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -415,6 +415,38 @@ cost_tidscan(Path *path, Query *root,
 	path->total_cost = startup_cost + run_cost;
 }
 
+/*
+ * cost_subqueryscan
+ *	  Determines and returns the cost of scanning a subquery RTE.
+ */
+void
+cost_subqueryscan(Path *path, RelOptInfo *baserel)
+{
+	Cost		startup_cost;
+	Cost		run_cost;
+	Cost		cpu_per_tuple;
+
+	/* Should only be applied to base relations that are subqueries */
+	Assert(baserel->relid > 0);
+	Assert(baserel->rtekind == RTE_SUBQUERY);
+
+	/*
+	 * Cost of path is cost of evaluating the subplan, plus cost of
+	 * evaluating any restriction clauses that will be attached to the
+	 * SubqueryScan node, plus cpu_tuple_cost to account for selection
+	 * and projection overhead.
+	 */
+	path->startup_cost = baserel->subplan->startup_cost;
+	path->total_cost = baserel->subplan->total_cost;
+
+	startup_cost = baserel->baserestrictcost.startup;
+	cpu_per_tuple = cpu_tuple_cost + baserel->baserestrictcost.per_tuple;
+	run_cost = cpu_per_tuple * baserel->tuples;
+
+	path->startup_cost += startup_cost;
+	path->total_cost += startup_cost + run_cost;
+}
+
 /*
  * cost_functionscan
  *	  Determines and returns the cost of scanning a function RTE.
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 1cdc3628b20ceb718b4e380e66232c12e77b1076..79855b00c0f97594b78cd91e540d5021b8ae5151 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.147 2003/06/29 23:05:04 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.148 2003/07/14 22:35:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -811,6 +811,8 @@ create_subqueryscan_plan(Path *best_path, List *tlist, List *scan_clauses)
 								  scan_relid,
 								  best_path->parent->subplan);
 
+	copy_path_costsize(&scan_plan->scan.plan, best_path);
+
 	return scan_plan;
 }
 
@@ -1503,8 +1505,14 @@ make_subqueryscan(List *qptlist,
 	SubqueryScan *node = makeNode(SubqueryScan);
 	Plan	   *plan = &node->scan.plan;
 
-	/* cost is figured here for the convenience of prepunion.c */
+	/*
+	 * Cost is figured here for the convenience of prepunion.c.  Note this
+	 * is only correct for the case where qpqual is empty; otherwise caller
+	 * should overwrite cost with a better estimate.
+	 */
 	copy_plan_costsize(plan, subplan);
+	plan->total_cost += cpu_tuple_cost * subplan->plan_rows;
+
 	plan->targetlist = qptlist;
 	plan->qual = qpqual;
 	plan->lefttree = NULL;
@@ -1540,7 +1548,11 @@ make_append(List *appendplans, bool isTarget, List *tlist)
 	Plan	   *plan = &node->plan;
 	List	   *subnode;
 
-	/* compute costs from subplan costs */
+	/*
+	 * Compute cost as sum of subplan costs.  We charge nothing extra for
+	 * the Append itself, which perhaps is too optimistic, but since it
+	 * doesn't do any selection or projection, it is a pretty cheap node.
+	 */
 	plan->startup_cost = 0;
 	plan->total_cost = 0;
 	plan->plan_rows = 0;
@@ -1556,6 +1568,7 @@ make_append(List *appendplans, bool isTarget, List *tlist)
 		if (plan->plan_width < subplan->plan_width)
 			plan->plan_width = subplan->plan_width;
 	}
+
 	plan->targetlist = tlist;
 	plan->qual = NIL;
 	plan->lefttree = NULL;
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 9e919079ccf9c2d6d1f18ee34c6bb2a70259826e..19198bf2494c88c2495b1d2999e6f22b187bc296 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.91 2003/06/29 23:05:04 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.92 2003/07/14 22:35:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -686,9 +686,7 @@ create_subqueryscan_path(RelOptInfo *rel, List *pathkeys)
 	pathnode->parent = rel;
 	pathnode->pathkeys = pathkeys;
 
-	/* just copy the subplan's cost estimates */
-	pathnode->startup_cost = rel->subplan->startup_cost;
-	pathnode->total_cost = rel->subplan->total_cost;
+	cost_subqueryscan(pathnode, rel);
 
 	return pathnode;
 }
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index 45c83191a2691ff2e34b74ccb8d702cbb6ca8399..ad2122f46e70f9d21f2543d77c42e34ce8daae64 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: cost.h,v 1.53 2003/06/11 15:01:15 momjian Exp $
+ * $Id: cost.h,v 1.54 2003/07/14 22:35:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -56,6 +56,7 @@ extern void cost_index(Path *path, Query *root,
 		   List *indexQuals, bool is_injoin);
 extern void cost_tidscan(Path *path, Query *root,
 			 RelOptInfo *baserel, List *tideval);
+extern void cost_subqueryscan(Path *path, RelOptInfo *baserel);
 extern void cost_functionscan(Path *path, Query *root,
 				  RelOptInfo *baserel);
 extern void cost_sort(Path *path, Query *root,