This is an automated email from the ASF dual-hosted git repository.
chenjinbao1989 pushed a commit to branch cbdb-postgres-merge
in repository https://gitbox.apache.org/repos/asf/cloudberry.git
The following commit(s) were added to refs/heads/cbdb-postgres-merge by this
push:
new 813fb937388 Use if 0 to remove functions
813fb937388 is described below
commit 813fb937388c124689e3c780729a2e2f67c26b73
Author: Jinbao Chen <[email protected]>
AuthorDate: Fri Dec 26 23:09:00 2025 +0800
Use if 0 to remove functions
---
src/backend/optimizer/plan/planner.c | 484 ++++++++++++++++++-----------------
1 file changed, 247 insertions(+), 237 deletions(-)
diff --git a/src/backend/optimizer/plan/planner.c
b/src/backend/optimizer/plan/planner.c
index 4f0deaeefb4..5aaccef5423 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -3950,21 +3950,23 @@ reorder_grouping_sets(List *groupingSets, List
*sortclause)
* Returns true if any PathKey in 'keys' has an EquivalenceClass
* containing a volatile function. Otherwise returns false.
*/
-//static bool
-//has_volatile_pathkey(List *keys)
-//{
-// ListCell *lc;
-//
-// foreach(lc, keys)
-// {
-// PathKey *pathkey = lfirst_node(PathKey, lc);
-//
-// if (pathkey->pk_eclass->ec_has_volatile)
-// return true;
-// }
-//
-// return false;
-//}
+#if 0
+static bool
+has_volatile_pathkey(List *keys)
+{
+ ListCell *lc;
+
+ foreach(lc, keys)
+ {
+ PathKey *pathkey = lfirst_node(PathKey, lc);
+
+ if (pathkey->pk_eclass->ec_has_volatile)
+ return true;
+ }
+
+ return false;
+}
+#endif
/*
* adjust_group_pathkeys_for_groupagg
@@ -3995,226 +3997,228 @@ reorder_grouping_sets(List *groupingSets, List
*sortclause)
* query contains, we always force Aggrefs with volatile functions to perform
* their own sorts.
*/
-//static void
-//adjust_group_pathkeys_for_groupagg(PlannerInfo *root)
-//{
-// List *grouppathkeys = root->group_pathkeys;
-// List *bestpathkeys;
-// Bitmapset *bestaggs;
-// Bitmapset *unprocessed_aggs;
-// ListCell *lc;
-// int i;
-//
-// /* Shouldn't be here if there are grouping sets */
-// Assert(root->parse->groupingSets == NIL);
-// /* Shouldn't be here unless there are some ordered aggregates */
-// Assert(root->numOrderedAggs > 0);
-//
-// /* Do nothing if disabled */
-// if (!enable_presorted_aggregate)
-// return;
-//
-// /*
-// * Make a first pass over all AggInfos to collect a Bitmapset containing
-// * the indexes of all AggInfos to be processed below.
-// */
-// unprocessed_aggs = NULL;
-// foreach(lc, root->agginfos)
-// {
-// AggInfo *agginfo = lfirst_node(AggInfo, lc);
-// Aggref *aggref = linitial_node(Aggref, agginfo->aggrefs);
-//
-// if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
-// continue;
-//
-// /* Skip unless there's a DISTINCT or ORDER BY clause */
-// if (aggref->aggdistinct == NIL && aggref->aggorder == NIL)
-// continue;
-//
-// /* Additional safety checks are needed if there's a FILTER
clause */
-// if (aggref->aggfilter != NULL)
-// {
-// ListCell *lc2;
-// bool allow_presort = true;
-//
-// /*
-// * When the Aggref has a FILTER clause, it's possible
that the
-// * filter removes rows that cannot be sorted because the
-// * expression to sort by results in an error during its
-// * evaluation. This is a problem for presorting as
that happens
-// * before the FILTER, whereas without presorting, the
Aggregate
-// * node will apply the FILTER *before* sorting. So
that we never
-// * try to sort anything that might error, here we aim
to skip over
-// * any Aggrefs with arguments with expressions which,
when
-// * evaluated, could cause an ERROR. Vars and Consts
are ok. There
-// * may be more cases that should be allowed, but more
thought
-// * needs to be given. Err on the side of caution.
-// */
-// foreach(lc2, aggref->args)
-// {
-// TargetEntry *tle = (TargetEntry *) lfirst(lc2);
-// Expr *expr = tle->expr;
-//
-// while (IsA(expr, RelabelType))
-// expr = (Expr *) (castNode(RelabelType,
expr))->arg;
-//
-// /* Common case, Vars and Consts are ok */
-// if (IsA(expr, Var) || IsA(expr, Const))
-// continue;
-//
-// /* Unsupported. Don't try to presort for this
Aggref */
-// allow_presort = false;
-// break;
-// }
-//
-// /* Skip unsupported Aggrefs */
-// if (!allow_presort)
-// continue;
-// }
-//
-// unprocessed_aggs = bms_add_member(unprocessed_aggs,
-//
foreach_current_index(lc));
-// }
-//
-// /*
-// * Now process all the unprocessed_aggs to find the best set of pathkeys
-// * for the given set of aggregates.
-// *
-// * On the first outer loop here 'bestaggs' will be empty. We'll
populate
-// * this during the first loop using the pathkeys for the very first
-// * AggInfo then taking any stronger pathkeys from any other AggInfos
with
-// * a more strict set of compatible pathkeys. Once the outer loop is
-// * complete, we mark off all the aggregates with compatible pathkeys
then
-// * remove those from the unprocessed_aggs and repeat the process to try
to
-// * find another set of pathkeys that are suitable for a larger number of
-// * aggregates. The outer loop will stop when there are not enough
-// * unprocessed aggregates for it to be possible to find a set of
pathkeys
-// * to suit a larger number of aggregates.
-// */
-// bestpathkeys = NIL;
-// bestaggs = NULL;
-// while (bms_num_members(unprocessed_aggs) > bms_num_members(bestaggs))
-// {
-// Bitmapset *aggindexes = NULL;
-// List *currpathkeys = NIL;
-//
-// i = -1;
-// while ((i = bms_next_member(unprocessed_aggs, i)) >= 0)
-// {
-// AggInfo *agginfo = list_nth_node(AggInfo,
root->agginfos, i);
-// Aggref *aggref = linitial_node(Aggref,
agginfo->aggrefs);
-// List *sortlist;
-// List *pathkeys;
-//
-// if (aggref->aggdistinct != NIL)
-// sortlist = aggref->aggdistinct;
-// else
-// sortlist = aggref->aggorder;
-//
-// pathkeys = make_pathkeys_for_sortclauses(root, sortlist,
-//
aggref->args);
-//
-// /*
-// * Ignore Aggrefs which have volatile functions in
their ORDER BY
-// * or DISTINCT clause.
-// */
-// if (has_volatile_pathkey(pathkeys))
-// {
-// unprocessed_aggs =
bms_del_member(unprocessed_aggs, i);
-// continue;
-// }
-//
-// /*
-// * When not set yet, take the pathkeys from the first
unprocessed
-// * aggregate.
-// */
-// if (currpathkeys == NIL)
-// {
-// currpathkeys = pathkeys;
-//
-// /* include the GROUP BY pathkeys, if they exist
*/
-// if (grouppathkeys != NIL)
-// currpathkeys =
append_pathkeys(list_copy(grouppathkeys),
-//
currpathkeys);
-//
-// /* record that we found pathkeys for this
aggregate */
-// aggindexes = bms_add_member(aggindexes, i);
-// }
-// else
-// {
-// /* now look for a stronger set of matching
pathkeys */
-//
-// /* include the GROUP BY pathkeys, if they exist
*/
-// if (grouppathkeys != NIL)
-// pathkeys =
append_pathkeys(list_copy(grouppathkeys),
-//
pathkeys);
-//
-// /* are 'pathkeys' compatible or better than
'currpathkeys'? */
-// switch (compare_pathkeys(currpathkeys,
pathkeys))
-// {
-// case PATHKEYS_BETTER2:
-// /* 'pathkeys' are stronger, use
these ones instead */
-// currpathkeys = pathkeys;
-// /* FALLTHROUGH */
-//
-// case PATHKEYS_BETTER1:
-// /* 'pathkeys' are less strict */
-// /* FALLTHROUGH */
-//
-// case PATHKEYS_EQUAL:
-// /* mark this aggregate as
covered by 'currpathkeys' */
-// aggindexes =
bms_add_member(aggindexes, i);
-// break;
-//
-// case PATHKEYS_DIFFERENT:
-// break;
-// }
-// }
-// }
-//
-// /* remove the aggregates that we've just processed */
-// unprocessed_aggs = bms_del_members(unprocessed_aggs,
aggindexes);
-//
-// /*
-// * If this pass included more aggregates than the previous best
then
-// * use these ones as the best set.
-// */
-// if (bms_num_members(aggindexes) > bms_num_members(bestaggs))
-// {
-// bestaggs = aggindexes;
-// bestpathkeys = currpathkeys;
-// }
-// }
-//
-// /*
-// * If we found any ordered aggregates, update root->group_pathkeys to
add
-// * the best set of aggregate pathkeys. Note that bestpathkeys includes
-// * the original GROUP BY pathkeys already.
-// */
-// if (bestpathkeys != NIL)
-// root->group_pathkeys = bestpathkeys;
-//
-// /*
-// * Now that we've found the best set of aggregates we can set the
-// * presorted flag to indicate to the executor that it needn't bother
-// * performing a sort for these Aggrefs. We're able to do this now as
-// * there's no chance of a Hash Aggregate plan as create_grouping_paths
-// * will not mark the GROUP BY as GROUPING_CAN_USE_HASH due to the
presence
-// * of ordered aggregates.
-// */
-// i = -1;
-// while ((i = bms_next_member(bestaggs, i)) >= 0)
-// {
-// AggInfo *agginfo = list_nth_node(AggInfo, root->agginfos, i);
-//
-// foreach(lc, agginfo->aggrefs)
-// {
-// Aggref *aggref = lfirst_node(Aggref, lc);
-//
-// aggref->aggpresorted = true;
-// }
-// }
-//}
+#if 0
+static void
+adjust_group_pathkeys_for_groupagg(PlannerInfo *root)
+{
+ List *grouppathkeys = root->group_pathkeys;
+ List *bestpathkeys;
+ Bitmapset *bestaggs;
+ Bitmapset *unprocessed_aggs;
+ ListCell *lc;
+ int i;
+
+ /* Shouldn't be here if there are grouping sets */
+ Assert(root->parse->groupingSets == NIL);
+ /* Shouldn't be here unless there are some ordered aggregates */
+ Assert(root->numOrderedAggs > 0);
+
+ /* Do nothing if disabled */
+ if (!enable_presorted_aggregate)
+ return;
+
+ /*
+ * Make a first pass over all AggInfos to collect a Bitmapset containing
+ * the indexes of all AggInfos to be processed below.
+ */
+ unprocessed_aggs = NULL;
+ foreach(lc, root->agginfos)
+ {
+ AggInfo *agginfo = lfirst_node(AggInfo, lc);
+ Aggref *aggref = linitial_node(Aggref, agginfo->aggrefs);
+
+ if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
+ continue;
+
+ /* Skip unless there's a DISTINCT or ORDER BY clause */
+ if (aggref->aggdistinct == NIL && aggref->aggorder == NIL)
+ continue;
+
+ /* Additional safety checks are needed if there's a FILTER
clause */
+ if (aggref->aggfilter != NULL)
+ {
+ ListCell *lc2;
+ bool allow_presort = true;
+
+ /*
+ * When the Aggref has a FILTER clause, it's possible
that the
+ * filter removes rows that cannot be sorted because the
+ * expression to sort by results in an error during its
+ * evaluation. This is a problem for presorting as
that happens
+ * before the FILTER, whereas without presorting, the
Aggregate
+ * node will apply the FILTER *before* sorting. So
that we never
+ * try to sort anything that might error, here we aim
to skip over
+ * any Aggrefs with arguments with expressions which,
when
+ * evaluated, could cause an ERROR. Vars and Consts
are ok. There
+ * may be more cases that should be allowed, but more
thought
+ * needs to be given. Err on the side of caution.
+ */
+ foreach(lc2, aggref->args)
+ {
+ TargetEntry *tle = (TargetEntry *) lfirst(lc2);
+ Expr *expr = tle->expr;
+
+ while (IsA(expr, RelabelType))
+ expr = (Expr *) (castNode(RelabelType,
expr))->arg;
+
+ /* Common case, Vars and Consts are ok */
+ if (IsA(expr, Var) || IsA(expr, Const))
+ continue;
+
+ /* Unsupported. Don't try to presort for this
Aggref */
+ allow_presort = false;
+ break;
+ }
+
+ /* Skip unsupported Aggrefs */
+ if (!allow_presort)
+ continue;
+ }
+
+ unprocessed_aggs = bms_add_member(unprocessed_aggs,
+
foreach_current_index(lc));
+ }
+
+ /*
+ * Now process all the unprocessed_aggs to find the best set of pathkeys
+ * for the given set of aggregates.
+ *
+ * On the first outer loop here 'bestaggs' will be empty. We'll
populate
+ * this during the first loop using the pathkeys for the very first
+ * AggInfo then taking any stronger pathkeys from any other AggInfos
with
+ * a more strict set of compatible pathkeys. Once the outer loop is
+ * complete, we mark off all the aggregates with compatible pathkeys
then
+ * remove those from the unprocessed_aggs and repeat the process to try
to
+ * find another set of pathkeys that are suitable for a larger number of
+ * aggregates. The outer loop will stop when there are not enough
+ * unprocessed aggregates for it to be possible to find a set of
pathkeys
+ * to suit a larger number of aggregates.
+ */
+ bestpathkeys = NIL;
+ bestaggs = NULL;
+ while (bms_num_members(unprocessed_aggs) > bms_num_members(bestaggs))
+ {
+ Bitmapset *aggindexes = NULL;
+ List *currpathkeys = NIL;
+
+ i = -1;
+ while ((i = bms_next_member(unprocessed_aggs, i)) >= 0)
+ {
+ AggInfo *agginfo = list_nth_node(AggInfo,
root->agginfos, i);
+ Aggref *aggref = linitial_node(Aggref,
agginfo->aggrefs);
+ List *sortlist;
+ List *pathkeys;
+
+ if (aggref->aggdistinct != NIL)
+ sortlist = aggref->aggdistinct;
+ else
+ sortlist = aggref->aggorder;
+
+ pathkeys = make_pathkeys_for_sortclauses(root, sortlist,
+
aggref->args);
+
+ /*
+ * Ignore Aggrefs which have volatile functions in
their ORDER BY
+ * or DISTINCT clause.
+ */
+ if (has_volatile_pathkey(pathkeys))
+ {
+ unprocessed_aggs =
bms_del_member(unprocessed_aggs, i);
+ continue;
+ }
+
+ /*
+ * When not set yet, take the pathkeys from the first
unprocessed
+ * aggregate.
+ */
+ if (currpathkeys == NIL)
+ {
+ currpathkeys = pathkeys;
+
+ /* include the GROUP BY pathkeys, if they exist
*/
+ if (grouppathkeys != NIL)
+ currpathkeys =
append_pathkeys(list_copy(grouppathkeys),
+
currpathkeys);
+
+ /* record that we found pathkeys for this
aggregate */
+ aggindexes = bms_add_member(aggindexes, i);
+ }
+ else
+ {
+ /* now look for a stronger set of matching
pathkeys */
+
+ /* include the GROUP BY pathkeys, if they exist
*/
+ if (grouppathkeys != NIL)
+ pathkeys =
append_pathkeys(list_copy(grouppathkeys),
+
pathkeys);
+
+ /* are 'pathkeys' compatible or better than
'currpathkeys'? */
+ switch (compare_pathkeys(currpathkeys,
pathkeys))
+ {
+ case PATHKEYS_BETTER2:
+ /* 'pathkeys' are stronger, use
these ones instead */
+ currpathkeys = pathkeys;
+ /* FALLTHROUGH */
+
+ case PATHKEYS_BETTER1:
+ /* 'pathkeys' are less strict */
+ /* FALLTHROUGH */
+
+ case PATHKEYS_EQUAL:
+ /* mark this aggregate as
covered by 'currpathkeys' */
+ aggindexes =
bms_add_member(aggindexes, i);
+ break;
+
+ case PATHKEYS_DIFFERENT:
+ break;
+ }
+ }
+ }
+
+ /* remove the aggregates that we've just processed */
+ unprocessed_aggs = bms_del_members(unprocessed_aggs,
aggindexes);
+
+ /*
+ * If this pass included more aggregates than the previous best
then
+ * use these ones as the best set.
+ */
+ if (bms_num_members(aggindexes) > bms_num_members(bestaggs))
+ {
+ bestaggs = aggindexes;
+ bestpathkeys = currpathkeys;
+ }
+ }
+
+ /*
+ * If we found any ordered aggregates, update root->group_pathkeys to
add
+ * the best set of aggregate pathkeys. Note that bestpathkeys includes
+ * the original GROUP BY pathkeys already.
+ */
+ if (bestpathkeys != NIL)
+ root->group_pathkeys = bestpathkeys;
+
+ /*
+ * Now that we've found the best set of aggregates we can set the
+ * presorted flag to indicate to the executor that it needn't bother
+ * performing a sort for these Aggrefs. We're able to do this now as
+ * there's no chance of a Hash Aggregate plan as create_grouping_paths
+ * will not mark the GROUP BY as GROUPING_CAN_USE_HASH due to the
presence
+ * of ordered aggregates.
+ */
+ i = -1;
+ while ((i = bms_next_member(bestaggs, i)) >= 0)
+ {
+ AggInfo *agginfo = list_nth_node(AggInfo, root->agginfos, i);
+
+ foreach(lc, agginfo->aggrefs)
+ {
+ Aggref *aggref = lfirst_node(Aggref, lc);
+
+ aggref->aggpresorted = true;
+ }
+ }
+}
+#endif
/*
* Compute query_pathkeys and other pathkeys during plan generation
@@ -4289,8 +4293,14 @@ standard_qp_callback(PlannerInfo *root, void *extra)
{
root->num_groupby_pathkeys =
list_length(root->group_pathkeys);
/* If we have ordered aggs, consider adding onto
group_pathkeys */
-// if (root->numOrderedAggs > 0)
-// adjust_group_pathkeys_for_groupagg(root);
+ /*
+ * adjust_group_pathkeys_for_groupagg add distinct key
to group path key,
+ * It should cause error for muti-stage aggregate.
+ */
+#if 0
+ if (root->numOrderedAggs > 0)
+ adjust_group_pathkeys_for_groupagg(root);
+#endif
}
}
else
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]