@@ -380,15 +380,18 @@ group_keys_reorder_by_pathkeys(List *pathkeys, List **group_pathkeys,
380
380
381
381
/*
382
382
* 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
384
384
* *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
386
386
* 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,
388
388
* we allocate a separate list of pathkeys for lookups.
389
389
*/
390
390
grouping_pathkeys = list_copy_head (* group_pathkeys , num_groupby_pathkeys );
391
391
392
+ /* Make a new copy before reordering clauses */
393
+ * group_clauses = list_copy (* group_clauses );
394
+
392
395
/*
393
396
* Walk the pathkeys (determining ordering of the input path) and see if
394
397
* 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,
400
403
*/
401
404
foreach (lc , pathkeys )
402
405
{
403
- PathKey * pathkey = (PathKey * ) lfirst (lc );
404
- SortGroupClause * sgc ;
406
+ PathKey * pathkey = (PathKey * ) lfirst (lc );
407
+ SortGroupClause * sgc ;
405
408
406
409
/*
407
410
* 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,
431
434
Assert (OidIsValid (sgc -> sortop ));
432
435
433
436
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
+ */
434
442
new_group_clauses = lappend (new_group_clauses , sgc );
443
+ * group_clauses = list_delete_ptr (* group_clauses , sgc );
435
444
}
436
445
437
446
/* remember the number of pathkeys with a matching GROUP BY key */
438
447
n = list_length (new_group_pathkeys );
439
448
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
+ */
441
453
* group_pathkeys = list_concat_unique_ptr (new_group_pathkeys ,
442
454
* 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 );
445
456
446
457
list_free (grouping_pathkeys );
447
458
return n ;
@@ -484,9 +495,9 @@ pathkeys_are_duplicate(List *infos, List *pathkeys)
484
495
List *
485
496
get_useful_group_keys_orderings (PlannerInfo * root , Path * path )
486
497
{
487
- Query * parse = root -> parse ;
488
- List * infos = NIL ;
489
- PathKeyInfo * info ;
498
+ Query * parse = root -> parse ;
499
+ List * infos = NIL ;
500
+ PathKeyInfo * info ;
490
501
491
502
List * pathkeys = root -> group_pathkeys ;
492
503
List * clauses = root -> processed_groupClause ;
@@ -561,6 +572,23 @@ get_useful_group_keys_orderings(PlannerInfo *root, Path *path)
561
572
}
562
573
}
563
574
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
564
592
return infos ;
565
593
}
566
594
0 commit comments