diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index cdb18d9..324c8c1 100644
*** a/src/backend/optimizer/path/costsize.c
--- b/src/backend/optimizer/path/costsize.c
*************** final_cost_nestloop(PlannerInfo *root, N
*** 2287,2306 ****
  			 * difficult to estimate whether that will happen (and it could
  			 * not happen if there are any unmatched outer rows!), so be
  			 * conservative and always charge the whole first-scan cost once.
  			 */
  			run_cost += inner_run_cost;
  
  			/* Add inner run cost for additional outer tuples having matches */
! 			if (outer_matched_rows > 1)
! 				run_cost += (outer_matched_rows - 1) * inner_rescan_run_cost * inner_scan_frac;
! 
! 			/* Add inner run cost for unmatched outer tuples */
! 			run_cost += (outer_path_rows - outer_matched_rows) *
! 				inner_rescan_run_cost;
  
! 			/* And count the unmatched join tuples as being processed */
! 			ntuples += (outer_path_rows - outer_matched_rows) *
! 				inner_path_rows;
  		}
  	}
  	else
--- 2287,2317 ----
  			 * difficult to estimate whether that will happen (and it could
  			 * not happen if there are any unmatched outer rows!), so be
  			 * conservative and always charge the whole first-scan cost once.
+ 			 * We consider this charge to correspond to the first unmatched
+ 			 * outer row, unless there isn't one in our estimate, in which
+ 			 * case blame it on the first matched row.
  			 */
+ 			double		outer_unmatched_rows;
+ 
+ 			outer_unmatched_rows = outer_path_rows - outer_matched_rows;
+ 
+ 			/* While at it, count unmatched join tuples as being processed */
+ 			ntuples += outer_unmatched_rows * inner_path_rows;
+ 
+ 			/* Now add the forced full scan, and decrement appropriate count */
  			run_cost += inner_run_cost;
+ 			if (outer_unmatched_rows >= 1)
+ 				outer_unmatched_rows -= 1;
+ 			else
+ 				outer_matched_rows -= 1;
  
  			/* Add inner run cost for additional outer tuples having matches */
! 			if (outer_matched_rows > 0)
! 				run_cost += outer_matched_rows * inner_rescan_run_cost * inner_scan_frac;
  
! 			/* Add inner run cost for additional unmatched outer tuples */
! 			if (outer_unmatched_rows > 0)
! 				run_cost += outer_unmatched_rows * inner_rescan_run_cost;
  		}
  	}
  	else
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index d08b1e1..9cad4e6 100644
*** a/src/test/regress/expected/join.out
--- b/src/test/regress/expected/join.out
*************** select * from j1 natural join j2;
*** 5476,5523 ****
  explain (verbose, costs off)
  select * from j1
  inner join (select distinct id from j3) j3 on j1.id = j3.id;
!                   QUERY PLAN                   
! -----------------------------------------------
   Nested Loop
     Output: j1.id, j3.id
     Inner Unique: true
     Join Filter: (j1.id = j3.id)
!    ->  Seq Scan on public.j1
!          Output: j1.id
!    ->  Materialize
           Output: j3.id
!          ->  Unique
                 Output: j3.id
!                ->  Sort
                       Output: j3.id
!                      Sort Key: j3.id
!                      ->  Seq Scan on public.j3
!                            Output: j3.id
! (15 rows)
  
  -- ensure group by clause allows the inner to become unique
  explain (verbose, costs off)
  select * from j1
  inner join (select id from j3 group by id) j3 on j1.id = j3.id;
!                   QUERY PLAN                   
! -----------------------------------------------
   Nested Loop
     Output: j1.id, j3.id
     Inner Unique: true
     Join Filter: (j1.id = j3.id)
!    ->  Seq Scan on public.j1
!          Output: j1.id
!    ->  Materialize
           Output: j3.id
!          ->  Group
                 Output: j3.id
!                Group Key: j3.id
!                ->  Sort
                       Output: j3.id
!                      Sort Key: j3.id
!                      ->  Seq Scan on public.j3
!                            Output: j3.id
! (16 rows)
  
  drop table j1;
  drop table j2;
--- 5476,5519 ----
  explain (verbose, costs off)
  select * from j1
  inner join (select distinct id from j3) j3 on j1.id = j3.id;
!                QUERY PLAN                
! -----------------------------------------
   Nested Loop
     Output: j1.id, j3.id
     Inner Unique: true
     Join Filter: (j1.id = j3.id)
!    ->  Unique
           Output: j3.id
!          ->  Sort
                 Output: j3.id
!                Sort Key: j3.id
!                ->  Seq Scan on public.j3
                       Output: j3.id
!    ->  Seq Scan on public.j1
!          Output: j1.id
! (13 rows)
  
  -- ensure group by clause allows the inner to become unique
  explain (verbose, costs off)
  select * from j1
  inner join (select id from j3 group by id) j3 on j1.id = j3.id;
!                QUERY PLAN                
! -----------------------------------------
   Nested Loop
     Output: j1.id, j3.id
     Inner Unique: true
     Join Filter: (j1.id = j3.id)
!    ->  Group
           Output: j3.id
!          Group Key: j3.id
!          ->  Sort
                 Output: j3.id
!                Sort Key: j3.id
!                ->  Seq Scan on public.j3
                       Output: j3.id
!    ->  Seq Scan on public.j1
!          Output: j1.id
! (14 rows)
  
  drop table j1;
  drop table j2;
*************** inner join j2 on j1.id1 = j2.id1 and j1.
*** 5558,5570 ****
     Output: j1.id1, j1.id2, j2.id1, j2.id2
     Inner Unique: true
     Join Filter: ((j1.id1 = j2.id1) AND (j1.id2 = j2.id2))
     ->  Seq Scan on public.j1
           Output: j1.id1, j1.id2
!    ->  Materialize
!          Output: j2.id1, j2.id2
!          ->  Seq Scan on public.j2
!                Output: j2.id1, j2.id2
! (10 rows)
  
  -- ensure we don't detect the join to be unique when quals are not part of the
  -- join condition
--- 5554,5564 ----
     Output: j1.id1, j1.id2, j2.id1, j2.id2
     Inner Unique: true
     Join Filter: ((j1.id1 = j2.id1) AND (j1.id2 = j2.id2))
+    ->  Seq Scan on public.j2
+          Output: j2.id1, j2.id2
     ->  Seq Scan on public.j1
           Output: j1.id1, j1.id2
! (8 rows)
  
  -- ensure we don't detect the join to be unique when quals are not part of the
  -- join condition
