diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-09-11 02:00:27 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-09-11 02:00:27 +0000 |
| commit | e47cc781d844eea72e677d1d212b2dfd1b0c9225 (patch) | |
| tree | a38b67a85c4a516ca729925ef3e720f6b5fd01ac | |
| parent | 11fd9f2d849c5ab75f0b57cc57ae5035d6e438d8 (diff) | |
A bug from queryset-refactor days: although the Query class has "group_by" and
"having" attributes, only the former was included in the resulting SQL, meaning
subclasses had to completely duplicate Query.as_sql() if they were using any
kind of grouping filtering on the results.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@9007 bcc190cf-cafb-0310-a4f2-bffc1f526a37
| -rw-r--r-- | django/db/models/sql/query.py | 23 | ||||
| -rw-r--r-- | tests/regressiontests/queries/models.py | 13 |
2 files changed, 36 insertions, 0 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index ceaf65cd4d..b4525f1075 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -292,6 +292,11 @@ class Query(object): grouping = self.get_grouping() result.append('GROUP BY %s' % ', '.join(grouping)) + if self.having: + having, h_params = self.get_having() + result.append('HAVING %s' % ', '.join(having)) + params.extend(h_params) + if ordering: result.append('ORDER BY %s' % ', '.join(ordering)) @@ -573,6 +578,24 @@ class Query(object): result.append(str(col)) return result + def get_having(self): + """ + Returns a tuple representing the SQL elements in the "having" clause. + By default, the elements of self.having have their as_sql() method + called or are returned unchanged (if they don't have an as_sql() + method). + """ + result = [] + params = [] + for elt in self.having: + if hasattr(elt, 'as_sql'): + sql, params = elt.as_sql() + result.append(sql) + params.extend(params) + else: + result.append(elt) + return result, params + def get_ordering(self): """ Returns list representing the SQL elements in the "order by" clause. diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py index aa1fa1edfc..49b45e83fd 100644 --- a/tests/regressiontests/queries/models.py +++ b/tests/regressiontests/queries/models.py @@ -953,6 +953,19 @@ relations. >>> len([x[2] for x in q.alias_map.values() if x[2] == q.LOUTER and q.alias_refcount[x[1]]]) 1 +A check to ensure we don't break the internal query construction of GROUP BY +and HAVING. These aren't supported in the public API, but the Query class knows +about them and shouldn't do bad things. +>>> qs = Tag.objects.values_list('parent_id', flat=True).order_by() +>>> qs.query.group_by = ['parent_id'] +>>> qs.query.having = ['count(parent_id) > 1'] +>>> expected = [t3.parent_id, t4.parent_id] +>>> expected.sort() +>>> result = list(qs) +>>> result.sort() +>>> expected == result +True + """} # In Python 2.3 and the Python 2.6 beta releases, exceptions raised in __len__ |
