get_cheapest_path_for_pathkeys(childrel->pathlist,
                                                                                           pathkeys,
                                                                                           NULL,
-                                                                                          STARTUP_COST);
+                                                                                          STARTUP_COST,
+                                                                                          false);
                        cheapest_total =
                                get_cheapest_path_for_pathkeys(childrel->pathlist,
                                                                                           pathkeys,
                                                                                           NULL,
-                                                                                          TOTAL_COST);
+                                                                                          TOTAL_COST,
+                                                                                          false);
 
                        /*
                         * If we can't find any paths with the right order just use the
        cheapest = get_cheapest_path_for_pathkeys(rel->pathlist,
                                                                                          NIL,
                                                                                          required_outer,
-                                                                                         TOTAL_COST);
+                                                                                         TOTAL_COST,
+                                                                                         false);
        Assert(cheapest != NULL);
        if (bms_equal(PATH_REQ_OUTER(cheapest), required_outer))
                return cheapest;
 
                innerpath = get_cheapest_path_for_pathkeys(innerrel->pathlist,
                                                                                                   trialsortkeys,
                                                                                                   NULL,
-                                                                                                  TOTAL_COST);
+                                                                                                  TOTAL_COST,
+                                                                                                  false);
                if (innerpath != NULL &&
                        (cheapest_total_inner == NULL ||
                         compare_path_costs(innerpath, cheapest_total_inner,
                innerpath = get_cheapest_path_for_pathkeys(innerrel->pathlist,
                                                                                                   trialsortkeys,
                                                                                                   NULL,
-                                                                                                  STARTUP_COST);
+                                                                                                  STARTUP_COST,
+                                                                                                  false);
                if (innerpath != NULL &&
                        (cheapest_startup_inner == NULL ||
                         compare_path_costs(innerpath, cheapest_startup_inner,
                        if (cheapest_total_inner->parallel_safe)
                                cheapest_safe_inner = cheapest_total_inner;
                        else if (save_jointype != JOIN_UNIQUE_INNER)
-                       {
-                               ListCell   *lc;
-
-                               foreach(lc, innerrel->pathlist)
-                               {
-                                       Path       *innerpath = (Path *) lfirst(lc);
-
-                                       if (innerpath->parallel_safe &&
-                                               bms_is_empty(PATH_REQ_OUTER(innerpath)))
-                                       {
-                                               cheapest_safe_inner = innerpath;
-                                               break;
-                                       }
-                               }
-                       }
+                               cheapest_safe_inner =
+                                       get_cheapest_parallel_safe_total_inner(innerrel->pathlist);
 
                        if (cheapest_safe_inner != NULL)
                                try_partial_hashjoin_path(root, joinrel,
 
  * 'pathkeys' represents a required ordering (in canonical form!)
  * 'required_outer' denotes allowable outer relations for parameterized paths
  * 'cost_criterion' is STARTUP_COST or TOTAL_COST
+ * 'require_parallel_safe' causes us to consider only parallel-safe paths
  */
 Path *
 get_cheapest_path_for_pathkeys(List *paths, List *pathkeys,
                                                           Relids required_outer,
-                                                          CostSelector cost_criterion)
+                                                          CostSelector cost_criterion,
+                                                          bool require_parallel_safe)
 {
        Path       *matched_path = NULL;
        ListCell   *l;
                        compare_path_costs(matched_path, path, cost_criterion) <= 0)
                        continue;
 
+               if (require_parallel_safe && !path->parallel_safe)
+                       continue;
+
                if (pathkeys_contained_in(pathkeys, path->pathkeys) &&
                        bms_is_subset(PATH_REQ_OUTER(path), required_outer))
                        matched_path = path;
        return matched_path;
 }
 
+
+/*
+ * get_cheapest_parallel_safe_total_inner
+ *       Find the unparameterized parallel-safe path with the least total cost.
+ */
+Path *
+get_cheapest_parallel_safe_total_inner(List *paths)
+{
+       ListCell   *l;
+
+       foreach(l, paths)
+       {
+               Path       *innerpath = (Path *) lfirst(l);
+
+               if (innerpath->parallel_safe &&
+                       bms_is_empty(PATH_REQ_OUTER(innerpath)))
+                       return innerpath;
+       }
+
+       return NULL;
+}
+
 /****************************************************************************
  *             NEW PATHKEY FORMATION
  ****************************************************************************/
 
 extern bool pathkeys_contained_in(List *keys1, List *keys2);
 extern Path *get_cheapest_path_for_pathkeys(List *paths, List *pathkeys,
                                                           Relids required_outer,
-                                                          CostSelector cost_criterion);
+                                                          CostSelector cost_criterion,
+                                                          bool require_parallel_safe);
 extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths,
                                                                                  List *pathkeys,
                                                                                  Relids required_outer,
                                                                                  double fraction);
+extern Path *get_cheapest_parallel_safe_total_inner(List *paths);
 extern List *build_index_pathkeys(PlannerInfo *root, IndexOptInfo *index,
                                         ScanDirection scandir);
 extern List *build_expression_pathkey(PlannerInfo *root, Expr *expr,