Skip to content

Commit 449c621

Browse files
committed
4
1 parent fedb37d commit 449c621

File tree

4 files changed

+40
-19
lines changed

4 files changed

+40
-19
lines changed

src/backend/optimizer/path/pathkeys.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ group_keys_reorder_by_pathkeys(List *pathkeys, List **group_pathkeys,
461461
/*
462462
* pathkeys_are_duplicate
463463
* Check if give pathkeys are already contained the list of
464-
* PathKeyInfo's.
464+
* GroupByOrdering's.
465465
*/
466466
static bool
467467
pathkeys_are_duplicate(List *infos, List *pathkeys)
@@ -470,7 +470,7 @@ pathkeys_are_duplicate(List *infos, List *pathkeys)
470470

471471
foreach(lc, infos)
472472
{
473-
PathKeyInfo *info = lfirst_node(PathKeyInfo, lc);
473+
GroupByOrdering *info = lfirst_node(GroupByOrdering, lc);
474474

475475
if (compare_pathkeys(pathkeys, info->pathkeys) == PATHKEYS_EQUAL)
476476
return true;
@@ -482,7 +482,7 @@ pathkeys_are_duplicate(List *infos, List *pathkeys)
482482
* get_useful_group_keys_orderings
483483
* Determine which orderings of GROUP BY keys are potentially interesting.
484484
*
485-
* Returns a list of PathKeyInfo items, each representing an interesting
485+
* Returns a list of GroupByOrdering items, each representing an interesting
486486
* ordering of GROUP BY keys. Each item stores pathkeys and clauses in the
487487
* matching order.
488488
*
@@ -495,15 +495,15 @@ pathkeys_are_duplicate(List *infos, List *pathkeys)
495495
List *
496496
get_useful_group_keys_orderings(PlannerInfo *root, Path *path)
497497
{
498-
Query *parse = root->parse;
499-
List *infos = NIL;
500-
PathKeyInfo *info;
498+
Query *parse = root->parse;
499+
List *infos = NIL;
500+
GroupByOrdering *info;
501501

502502
List *pathkeys = root->group_pathkeys;
503503
List *clauses = root->processed_groupClause;
504504

505505
/* always return at least the original pathkeys/clauses */
506-
info = makeNode(PathKeyInfo);
506+
info = makeNode(GroupByOrdering);
507507
info->pathkeys = pathkeys;
508508
info->clauses = clauses;
509509
infos = lappend(infos, info);
@@ -539,7 +539,7 @@ get_useful_group_keys_orderings(PlannerInfo *root, Path *path)
539539
(enable_incremental_sort || n == root->num_groupby_pathkeys) &&
540540
!pathkeys_are_duplicate(infos, pathkeys))
541541
{
542-
info = makeNode(PathKeyInfo);
542+
info = makeNode(GroupByOrdering);
543543
info->pathkeys = pathkeys;
544544
info->clauses = clauses;
545545

@@ -564,7 +564,7 @@ get_useful_group_keys_orderings(PlannerInfo *root, Path *path)
564564
(enable_incremental_sort || n == list_length(root->sort_pathkeys)) &&
565565
!pathkeys_are_duplicate(infos, pathkeys))
566566
{
567-
info = makeNode(PathKeyInfo);
567+
info = makeNode(GroupByOrdering);
568568
info->pathkeys = pathkeys;
569569
info->clauses = clauses;
570570

@@ -574,18 +574,29 @@ get_useful_group_keys_orderings(PlannerInfo *root, Path *path)
574574

575575
#ifdef USE_ASSERT_CHECKING
576576
{
577-
PathKeyInfo *pinfo = linitial_node(PathKeyInfo, infos);
577+
GroupByOrdering *pinfo = linitial_node(GroupByOrdering, infos);
578578
ListCell *lc;
579579

580580
/* Test consistency of info structures */
581581
for_each_from(lc, infos, 1)
582582
{
583-
info = lfirst_node(PathKeyInfo, lc);
583+
ListCell *lc1, *lc2;
584+
585+
info = lfirst_node(GroupByOrdering, lc);
584586

585587
Assert(list_length(info->clauses) == list_length(pinfo->clauses));
586588
Assert(list_length(info->pathkeys) == list_length(pinfo->pathkeys));
587589
Assert(list_difference(info->clauses, pinfo->clauses) == NIL);
588590
Assert(list_difference_ptr(info->pathkeys, pinfo->pathkeys) == NIL);
591+
592+
forboth(lc1, info->clauses, lc2, info->pathkeys)
593+
{
594+
SortGroupClause *sgc = lfirst_node(SortGroupClause, lc1);
595+
PathKey *pk = lfirst_node(PathKey, lc2);
596+
597+
if (pk->pk_eclass->ec_sortref != sgc->tleSortGroupRef)
598+
elog(ERROR, "Order of group-by clauses doesn't correspond incoming sort order");
599+
}
589600
}
590601
}
591602
#endif

src/backend/optimizer/plan/planner.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6882,7 +6882,7 @@ add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel,
68826882

68836883
foreach(lc2, pathkey_orderings)
68846884
{
6885-
PathKeyInfo *info = (PathKeyInfo *) lfirst(lc2);
6885+
GroupByOrdering *info = (GroupByOrdering *) lfirst(lc2);
68866886

68876887
/* restore the path (we replace it in the loop) */
68886888
path = path_save;
@@ -6963,7 +6963,7 @@ add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel,
69636963
/* process all potentially interesting grouping reorderings */
69646964
foreach(lc2, pathkey_orderings)
69656965
{
6966-
PathKeyInfo *info = (PathKeyInfo *) lfirst(lc2);
6966+
GroupByOrdering *info = (GroupByOrdering *) lfirst(lc2);
69676967

69686968
/* restore the path (we replace it in the loop) */
69696969
path = path_save;
@@ -7214,7 +7214,7 @@ create_partial_grouping_paths(PlannerInfo *root,
72147214
/* process all potentially interesting grouping reorderings */
72157215
foreach(lc2, pathkey_orderings)
72167216
{
7217-
PathKeyInfo *info = (PathKeyInfo *) lfirst(lc2);
7217+
GroupByOrdering *info = (GroupByOrdering *) lfirst(lc2);
72187218

72197219
/* restore the path (we replace it in the loop) */
72207220
path = path_save;
@@ -7270,7 +7270,7 @@ create_partial_grouping_paths(PlannerInfo *root,
72707270
/* process all potentially interesting grouping reorderings */
72717271
foreach(lc2, pathkey_orderings)
72727272
{
7273-
PathKeyInfo *info = (PathKeyInfo *) lfirst(lc2);
7273+
GroupByOrdering *info = (GroupByOrdering *) lfirst(lc2);
72747274

72757275

72767276
/* restore the path (we replace it in the loop) */

src/include/nodes/pathnodes.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,10 @@ struct PlannerInfo
427427
* containing all the query's rows. Hence, if you want to check whether
428428
* GROUP BY was specified, test for nonempty parse->groupClause, not for
429429
* nonempty processed_groupClause.
430+
* Optimiser chooses specific order of group-by clauses during the upper
431+
* paths generation process, attempting to use different strategies to
432+
* minimize number of sorts or engage incremental sort.
433+
* See get_useful_group_keys_orderings for details.
430434
*
431435
* Currently, when grouping sets are specified we do not attempt to
432436
* optimize the groupClause, so that processed_groupClause will be
@@ -1468,14 +1472,20 @@ typedef struct PathKey
14681472
} PathKey;
14691473

14701474
/*
1471-
* Combines the information about pathkeys and the associated clauses.
1475+
* Contains an order of group-by clauses and corresponding list of pathkeys.
1476+
*
1477+
* Order of SortGroupClause elements must correspond the order in the head of
1478+
* PathKey list:
1479+
* tleSortGroupRef of N-th element in the clauses must be the same as the value
1480+
* of ec_sortref in N-th pathkey equivalence class.
14721481
*/
1473-
typedef struct PathKeyInfo
1482+
typedef struct GroupByOrdering
14741483
{
14751484
NodeTag type;
1485+
14761486
List *pathkeys;
14771487
List *clauses;
1478-
} PathKeyInfo;
1488+
} GroupByOrdering;
14791489

14801490
/*
14811491
* VolatileFunctionStatus -- allows nodes to cache their

src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4113,7 +4113,7 @@ manifest_writer
41134113
rfile
41144114
ws_options
41154115
ws_file_info
4116-
PathKeyInfo
4116+
GroupByOrdering
41174117
TidStore
41184118
TidStoreIter
41194119
TidStoreIterResult

0 commit comments

Comments
 (0)