+ /*
+ * Next, build MergeAppend paths based on the collected list of child
+ * pathkeys. We consider both cheapest-startup and cheapest-total
+ * cases, ie, for each interesting ordering, collect all the cheapest
+ * startup subpaths and all the cheapest total paths, and build a
+ * MergeAppend path for each list.
+ */
+ foreach(l, all_child_pathkeys)
+ {
+ List *pathkeys = (List *) lfirst(l);
+ List *startup_subpaths = NIL;
+ List *total_subpaths = NIL;
+ bool startup_neq_total = false;
+ ListCell *lcr;
+
+ /* Select the child paths for this ordering... */
+ foreach(lcr, live_childrels)
+ {
+ RelOptInfo *childrel = (RelOptInfo *) lfirst(lcr);
+ Path *cheapest_startup,
+ *cheapest_total;
+
+ /* Locate the right paths, if they are available. */
+ cheapest_startup =
+ get_cheapest_path_for_pathkeys(childrel->pathlist,
+ pathkeys,
+ STARTUP_COST);
+ cheapest_total =
+ get_cheapest_path_for_pathkeys(childrel->pathlist,
+ pathkeys,
+ TOTAL_COST);
+
+ /*
+ * If we can't find any paths with the right order just add the
+ * cheapest-total path; we'll have to sort it.
+ */
+ if (cheapest_startup == NULL)
+ cheapest_startup = childrel->cheapest_total_path;
+ if (cheapest_total == NULL)
+ cheapest_total = childrel->cheapest_total_path;
+
+ /*
+ * Notice whether we actually have different paths for the
+ * "cheapest" and "total" cases; frequently there will be no
+ * point in two create_merge_append_path() calls.
+ */
+ if (cheapest_startup != cheapest_total)
+ startup_neq_total = true;
+
+ startup_subpaths =
+ accumulate_append_subpath(startup_subpaths, cheapest_startup);
+ total_subpaths =
+ accumulate_append_subpath(total_subpaths, cheapest_total);
+ }
+
+ /* ... and build the MergeAppend paths */
+ add_path(rel, (Path *) create_merge_append_path(root,
+ rel,
+ startup_subpaths,
+ pathkeys));
+ if (startup_neq_total)
+ add_path(rel, (Path *) create_merge_append_path(root,
+ rel,
+ total_subpaths,
+ pathkeys));
+ }
+
+ /* Select cheapest path */