From 66c870d7308f75601024eee5937b0ff0643dc1c9 Mon Sep 17 00:00:00 2001 From: AarDG10 Date: Thu, 15 Jan 2026 18:11:32 +0530 Subject: [PATCH] feat(dx): add validation to check if selected fields are grouped or aggregated for a better dev experience --- frappe/database/query.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/frappe/database/query.py b/frappe/database/query.py index d5d2dd1aec..8118326c20 100644 --- a/frappe/database/query.py +++ b/frappe/database/query.py @@ -1135,6 +1135,7 @@ class Engine: """In PostgreSQL order_by fields need to either be in group_by or be aggregated when used with select and group_by""" if self.is_postgres and self.is_aggregate_query: + self._validate_select_field_grouping_postgres() # DX: validate query current_sql = field.get_sql() if hasattr(field, "get_sql") else str(field) if current_sql in self._grouped_queries: return field @@ -1741,6 +1742,24 @@ class Engine: return True + def _validate_select_field_grouping_postgres(self): + """DX: In PostgreSQL, selected fields used with group by need to either be aggregated or be grouped, + the Query Builder validates this rule if user is unaware""" + for field in self.fields: + if isinstance(field, AggregateFunction): + continue + alias = getattr(field, "alias", None) + field_val = alias if alias is not None else field + field_val = str(field_val).replace('"', "") + if field_val not in self._grouped_queries: + frappe.throw( + _( + "PostgreSQL grouping error: The field '{0}' is selected but neither grouped nor aggregated. " + "Add it to 'group_by' or aggregate it." + ).format(field_val), + frappe.ValidationError, + ) + class DynamicTableField: def __init__(