aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
authorDavid Rowley <drowley@postgresql.org>2022-07-13 14:02:20 +1200
committerDavid Rowley <drowley@postgresql.org>2022-07-13 14:02:20 +1200
commit4cc832f94a583146fcf7886c9ce685894956d804 (patch)
tree442437fe5ae7c83831d0eb255632a6960c50ddf8 /src/backend/optimizer
parent83f1c7b742e80d5aa15e6710ecb324e388d007b3 (diff)
downloadpostgresql-4cc832f94a583146fcf7886c9ce685894956d804.tar.gz
postgresql-4cc832f94a583146fcf7886c9ce685894956d804.zip
Tidy up code in get_cheapest_group_keys_order()
There are a few things that we could do a little better within get_cheapest_group_keys_order(): 1. We should be using list_free() rather than pfree() on a List. 2. We should use for_each_from() instead of manually coding a for loop to skip the first n elements of a List 3. list_truncate(list_copy(...), n) is not a great way to copy the first n elements of a list. Let's invent list_copy_head() for that. That way we don't need to copy the entire list just to truncate it directly afterwards. 4. We can simplify finding the cheapest cost by setting the cheapest cost variable to DBL_MAX. That allows us to skip special-casing the initial iteration of the loop. Author: David Rowley Discussion: https://postgr.es/m/CAApHDvrGyL3ft8waEkncG9y5HDMu5TFFJB1paoTC8zi9YK97Nw@mail.gmail.com Backpatch-through: 15, where get_cheapest_group_keys_order was added.
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/path/pathkeys.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c
index 9775c4a7225..985b5d8de9b 100644
--- a/src/backend/optimizer/path/pathkeys.c
+++ b/src/backend/optimizer/path/pathkeys.c
@@ -17,6 +17,8 @@
*/
#include "postgres.h"
+#include <float.h>
+
#include "miscadmin.h"
#include "access/stratnum.h"
#include "catalog/pg_opfamily.h"
@@ -591,7 +593,7 @@ get_cheapest_group_keys_order(PlannerInfo *root, double nrows,
ListCell *cell;
PathkeyMutatorState mstate;
- double cheapest_sort_cost = -1.0;
+ double cheapest_sort_cost = DBL_MAX;
int nFreeKeys;
int nToPermute;
@@ -620,23 +622,23 @@ get_cheapest_group_keys_order(PlannerInfo *root, double nrows,
nToPermute = 4;
if (nFreeKeys > nToPermute)
{
- int i;
PathkeySortCost *costs = palloc(sizeof(PathkeySortCost) * nFreeKeys);
+ PathkeySortCost *cost = costs;
- /* skip the pre-ordered pathkeys */
- cell = list_nth_cell(*group_pathkeys, n_preordered);
-
- /* estimate cost for sorting individual pathkeys */
- for (i = 0; cell != NULL; i++, (cell = lnext(*group_pathkeys, cell)))
+ /*
+ * Estimate cost for sorting individual pathkeys skipping the
+ * pre-ordered pathkeys.
+ */
+ for_each_from(cell, *group_pathkeys, n_preordered)
{
- List *to_cost = list_make1(lfirst(cell));
-
- Assert(i < nFreeKeys);
+ PathKey *pathkey = (PathKey *) lfirst(cell);
+ List *to_cost = list_make1(pathkey);
- costs[i].pathkey = lfirst(cell);
- costs[i].cost = cost_sort_estimate(root, to_cost, 0, nrows);
+ cost->pathkey = pathkey;
+ cost->cost = cost_sort_estimate(root, to_cost, 0, nrows);
+ cost++;
- pfree(to_cost);
+ list_free(to_cost);
}
/* sort the pathkeys by sort cost in ascending order */
@@ -646,9 +648,9 @@ get_cheapest_group_keys_order(PlannerInfo *root, double nrows,
* Rebuild the list of pathkeys - first the preordered ones, then the
* rest ordered by cost.
*/
- new_group_pathkeys = list_truncate(list_copy(*group_pathkeys), n_preordered);
+ new_group_pathkeys = list_copy_head(*group_pathkeys, n_preordered);
- for (i = 0; i < nFreeKeys; i++)
+ for (int i = 0; i < nFreeKeys; i++)
new_group_pathkeys = lappend(new_group_pathkeys, costs[i].pathkey);
pfree(costs);
@@ -689,7 +691,7 @@ get_cheapest_group_keys_order(PlannerInfo *root, double nrows,
cost = cost_sort_estimate(root, var_group_pathkeys, n_preordered, nrows);
- if (cost < cheapest_sort_cost || cheapest_sort_cost < 0)
+ if (cost < cheapest_sort_cost)
{
list_free(new_group_pathkeys);
new_group_pathkeys = list_copy(var_group_pathkeys);