1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-07 00:36:50 +03:00

Fix asymmetry in setting EquivalenceClass.ec_sortref

0452b461bc made get_eclass_for_sort_expr() always set
EquivalenceClass.ec_sortref if it's not done yet.  This leads to an asymmetric
situation when whoever first looks for the EquivalenceClass sets the
ec_sortref.  It is also counterintuitive that get_eclass_for_sort_expr()
performs modification of data structures.

This commit makes make_pathkeys_for_sortclauses_extended() responsible for
setting EquivalenceClass.ec_sortref.  Now we set the
EquivalenceClass.ec_sortref's needed to explore alternative GROUP BY ordering
specifically during building pathkeys by the list of grouping clauses.

Discussion: https://postgr.es/m/17037754-f187-4138-8285-0e2bfebd0dea%40postgrespro.ru
Reported-by: Tom Lane
Author: Andrei Lepikhov
Reviewed-by: Alexander Korotkov, Pavel Borisov
This commit is contained in:
Alexander Korotkov
2024-06-06 13:41:34 +03:00
parent f654f000dd
commit 199012a3d8
6 changed files with 92 additions and 19 deletions

View File

@ -652,18 +652,7 @@ get_eclass_for_sort_expr(PlannerInfo *root,
if (opcintype == cur_em->em_datatype &&
equal(expr, cur_em->em_expr))
{
/*
* Match!
*
* Copy the sortref if it wasn't set yet. That may happen if
* the ec was constructed from a WHERE clause, i.e. it doesn't
* have a target reference at all.
*/
if (cur_ec->ec_sortref == 0 && sortref > 0)
cur_ec->ec_sortref = sortref;
return cur_ec;
}
return cur_ec; /* Match! */
}
}

View File

@ -1355,7 +1355,8 @@ make_pathkeys_for_sortclauses(PlannerInfo *root,
&sortclauses,
tlist,
false,
&sortable);
&sortable,
false);
/* It's caller error if not all clauses were sortable */
Assert(sortable);
return result;
@ -1379,13 +1380,17 @@ make_pathkeys_for_sortclauses(PlannerInfo *root,
* to remove any clauses that can be proven redundant via the eclass logic.
* Even though we'll have to hash in that case, we might as well not hash
* redundant columns.)
*
* If set_ec_sortref is true then sets the value of the pathkey's
* EquivalenceClass unless it's already initialized.
*/
List *
make_pathkeys_for_sortclauses_extended(PlannerInfo *root,
List **sortclauses,
List *tlist,
bool remove_redundant,
bool *sortable)
bool *sortable,
bool set_ec_sortref)
{
List *pathkeys = NIL;
ListCell *l;
@ -1409,6 +1414,15 @@ make_pathkeys_for_sortclauses_extended(PlannerInfo *root,
sortcl->nulls_first,
sortcl->tleSortGroupRef,
true);
if (pathkey->pk_eclass->ec_sortref == 0 && set_ec_sortref)
{
/*
* Copy the sortref if it hasn't been set yet. That may happen if
* the EquivalenceClass was constructed from a WHERE clause, i.e.
* it doesn't have a target reference at all.
*/
pathkey->pk_eclass->ec_sortref = sortcl->tleSortGroupRef;
}
/* Canonical form eliminates redundant ordering keys */
if (!pathkey_is_redundant(pathkey, pathkeys))

View File

@ -3395,12 +3395,17 @@ standard_qp_callback(PlannerInfo *root, void *extra)
*/
bool sortable;
/*
* Convert group clauses into pathkeys. Set the ec_sortref field of
* EquivalenceClass'es if it's not set yet.
*/
root->group_pathkeys =
make_pathkeys_for_sortclauses_extended(root,
&root->processed_groupClause,
tlist,
true,
&sortable);
&sortable,
true);
if (!sortable)
{
/* Can't sort; no point in considering aggregate ordering either */
@ -3450,7 +3455,8 @@ standard_qp_callback(PlannerInfo *root, void *extra)
&root->processed_distinctClause,
tlist,
true,
&sortable);
&sortable,
false);
if (!sortable)
root->distinct_pathkeys = NIL;
}
@ -3476,7 +3482,8 @@ standard_qp_callback(PlannerInfo *root, void *extra)
&groupClauses,
tlist,
false,
&sortable);
&sortable,
false);
if (!sortable)
root->setop_pathkeys = NIL;
}
@ -6061,7 +6068,8 @@ make_pathkeys_for_window(PlannerInfo *root, WindowClause *wc,
&wc->partitionClause,
tlist,
true,
&sortable);
&sortable,
false);
Assert(sortable);
}