Fix GROUP BY to exclude constants in ExpressionWrapper

Ensure ExpressionWrapper passes group by columns from its inner expression,
preventing constant expressions from being incorrectly included in the GROUP BY
clause. This addresses SQL errors on Postgres with aggregates (# issue).

Add regression test to verify correct SQL generation and results.
This commit is contained in:
utkarsh.arya@zomato.com 2025-11-15 22:59:52 +00:00
parent 22a59c01c0
commit 57d58b4dc9
2 changed files with 21 additions and 0 deletions

View file

@ -866,6 +866,9 @@ class ExpressionWrapper(Expression):
def as_sql(self, compiler, connection):
return self.expression.as_sql(compiler, connection)
def get_group_by_cols(self, alias=None):
return self.expression.get_group_by_cols(alias)
def __repr__(self):
return "{}({})".format(self.__class__.__name__, self.expression)

View file

@ -781,6 +781,24 @@ class BasicExpressionsTests(TestCase):
[self.example_inc.ceo, self.max],
)
def test_expressionwrapper_with_constant_values_aggregate(self):
# Constant expressions wrapped in ExpressionWrapper should not be
# included in the GROUP BY clause.
expr = ExpressionWrapper(Value(3), output_field=IntegerField())
qs = Employee.objects.annotate(
expr_res=expr
).values('expr_res', 'lastname').annotate(sum=Sum('salary'))
# This should work without raising an error about constants in GROUP BY
results = list(qs)
# Verify that the constant expression is in the SELECT but not in GROUP BY
sql = str(qs.query)
self.assertIn('3', sql) # Constant in SELECT
# Verify results are grouped by lastname only
self.assertEqual(len(results), 3) # Smith, Meyer, Mustermann
# All results should have expr_res=3
for result in results:
self.assertEqual(result['expr_res'], 3)
class IterableLookupInnerExpressionsTests(TestCase):
@classmethod