Repository: mathesar-foundation/mathesar

Issue:
When summarizing in Data Explorer, the grouping column should keep its name.
## Description
<!-- A clear and concise description of what the bug is. -->

When summarizing in data explorer, the grouping column has a weird default name set. Specifically, it has the string `'group'` appended. This is a mistake, since grouping by the (for example) `Speaker` column gives the `Speaker` column. 

## Expected behavior
<!-- A clear and concise description of what you expected to happen. -->

The grouping column should keep its name.



Discussion:
Leaving as draft since I expect this to be a bit controversial.
I agree with this, removing draft status
> This is a mistake, since grouping by the (for example) Speaker column gives the Speaker column.

There is one issue here. For grouping we allow preprocessing functions. For eg., by month-year for dates, which convert the type of the grouped column from date to text.

Since the type changes, we need a way for the user to understand that it's a new column which is a string and not the same column with the date type. This also changes the filters allowed on the grouped column. So, it's inaccurate to say that it gives the same column.

The string 'group' was appended inorder to make this distinction. It's not the best solution and I'm open to another approach here.
@pavish I think it's fine to remove the appended string for now and see if it is an actual usability problem for users. If it is, we can figure out how to solve it then.
@Anish9901 this should be a one line change: https://github.com/centerofci/mathesar/blob/master/mathesar/models/query.py#L440
> @Anish9901 this should be a one line change: https://github.com/centerofci/mathesar/blob/master/mathesar/models/query.py#L440

Thanks @dmos62 
This issue has not been updated in 90 days and is being marked as stale.

Resolving patch:
diff --git a/mathesar/models/query.py b/mathesar/models/query.py
--- a/mathesar/models/query.py
+++ b/mathesar/models/query.py
@@ -6,11 +6,28 @@
 from db.transforms.operations.deserialize import deserialize_transformation
 from db.transforms.operations.serialize import serialize_transformation
 from db.transforms.base import Summarize
-from db.functions.base import Count, ArrayAgg, Sum, Median, Mode, Percentage_True, Max, Min, Mean, PeakTime, PeakMonth
+from db.functions.base import (
+    Count,
+    ArrayAgg,
+    Sum,
+    Median,
+    Mode,
+    Percentage_True,
+    Max,
+    Min,
+    Mean,
+    PeakTime,
+    PeakMonth,
+)
 from db.functions.packed import DistinctArrayAgg
 
 from mathesar.api.exceptions.query_exceptions.exceptions import DeletedColumnAccess
-from mathesar.models.validators import DictValidator, InitialColumnsValidator, ListOfDictValidator, TransformationsValidator
+from mathesar.models.validators import (
+    DictValidator,
+    InitialColumnsValidator,
+    ListOfDictValidator,
+    TransformationsValidator,
+)
 from mathesar.state.cached_property import cached_property
 from mathesar.models.base import BaseModel, Column
 from mathesar.models.relation import Relation
@@ -22,13 +39,10 @@ class UIQuery(BaseModel, Relation):
         max_length=128,
     )
 
-    description = models.TextField(
-        null=True,
-        blank=True
-    )
+    description = models.TextField(null=True, blank=True)
 
     base_table = models.ForeignKey(
-        'Table', on_delete=models.CASCADE, related_name='queries'
+        "Table", on_delete=models.CASCADE, related_name="queries"
     )
 
     # sequence of dicts
@@ -82,8 +96,7 @@ def output_columns_described(self):
         """
         return tuple(
             self._describe_query_column(sa_col)
-            for sa_col
-            in self.db_query.sa_output_columns
+            for sa_col in self.db_query.sa_output_columns
         )
 
     @property
@@ -94,16 +107,13 @@ def output_columns_simple(self):
     def initial_columns_described(self):
         return tuple(
             {
-                'alias': initial_col_alias,
-                'display_name': self._get_display_name_for_alias(
-                    initial_col_alias
-                ),
-                'type': dj_col.db_type.id,
-                'type_options': dj_col._sa_column.type_options,
-                'display_options': dj_col.display_options
+                "alias": initial_col_alias,
+                "display_name": self._get_display_name_for_alias(initial_col_alias),
+                "type": dj_col.db_type.id,
+                "type_options": dj_col._sa_column.type_options,
+                "display_options": dj_col.display_options,
             }
-            for initial_col_alias, dj_col
-            in self._map_of_initial_col_alias_to_dj_column.items()
+            for initial_col_alias, dj_col in self._map_of_initial_col_alias_to_dj_column.items()
         )
 
     def _describe_query_column(self, sa_col):
@@ -126,7 +136,9 @@ def _describe_query_column(self, sa_col):
         )
         output = output | optionals
         if is_initial_column:
-            initial_dj_column = _get_dj_column_for_initial_db_column(initial_db_column, self._database)
+            initial_dj_column = _get_dj_column_for_initial_db_column(
+                initial_db_column, self._database
+            )
             output = output | dict(
                 input_column_name=initial_dj_column.name,
                 input_table_name=initial_dj_column.table.name,
@@ -134,9 +146,7 @@ def _describe_query_column(self, sa_col):
             )
         else:
             input_alias = self.db_query.get_input_alias_for_output_alias(alias)
-            output = output | dict(
-                input_alias=input_alias
-            )
+            output = output | dict(input_alias=input_alias)
         return output
 
     def _get_db_initial_column_by_alias(self, alias):
@@ -180,8 +190,7 @@ def replace_transformations_with_processed_transformations(self):
     def _processed_transformations(self):
         return tuple(
             serialize_transformation(db_transformation)
-            for db_transformation
-            in self._processed_db_transformations
+            for db_transformation in self._processed_db_transformations
         )
 
     @property
@@ -212,15 +221,14 @@ def db_query(self):
             engine=self._sa_engine,
             transformations=self._db_transformations,
             name=self.name,
-            metadata=get_cached_metadata()
+            metadata=get_cached_metadata(),
         )
 
     # TODO reused; consider using cached_property
     @property
     def _db_initial_columns(self):
         return tuple(
-            _db_initial_column_from_json(json_col)
-            for json_col in self.initial_columns
+            _db_initial_column_from_json(json_col) for json_col in self.initial_columns
         )
 
     @property
@@ -228,9 +236,7 @@ def _db_transformations(self):
         """No processing necessary."""
         if self.transformations:
             return tuple(
-                deserialize_transformation(json)
-                for json
-                in self.transformations
+                deserialize_transformation(json) for json in self.transformations
             )
 
     def _get_display_name_for_alias(self, alias):
@@ -248,8 +254,7 @@ def _get_display_options_for_alias(self, alias):
                 display_options = dj_col.display_options
         # Try recursively repeating these steps for its parent alias, if it can be found
         if display_options is None:
-            parent_alias = \
-                self.db_query.map_of_output_alias_to_input_alias.get(alias)
+            parent_alias = self.db_query.map_of_output_alias_to_input_alias.get(alias)
             if parent_alias:
                 display_options = self._get_display_options_for_alias(parent_alias)
         return display_options
@@ -286,46 +291,49 @@ def _default_display_names(self):
         attribute), though they are used when generating some of the default display names.
         """
         current_display_names = self.display_names or dict()
-        default_display_names_for_initial_columns = self._default_display_names_for_initial_columns
-        current_display_names = \
-            default_display_names_for_initial_columns \
-            | current_display_names
-        default_display_names_for_summarize_transforms = \
+        default_display_names_for_initial_columns = (
+            self._default_display_names_for_initial_columns
+        )
+        current_display_names = (
+            default_display_names_for_initial_columns | current_display_names
+        )
+        default_display_names_for_summarize_transforms = (
             self._get_default_display_names_for_summarize_transforms(
                 current_display_names
             )
-        default_display_names = \
-            default_display_names_for_summarize_transforms \
+        )
+        default_display_names = (
+            default_display_names_for_summarize_transforms
             | default_display_names_for_initial_columns
+        )
         return default_display_names
 
     @property
     def _default_display_names_for_initial_columns(self):
         return {
             alias: dj_col.name
-            for alias, dj_col
-            in self._map_of_initial_col_alias_to_dj_column.items()
+            for alias, dj_col in self._map_of_initial_col_alias_to_dj_column.items()
         }
 
-    def _get_default_display_names_for_summarize_transforms(self, current_display_names):
+    def _get_default_display_names_for_summarize_transforms(
+        self, current_display_names
+    ):
         default_display_names = dict()
         if not current_display_names:
             return default_display_names
         summarize_transforms = [
             db_transform
-            for db_transform
-            in self.db_query.transformations
+            for db_transform in self.db_query.transformations
             if isinstance(db_transform, Summarize)
         ]
         for summarize_transform in summarize_transforms:
             # Find default display names for grouping output aliases
             for output_alias in summarize_transform.grouping_output_aliases:
-                default_display_name = \
-                    _get_default_display_name_for_group_output_alias(
-                        summarize_transform,
-                        output_alias,
-                        current_display_names,
-                    )
+                default_display_name = _get_default_display_name_for_group_output_alias(
+                    summarize_transform,
+                    output_alias,
+                    current_display_names,
+                )
                 if default_display_name:
                     default_display_names[output_alias] = default_display_name
             # Find default display names for aggregation output aliases
@@ -333,25 +341,22 @@ def _get_default_display_names_for_summarize_transforms(self, current_display_na
                 input_alias = agg_col_spec.get("input_alias")
                 output_alias = agg_col_spec.get("output_alias")
                 agg_function = agg_col_spec.get("function")
-                default_display_name = \
-                    _get_default_display_name_for_agg_output_alias(
-                        output_alias,
-                        input_alias,
-                        agg_function,
-                        current_display_names,
-                    )
+                default_display_name = _get_default_display_name_for_agg_output_alias(
+                    output_alias,
+                    input_alias,
+                    agg_function,
+                    current_display_names,
+                )
                 if default_display_name:
                     default_display_names[output_alias] = default_display_name
         return default_display_names
 
     @property
     def _map_of_initial_col_alias_to_dj_column(self):
-        dj_column_ids = [col['id'] for col in self.initial_columns]
+        dj_column_ids = [col["id"] for col in self.initial_columns]
         dj_columns = Column.objects.filter(pk__in=dj_column_ids)
         initial_col_aliases = [
-            initial_col['alias']
-            for initial_col
-            in self.initial_columns
+            initial_col["alias"] for initial_col in self.initial_columns
         ]
         return frozendict(
             zip(
@@ -383,9 +388,7 @@ def _db_initial_column_from_json(col_json):
     attnum = column_pair[1]
     alias = col_json["alias"]
     jp_path = [
-        _join_parameter_from_json(jp_json)
-        for jp_json
-        in col_json.get("jp_path", [])
+        _join_parameter_from_json(jp_json) for jp_json in col_json.get("jp_path", [])
     ]
     return InitialColumn(
         reloid=reloid,
@@ -441,10 +444,6 @@ def _get_default_display_name_for_group_output_alias(
     output_alias,
     current_display_names,
 ):
-    input_alias = \
-        summarize_transform\
-        .map_of_output_alias_to_input_alias[output_alias]
+    input_alias = summarize_transform.map_of_output_alias_to_input_alias[output_alias]
     input_alias_display_name = current_display_names.get(input_alias)
-    if input_alias_display_name:
-        suffix_to_add = " group"
-        return input_alias_display_name + suffix_to_add
+    return input_alias_display_name


Test patch:
diff --git a/mathesar/tests/api/query/test_query_run_partial_transforms.py b/mathesar/tests/api/query/test_query_run_partial_transforms.py
--- a/mathesar/tests/api/query/test_query_run_partial_transforms.py
+++ b/mathesar/tests/api/query/test_query_run_partial_transforms.py
@@ -113,7 +113,7 @@ def test_partial_summarize_transform(
             'transformations': output_transformations,
             'display_names': {
                 'col1': 'Center',
-                'col1_grouped': 'Center group',
+                'col1_grouped': 'Center',
                 'col2': 'Case Number',
                 'col2_agged': 'Case Number distinct list',
             },
@@ -135,7 +135,7 @@ def test_partial_summarize_transform(
             },
             'col1_grouped': {
                 'alias': 'col1_grouped',
-                'display_name': 'Center group',
+                'display_name': 'Center',
                 'display_options': None,
                 'input_alias': 'col1',
                 'input_column_name': None,