|
23 | 23 | #include "access/sysattr.h"
|
24 | 24 | #include "access/table.h"
|
25 | 25 | #include "catalog/pg_aggregate.h"
|
26 |
| -#include "catalog/pg_constraint.h" |
27 | 26 | #include "catalog/pg_inherits.h"
|
28 | 27 | #include "catalog/pg_proc.h"
|
29 | 28 | #include "catalog/pg_type.h"
|
@@ -139,7 +138,6 @@ static void preprocess_rowmarks(PlannerInfo *root);
|
139 | 138 | static double preprocess_limit(PlannerInfo *root,
|
140 | 139 | double tuple_fraction,
|
141 | 140 | int64 *offset_est, int64 *count_est);
|
142 |
| -static void remove_useless_groupby_columns(PlannerInfo *root); |
143 | 141 | static List *preprocess_groupclause(PlannerInfo *root, List *force);
|
144 | 142 | static List *extract_rollup_sets(List *groupingSets);
|
145 | 143 | static List *reorder_grouping_sets(List *groupingSets, List *sortclause);
|
@@ -1487,8 +1485,6 @@ grouping_planner(PlannerInfo *root, double tuple_fraction,
|
1487 | 1485 | {
|
1488 | 1486 | /* Preprocess regular GROUP BY clause, if any */
|
1489 | 1487 | root->processed_groupClause = preprocess_groupclause(root, NIL);
|
1490 |
| - /* Remove any redundant GROUP BY columns */ |
1491 |
| - remove_useless_groupby_columns(root); |
1492 | 1488 | }
|
1493 | 1489 |
|
1494 | 1490 | /*
|
@@ -2724,166 +2720,6 @@ limit_needed(Query *parse)
|
2724 | 2720 | return false; /* don't need a Limit plan node */
|
2725 | 2721 | }
|
2726 | 2722 |
|
2727 |
| - |
2728 |
| -/* |
2729 |
| - * remove_useless_groupby_columns |
2730 |
| - * Remove any columns in the GROUP BY clause that are redundant due to |
2731 |
| - * being functionally dependent on other GROUP BY columns. |
2732 |
| - * |
2733 |
| - * Since some other DBMSes do not allow references to ungrouped columns, it's |
2734 |
| - * not unusual to find all columns listed in GROUP BY even though listing the |
2735 |
| - * primary-key columns would be sufficient. Deleting such excess columns |
2736 |
| - * avoids redundant sorting work, so it's worth doing. |
2737 |
| - * |
2738 |
| - * Relcache invalidations will ensure that cached plans become invalidated |
2739 |
| - * when the underlying index of the pkey constraint is dropped. |
2740 |
| - * |
2741 |
| - * Currently, we only make use of pkey constraints for this, however, we may |
2742 |
| - * wish to take this further in the future and also use unique constraints |
2743 |
| - * which have NOT NULL columns. In that case, plan invalidation will still |
2744 |
| - * work since relations will receive a relcache invalidation when a NOT NULL |
2745 |
| - * constraint is dropped. |
2746 |
| - */ |
2747 |
| -static void |
2748 |
| -remove_useless_groupby_columns(PlannerInfo *root) |
2749 |
| -{ |
2750 |
| - Query *parse = root->parse; |
2751 |
| - Bitmapset **groupbyattnos; |
2752 |
| - Bitmapset **surplusvars; |
2753 |
| - ListCell *lc; |
2754 |
| - int relid; |
2755 |
| - |
2756 |
| - /* No chance to do anything if there are less than two GROUP BY items */ |
2757 |
| - if (list_length(root->processed_groupClause) < 2) |
2758 |
| - return; |
2759 |
| - |
2760 |
| - /* Don't fiddle with the GROUP BY clause if the query has grouping sets */ |
2761 |
| - if (parse->groupingSets) |
2762 |
| - return; |
2763 |
| - |
2764 |
| - /* |
2765 |
| - * Scan the GROUP BY clause to find GROUP BY items that are simple Vars. |
2766 |
| - * Fill groupbyattnos[k] with a bitmapset of the column attnos of RTE k |
2767 |
| - * that are GROUP BY items. |
2768 |
| - */ |
2769 |
| - groupbyattnos = (Bitmapset **) palloc0(sizeof(Bitmapset *) * |
2770 |
| - (list_length(parse->rtable) + 1)); |
2771 |
| - foreach(lc, root->processed_groupClause) |
2772 |
| - { |
2773 |
| - SortGroupClause *sgc = lfirst_node(SortGroupClause, lc); |
2774 |
| - TargetEntry *tle = get_sortgroupclause_tle(sgc, parse->targetList); |
2775 |
| - Var *var = (Var *) tle->expr; |
2776 |
| - |
2777 |
| - /* |
2778 |
| - * Ignore non-Vars and Vars from other query levels. |
2779 |
| - * |
2780 |
| - * XXX in principle, stable expressions containing Vars could also be |
2781 |
| - * removed, if all the Vars are functionally dependent on other GROUP |
2782 |
| - * BY items. But it's not clear that such cases occur often enough to |
2783 |
| - * be worth troubling over. |
2784 |
| - */ |
2785 |
| - if (!IsA(var, Var) || |
2786 |
| - var->varlevelsup > 0) |
2787 |
| - continue; |
2788 |
| - |
2789 |
| - /* OK, remember we have this Var */ |
2790 |
| - relid = var->varno; |
2791 |
| - Assert(relid <= list_length(parse->rtable)); |
2792 |
| - groupbyattnos[relid] = bms_add_member(groupbyattnos[relid], |
2793 |
| - var->varattno - FirstLowInvalidHeapAttributeNumber); |
2794 |
| - } |
2795 |
| - |
2796 |
| - /* |
2797 |
| - * Consider each relation and see if it is possible to remove some of its |
2798 |
| - * Vars from GROUP BY. For simplicity and speed, we do the actual removal |
2799 |
| - * in a separate pass. Here, we just fill surplusvars[k] with a bitmapset |
2800 |
| - * of the column attnos of RTE k that are removable GROUP BY items. |
2801 |
| - */ |
2802 |
| - surplusvars = NULL; /* don't allocate array unless required */ |
2803 |
| - relid = 0; |
2804 |
| - foreach(lc, parse->rtable) |
2805 |
| - { |
2806 |
| - RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc); |
2807 |
| - Bitmapset *relattnos; |
2808 |
| - Bitmapset *pkattnos; |
2809 |
| - Oid constraintOid; |
2810 |
| - |
2811 |
| - relid++; |
2812 |
| - |
2813 |
| - /* Only plain relations could have primary-key constraints */ |
2814 |
| - if (rte->rtekind != RTE_RELATION) |
2815 |
| - continue; |
2816 |
| - |
2817 |
| - /* |
2818 |
| - * We must skip inheritance parent tables as some of the child rels |
2819 |
| - * may cause duplicate rows. This cannot happen with partitioned |
2820 |
| - * tables, however. |
2821 |
| - */ |
2822 |
| - if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE) |
2823 |
| - continue; |
2824 |
| - |
2825 |
| - /* Nothing to do unless this rel has multiple Vars in GROUP BY */ |
2826 |
| - relattnos = groupbyattnos[relid]; |
2827 |
| - if (bms_membership(relattnos) != BMS_MULTIPLE) |
2828 |
| - continue; |
2829 |
| - |
2830 |
| - /* |
2831 |
| - * Can't remove any columns for this rel if there is no suitable |
2832 |
| - * (i.e., nondeferrable) primary key constraint. |
2833 |
| - */ |
2834 |
| - pkattnos = get_primary_key_attnos(rte->relid, false, &constraintOid); |
2835 |
| - if (pkattnos == NULL) |
2836 |
| - continue; |
2837 |
| - |
2838 |
| - /* |
2839 |
| - * If the primary key is a proper subset of relattnos then we have |
2840 |
| - * some items in the GROUP BY that can be removed. |
2841 |
| - */ |
2842 |
| - if (bms_subset_compare(pkattnos, relattnos) == BMS_SUBSET1) |
2843 |
| - { |
2844 |
| - /* |
2845 |
| - * To easily remember whether we've found anything to do, we don't |
2846 |
| - * allocate the surplusvars[] array until we find something. |
2847 |
| - */ |
2848 |
| - if (surplusvars == NULL) |
2849 |
| - surplusvars = (Bitmapset **) palloc0(sizeof(Bitmapset *) * |
2850 |
| - (list_length(parse->rtable) + 1)); |
2851 |
| - |
2852 |
| - /* Remember the attnos of the removable columns */ |
2853 |
| - surplusvars[relid] = bms_difference(relattnos, pkattnos); |
2854 |
| - } |
2855 |
| - } |
2856 |
| - |
2857 |
| - /* |
2858 |
| - * If we found any surplus Vars, build a new GROUP BY clause without them. |
2859 |
| - * (Note: this may leave some TLEs with unreferenced ressortgroupref |
2860 |
| - * markings, but that's harmless.) |
2861 |
| - */ |
2862 |
| - if (surplusvars != NULL) |
2863 |
| - { |
2864 |
| - List *new_groupby = NIL; |
2865 |
| - |
2866 |
| - foreach(lc, root->processed_groupClause) |
2867 |
| - { |
2868 |
| - SortGroupClause *sgc = lfirst_node(SortGroupClause, lc); |
2869 |
| - TargetEntry *tle = get_sortgroupclause_tle(sgc, parse->targetList); |
2870 |
| - Var *var = (Var *) tle->expr; |
2871 |
| - |
2872 |
| - /* |
2873 |
| - * New list must include non-Vars, outer Vars, and anything not |
2874 |
| - * marked as surplus. |
2875 |
| - */ |
2876 |
| - if (!IsA(var, Var) || |
2877 |
| - var->varlevelsup > 0 || |
2878 |
| - !bms_is_member(var->varattno - FirstLowInvalidHeapAttributeNumber, |
2879 |
| - surplusvars[var->varno])) |
2880 |
| - new_groupby = lappend(new_groupby, sgc); |
2881 |
| - } |
2882 |
| - |
2883 |
| - root->processed_groupClause = new_groupby; |
2884 |
| - } |
2885 |
| -} |
2886 |
| - |
2887 | 2723 | /*
|
2888 | 2724 | * preprocess_groupclause - do preparatory work on GROUP BY clause
|
2889 | 2725 | *
|
|
0 commit comments