Index: costsize.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/optimizer/path/costsize.c,v
retrieving revision 1.115.2.1
diff -c -r1.115.2.1 costsize.c
*** costsize.c	3 Dec 2003 17:45:36 -0000	1.115.2.1
--- costsize.c	6 Apr 2004 18:41:17 -0000
***************
*** 928,950 ****
  	 * all mergejoin paths associated with the merge clause, we cache the
  	 * results in the RestrictInfo node.
  	 */
! 	firstclause = (RestrictInfo *) lfirst(mergeclauses);
! 	if (firstclause->left_mergescansel < 0)		/* not computed yet? */
! 		mergejoinscansel(root, (Node *) firstclause->clause,
! 						 &firstclause->left_mergescansel,
! 						 &firstclause->right_mergescansel);
! 
! 	if (bms_is_subset(firstclause->left_relids, outer_path->parent->relids))
  	{
! 		/* left side of clause is outer */
! 		outerscansel = firstclause->left_mergescansel;
! 		innerscansel = firstclause->right_mergescansel;
  	}
  	else
  	{
! 		/* left side of clause is inner */
! 		outerscansel = firstclause->right_mergescansel;
! 		innerscansel = firstclause->left_mergescansel;
  	}
  
  	/* convert selectivity to row count; must scan at least one row */
--- 928,958 ----
  	 * all mergejoin paths associated with the merge clause, we cache the
  	 * results in the RestrictInfo node.
  	 */
! 	if (mergeclauses)
  	{
! 		firstclause = (RestrictInfo *) lfirst(mergeclauses);
! 		if (firstclause->left_mergescansel < 0)	/* not computed yet? */
! 			mergejoinscansel(root, (Node *) firstclause->clause,
! 							 &firstclause->left_mergescansel,
! 							 &firstclause->right_mergescansel);
! 
! 		if (bms_is_subset(firstclause->left_relids, outer_path->parent->relids))
! 		{
! 			/* left side of clause is outer */
! 			outerscansel = firstclause->left_mergescansel;
! 			innerscansel = firstclause->right_mergescansel;
! 		}
! 		else
! 		{
! 			/* left side of clause is inner */
! 			outerscansel = firstclause->right_mergescansel;
! 			innerscansel = firstclause->left_mergescansel;
! 		}
  	}
  	else
  	{
! 		/* cope with clauseless mergejoin */
! 		outerscansel = innerscansel = 1.0;
  	}
  
  	/* convert selectivity to row count; must scan at least one row */
Index: joinpath.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/optimizer/path/joinpath.c,v
retrieving revision 1.82
diff -c -r1.82 joinpath.c
*** joinpath.c	25 Sep 2003 06:58:00 -0000	1.82
--- joinpath.c	6 Apr 2004 18:41:18 -0000
***************
*** 489,497 ****
  													  outerpath->pathkeys,
  													  mergeclause_list);
  
! 		/* Done with this outer path if no chance for a mergejoin */
  		if (mergeclauses == NIL)
! 			continue;
  		if (useallclauses && length(mergeclauses) != length(mergeclause_list))
  			continue;
  
--- 489,515 ----
  													  outerpath->pathkeys,
  													  mergeclause_list);
  
! 		/*
! 		 * Done with this outer path if no chance for a mergejoin.
! 		 *
! 		 * Special corner case: for "x FULL JOIN y ON true", there will be
! 		 * no join clauses at all.  Ordinarily we'd generate a clauseless
! 		 * nestloop path, but since mergejoin is our only join type that
! 		 * supports FULL JOIN, it's necessary to generate a clauseless
! 		 * mergejoin path instead.
! 		 *
! 		 * Unfortunately this can't easily be extended to handle the case
! 		 * where there are joinclauses but none of them use mergejoinable
! 		 * operators; nodeMergejoin.c can only do a full join correctly if
! 		 * all the joinclauses are mergeclauses.
! 		 */
  		if (mergeclauses == NIL)
! 		{
! 			if (jointype == JOIN_FULL && restrictlist == NIL)
! 				/* okay to try for mergejoin */ ;
! 			else
! 				continue;
! 		}
  		if (useallclauses && length(mergeclauses) != length(mergeclause_list))
  			continue;
  
