From ad511a3ff352e2b6ef94791bb27b4b670a8dcb96 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun, 11 Nov 2001 19:18:54 +0000
Subject: [PATCH] sort_inner_and_outer needs a check to ensure that it's
 consumed all the mergeclauses in RIGHT/FULL join cases, just like the other
 routines have. I'm not quite sure why I thought it didn't need one --- but
 Nick Fankhauser's recent bug report proves that it does.

---
 src/backend/optimizer/path/joinpath.c | 29 ++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 15bb56757d1..4d60569e7ef 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.66 2001/10/25 05:49:32 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.67 2001/11/11 19:18:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -150,9 +150,31 @@ sort_inner_and_outer(Query *root,
 					 List *mergeclause_list,
 					 JoinType jointype)
 {
+	bool		useallclauses;
 	List	   *all_pathkeys;
 	List	   *i;
 
+	/*
+	 * If we are doing a right or full join, we must use *all* the
+	 * mergeclauses as join clauses, else we will not have a valid plan.
+	 */
+	switch (jointype)
+	{
+		case JOIN_INNER:
+		case JOIN_LEFT:
+			useallclauses = false;
+			break;
+		case JOIN_RIGHT:
+		case JOIN_FULL:
+			useallclauses = true;
+			break;
+		default:
+			elog(ERROR, "sort_inner_and_outer: unexpected join type %d",
+				 (int) jointype);
+			useallclauses = false;	/* keep compiler quiet */
+			break;
+	}
+
 	/*
 	 * Each possible ordering of the available mergejoin clauses will
 	 * generate a differently-sorted result path at essentially the same
@@ -212,6 +234,11 @@ sort_inner_and_outer(Query *root,
 													   mergeclause_list);
 		Assert(cur_mergeclauses != NIL);
 
+		/* Forget it if can't use all the clauses in right/full join */
+		if (useallclauses &&
+			length(cur_mergeclauses) != length(mergeclause_list))
+			continue;
+
 		/*
 		 * Build sort pathkeys for both sides.
 		 *
-- 
GitLab