Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7ee54dc

Browse files
committed
2
1 parent e729516 commit 7ee54dc

File tree

1 file changed

+39
-11
lines changed

1 file changed

+39
-11
lines changed

src/backend/optimizer/path/pathkeys.c

+39-11
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)