Skip to content

Commit ef59827

Browse files
committed
2
1 parent 62ecdfc commit ef59827

File tree

1 file changed

+39
-11
lines changed

1 file changed

+39
-11
lines changed

src/backend/optimizer/path/pathkeys.c

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -380,15 +380,18 @@ group_keys_reorder_by_pathkeys(List *pathkeys, List **group_pathkeys,
380380

381381
/*
382382
* We're going to search within just the first num_groupby_pathkeys of
383-
* *group_pathkeys. The thing is that root->group_pathkeys is passed as
383+
* *group_pathkeys. The thing is that root->group_pathkeys is passed as
384384
* *group_pathkeys containing grouping pathkeys altogether with aggregate
385-
* pathkeys. If we process aggregate pathkeys we could get an invalid
385+
* pathkeys. If we process aggregate pathkeys we could get an invalid
386386
* result of get_sortgroupref_clause_noerr(), because their
387-
* pathkey->pk_eclass->ec_sortref doesn't reference query targetlist. So,
387+
* pathkey->pk_eclass->ec_sortref doesn't reference query targetlist. So,
388388
* we allocate a separate list of pathkeys for lookups.
389389
*/
390390
grouping_pathkeys = list_copy_head(*group_pathkeys, num_groupby_pathkeys);
391391

392+
/* Make a new copy before reordering clauses */
393+
*group_clauses = list_copy(*group_clauses);
394+
392395
/*
393396
* Walk the pathkeys (determining ordering of the input path) and see if
394397
* there's a matching GROUP BY key. If we find one, we append it to the
@@ -400,8 +403,8 @@ group_keys_reorder_by_pathkeys(List *pathkeys, List **group_pathkeys,
400403
*/
401404
foreach(lc, pathkeys)
402405
{
403-
PathKey *pathkey = (PathKey *) lfirst(lc);
404-
SortGroupClause *sgc;
406+
PathKey *pathkey = (PathKey *) lfirst(lc);
407+
SortGroupClause *sgc;
405408

406409
/*
407410
* Pathkeys are built in a way that allows simply comparing pointers.
@@ -431,17 +434,25 @@ group_keys_reorder_by_pathkeys(List *pathkeys, List **group_pathkeys,
431434
Assert(OidIsValid(sgc->sortop));
432435

433436
new_group_pathkeys = lappend(new_group_pathkeys, pathkey);
437+
438+
/*
439+
* Keeping in mind that the SortGroupClause list doesn't guarantee
440+
* unique pointers we must explicitly transfer elements one-by-one.
441+
*/
434442
new_group_clauses = lappend(new_group_clauses, sgc);
443+
*group_clauses = list_delete_ptr(*group_clauses, sgc);
435444
}
436445

437446
/* remember the number of pathkeys with a matching GROUP BY key */
438447
n = list_length(new_group_pathkeys);
439448

440-
/* append the remaining group pathkeys (will be treated as not sorted) */
449+
/*
450+
* Append the remaining group pathkeys (will be treated as not sorted) and
451+
* grouping clauses.
452+
*/
441453
*group_pathkeys = list_concat_unique_ptr(new_group_pathkeys,
442454
*group_pathkeys);
443-
*group_clauses = list_concat_unique_ptr(new_group_clauses,
444-
*group_clauses);
455+
*group_clauses = list_concat(new_group_clauses, *group_clauses);
445456

446457
list_free(grouping_pathkeys);
447458
return n;
@@ -484,9 +495,9 @@ pathkeys_are_duplicate(List *infos, List *pathkeys)
484495
List *
485496
get_useful_group_keys_orderings(PlannerInfo *root, Path *path)
486497
{
487-
Query *parse = root->parse;
488-
List *infos = NIL;
489-
PathKeyInfo *info;
498+
Query *parse = root->parse;
499+
List *infos = NIL;
500+
PathKeyInfo *info;
490501

491502
List *pathkeys = root->group_pathkeys;
492503
List *clauses = root->processed_groupClause;
@@ -561,6 +572,23 @@ get_useful_group_keys_orderings(PlannerInfo *root, Path *path)
561572
}
562573
}
563574

575+
#ifdef USE_ASSERT_CHECKING
576+
{
577+
PathKeyInfo *pinfo = linitial_node(PathKeyInfo, infos);
578+
ListCell *lc;
579+
580+
/* Test consistency of info structures */
581+
for_each_from(lc, infos, 1)
582+
{
583+
info = lfirst_node(PathKeyInfo, lc);
584+
585+
Assert(list_length(info->clauses) == list_length(pinfo->clauses));
586+
Assert(list_length(info->pathkeys) == list_length(pinfo->pathkeys));
587+
Assert(list_difference(info->clauses, pinfo->clauses) == NIL);
588+
Assert(list_difference_ptr(info->pathkeys, pinfo->pathkeys) == NIL);
589+
}
590+
}
591+
#endif
564592
return infos;
565593
}
566594

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy