List *total_subpaths = NIL;
List *fractional_subpaths = NIL;
bool startup_neq_total = false;
- ListCell *lcr;
bool match_partition_order;
bool match_partition_order_desc;
+ int end_index;
+ int first_index;
+ int direction;
/*
* Determine if this sort ordering matches any partition pathkeys we
(!partition_pathkeys_desc_partial &&
pathkeys_contained_in(partition_pathkeys_desc, pathkeys)));
+ /*
+ * When the required pathkeys match the reverse of the partition
+ * order, we must build the list of paths in reverse starting with the
+ * last matching partition first. We can get away without making any
+ * special cases for this in the loop below by just looping backward
+ * over the child relations in this case.
+ */
+ if (match_partition_order_desc)
+ {
+ /* loop backward */
+ first_index = list_length(live_childrels) - 1;
+ end_index = -1;
+ direction = -1;
+
+ /*
+ * Set this to true to save us having to check for
+ * match_partition_order_desc in the loop below.
+ */
+ match_partition_order = true;
+ }
+ else
+ {
+ /* for all other case, loop forward */
+ first_index = 0;
+ end_index = list_length(live_childrels);
+ direction = 1;
+ }
+
/* Select the child paths for this ordering... */
- foreach(lcr, live_childrels)
+ for (int i = first_index; i != end_index; i += direction)
{
- RelOptInfo *childrel = (RelOptInfo *) lfirst(lcr);
+ RelOptInfo *childrel = list_nth_node(RelOptInfo, live_childrels, i);
Path *cheapest_startup,
*cheapest_total,
*cheapest_fractional = NULL;
fractional_subpaths = lappend(fractional_subpaths, cheapest_fractional);
}
}
- else if (match_partition_order_desc)
- {
- /*
- * As above, but we need to reverse the order of the children,
- * because nodeAppend.c doesn't know anything about reverse
- * ordering and will scan the children in the order presented.
- */
- cheapest_startup = get_singleton_append_subpath(cheapest_startup);
- cheapest_total = get_singleton_append_subpath(cheapest_total);
-
- startup_subpaths = lcons(cheapest_startup, startup_subpaths);
- total_subpaths = lcons(cheapest_total, total_subpaths);
-
- if (cheapest_fractional)
- {
- cheapest_fractional = get_singleton_append_subpath(cheapest_fractional);
- fractional_subpaths = lcons(cheapest_fractional, fractional_subpaths);
- }
- }
else
{
/*
}
/* ... and build the Append or MergeAppend paths */
- if (match_partition_order || match_partition_order_desc)
+ if (match_partition_order)
{
/* We only need Append */
add_path(rel, (Path *) create_append_path(root,