diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index c1a76584f0..a8f8b427ca 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -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) diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 72bca4f205..bf40f7f541 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -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