diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c index 1597b8e8127..cb686691bd9 100644 --- a/src/backend/nodes/list.c +++ b/src/backend/nodes/list.c @@ -1655,6 +1655,37 @@ list_copy_deep(const List *oldlist) return newlist; } +/* + * Reverses the order of 'list' elements in place and returns the input list + */ +List * +list_reverse(List *list) +{ + ListCell *head; + ListCell *tail; + + if (list == NIL) + return NIL; + + head = &list->elements[0]; + tail = &list->elements[list->length - 1]; + + while (head < tail) + { + ListCell tmp; + + /* Swap data at the head and tail position */ + memcpy(&tmp, head, sizeof(ListCell)); + memcpy(head, tail, sizeof(ListCell)); + memcpy(tail, &tmp, sizeof(ListCell)); + + head++; + tail--; + } + + return list; +} + /* * Sort a list according to the specified comparator function. * diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 6cc6966b060..a6ca409ac63 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1523,7 +1523,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, * if we have zero or one live subpath due to constraint exclusion.) */ if (subpaths_valid) - add_path(rel, (Path *) create_append_path(root, rel, subpaths, NIL, + add_path(rel, (Path *) create_append_path(root, rel, list_reverse(subpaths), NIL, NIL, NULL, 0, false, -1)); diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h index 4d1cdbbcfdd..413549d8c3e 100644 --- a/src/include/nodes/pg_list.h +++ b/src/include/nodes/pg_list.h @@ -677,6 +677,8 @@ pg_nodiscard extern List *list_copy_head(const List *oldlist, int len); pg_nodiscard extern List *list_copy_tail(const List *oldlist, int nskip); pg_nodiscard extern List *list_copy_deep(const List *oldlist); +extern List *list_reverse(List *list); + typedef int (*list_sort_comparator) (const ListCell *a, const ListCell *b); extern void list_sort(List *list, list_sort_comparator cmp);