RelOptInfo *innerrel,
                         List *restrictlist,
                         JoinType jointype,
-                        bool *have_nonmergeable_clause);
+                        bool *mergejoin_allowed);
 
 
 /*
                     List *restrictlist)
 {
    List       *mergeclause_list = NIL;
-   bool        have_nonmergeable_clause = false;
+   bool        mergejoin_allowed = true;
 
    /*
     * Find potential mergejoin clauses.  We can skip this if we are not
                                                    innerrel,
                                                    restrictlist,
                                                    jointype,
-                                                   &have_nonmergeable_clause);
+                                                   &mergejoin_allowed);
 
    /*
     * 1. Consider mergejoin paths where both relations must be explicitly
     * sorted.  Skip this if we can't mergejoin.
     */
-   if (!have_nonmergeable_clause)
+   if (mergejoin_allowed)
        sort_inner_and_outer(root, joinrel, outerrel, innerrel,
                             restrictlist, mergeclause_list, jointype, sjinfo);
 
     * sorted. This includes both nestloops and mergejoins where the outer
     * path is already ordered.  Again, skip this if we can't mergejoin.
     * (That's okay because we know that nestloop can't handle right/full
-    * joins at all, so it wouldn't work in those cases either.)
+    * joins at all, so it wouldn't work in the prohibited cases either.)
     */
-   if (!have_nonmergeable_clause)
+   if (mergejoin_allowed)
        match_unsorted_outer(root, joinrel, outerrel, innerrel,
                             restrictlist, mergeclause_list, jointype, sjinfo);
 
     * those made by match_unsorted_outer when add_paths_to_joinrel() is
     * invoked with the two rels given in the other order.
     */
-   if (!have_nonmergeable_clause)
+   if (mergejoin_allowed)
        match_unsorted_inner(root, joinrel, outerrel, innerrel,
                             restrictlist, mergeclause_list, jointype, sjinfo);
 #endif
  *   Select mergejoin clauses that are usable for a particular join.
  *   Returns a list of RestrictInfo nodes for those clauses.
  *
- * *have_nonmergeable_clause is set TRUE if this is a right/full join and
- * there are nonmergejoinable join clauses.  The executor's mergejoin
- * machinery cannot handle such cases, so we have to avoid generating a
- * mergejoin plan.
+ * *mergejoin_allowed is normally set to TRUE, but it is set to FALSE if
+ * this is a right/full join and there are nonmergejoinable join clauses.
+ * The executor's mergejoin machinery cannot handle such cases, so we have
+ * to avoid generating a mergejoin plan.  (Note that this flag does NOT
+ * consider whether there are actually any mergejoinable clauses.  This is
+ * correct because in some cases we need to build a clauseless mergejoin.
+ * Simply returning NIL is therefore not enough to distinguish safe from
+ * unsafe cases.)
  *
  * We also mark each selected RestrictInfo to show which side is currently
  * being considered as outer.  These are transient markings that are only
                         RelOptInfo *innerrel,
                         List *restrictlist,
                         JoinType jointype,
-                        bool *have_nonmergeable_clause)
+                        bool *mergejoin_allowed)
 {
    List       *result_list = NIL;
    bool        isouterjoin = IS_OUTER_JOIN(jointype);
+   bool        have_nonmergeable_joinclause = false;
    ListCell   *l;
 
-   *have_nonmergeable_clause = false;
-
    foreach(l, restrictlist)
    {
        RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
        /*
         * If processing an outer join, only use its own join clauses in the
         * merge.  For inner joins we can use pushed-down clauses too. (Note:
-        * we don't set have_nonmergeable_clause here because pushed-down
+        * we don't set have_nonmergeable_joinclause here because pushed-down
         * clauses will become otherquals not joinquals.)
         */
        if (isouterjoin && restrictinfo->is_pushed_down)
             * FALSE.)
             */
            if (!restrictinfo->clause || !IsA(restrictinfo->clause, Const))
-               *have_nonmergeable_clause = true;
+               have_nonmergeable_joinclause = true;
            continue;           /* not mergejoinable */
        }
 
         */
        if (!clause_sides_match_join(restrictinfo, outerrel, innerrel))
        {
-           *have_nonmergeable_clause = true;
+           have_nonmergeable_joinclause = true;
            continue;           /* no good for these input relations */
        }
 
        if (EC_MUST_BE_REDUNDANT(restrictinfo->left_ec) ||
            EC_MUST_BE_REDUNDANT(restrictinfo->right_ec))
        {
-           *have_nonmergeable_clause = true;
+           have_nonmergeable_joinclause = true;
            continue;           /* can't handle redundant eclasses */
        }
 
    }
 
    /*
-    * If it is not a right/full join then we don't need to insist on all the
-    * joinclauses being mergejoinable, so reset the flag.  This simplifies
-    * the logic in add_paths_to_joinrel.
+    * Report whether mergejoin is allowed (see comment at top of function).
     */
    switch (jointype)
    {
        case JOIN_RIGHT:
        case JOIN_FULL:
+           *mergejoin_allowed = !have_nonmergeable_joinclause;
            break;
        default:
-           /* otherwise, it's OK to have nonmergeable join quals */
-           *have_nonmergeable_clause = false;
+           *mergejoin_allowed = true;
            break;
    }