diff options
Diffstat (limited to 'django/db/models/sql')
| -rw-r--r-- | django/db/models/sql/compiler.py | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 002bc05824..7ea9ef9067 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -136,10 +136,7 @@ class SQLCompiler(object): # If the DB can group by primary key, then group by the primary key of # query's main model. Note that for PostgreSQL the GROUP BY clause must # include the primary key of every table, but for MySQL it is enough to - # have the main table's primary key. Currently only the MySQL form is - # implemented. - # MySQLism: however, columns in HAVING clause must be added to the - # GROUP BY. + # have the main table's primary key. if self.connection.features.allows_group_by_pk: # The logic here is: if the main model's primary key is in the # query, then set new_expressions to that field. If that happens, @@ -150,7 +147,18 @@ class SQLCompiler(object): getattr(expr.output_field, 'model') == self.query.model): pk = expr if pk: + # MySQLism: Columns in HAVING clause must be added to the GROUP BY. expressions = [pk] + [expr for expr in expressions if expr in having] + elif self.connection.features.allows_group_by_selected_pks: + # Filter out all expressions associated with a table's primary key + # present in the grouped columns. This is done by identifying all + # tables that have their primary key included in the grouped + # columns and removing non-primary key columns referring to them. + pks = {expr for expr in expressions if hasattr(expr, 'target') and expr.target.primary_key} + aliases = {expr.alias for expr in pks} + expressions = [ + expr for expr in expressions if expr in pks or getattr(expr, 'alias', None) not in aliases + ] return expressions def get_select(self): |
