diff options
Diffstat (limited to 'django/db/models/sql')
| -rw-r--r-- | django/db/models/sql/query.py | 12 | ||||
| -rw-r--r-- | django/db/models/sql/where.py | 11 |
2 files changed, 22 insertions, 1 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 16ed92a4d4..5f65786373 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -18,6 +18,7 @@ from django.db.models.aggregates import Count from django.db.models.constants import LOOKUP_SEP from django.db.models.expressions import Col, Ref from django.db.models.fields.related_lookups import MultiColSource +from django.db.models.lookups import Lookup from django.db.models.query_utils import ( Q, check_rel_lookup_compatibility, refs_expression, ) @@ -366,11 +367,20 @@ class Query(object): orig_exprs = annotation.get_source_expressions() new_exprs = [] for expr in orig_exprs: + # FIXME: These conditions are fairly arbitrary. Identify a better + # method of having expressions decide which code path they should + # take. if isinstance(expr, Ref): # Its already a Ref to subquery (see resolve_ref() for # details) new_exprs.append(expr) - elif isinstance(expr, Col): + elif isinstance(expr, (WhereNode, Lookup)): + # Decompose the subexpressions further. The code here is + # copied from the else clause, but this condition must appear + # before the contains_aggregate/is_summary condition below. + new_expr, col_cnt = self.rewrite_cols(expr, col_cnt) + new_exprs.append(new_expr) + elif isinstance(expr, Col) or (expr.contains_aggregate and not expr.is_summary): # Reference to column. Make sure the referenced column # is selected. col_cnt += 1 diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py index df44803b8a..bb4e9252b4 100644 --- a/django/db/models/sql/where.py +++ b/django/db/models/sql/where.py @@ -118,6 +118,13 @@ class WhereNode(tree.Node): cols.extend(child.get_group_by_cols()) return cols + def get_source_expressions(self): + return self.children[:] + + def set_source_expressions(self, children): + assert len(children) == len(self.children) + self.children = children + def relabel_aliases(self, change_map): """ Relabels the alias values of any children. 'change_map' is a dictionary @@ -160,6 +167,10 @@ class WhereNode(tree.Node): def contains_aggregate(self): return self._contains_aggregate(self) + @property + def is_summary(self): + return any(child.is_summary for child in self.children) + class NothingNode(object): """ |
