Fixed #10290: do not use aliases when adding extra_selects to the GROUP BY clause, to generate compliant sql that will be accepted by Oracle.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@9905 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
86a048b4e0
commit
8ffe8981f6
|
@ -392,18 +392,21 @@ class BaseQuery(object):
|
||||||
result.append('AND')
|
result.append('AND')
|
||||||
result.append(' AND '.join(self.extra_where))
|
result.append(' AND '.join(self.extra_where))
|
||||||
|
|
||||||
grouping = self.get_grouping()
|
grouping, gb_params = self.get_grouping()
|
||||||
if grouping:
|
if grouping:
|
||||||
if ordering:
|
if ordering:
|
||||||
# If the backend can't group by PK (i.e., any database
|
# If the backend can't group by PK (i.e., any database
|
||||||
# other than MySQL), then any fields mentioned in the
|
# other than MySQL), then any fields mentioned in the
|
||||||
# ordering clause needs to be in the group by clause.
|
# ordering clause needs to be in the group by clause.
|
||||||
if not self.connection.features.allows_group_by_pk:
|
if not self.connection.features.allows_group_by_pk:
|
||||||
grouping.extend([str(col) for col in ordering_group_by
|
for col, col_params in ordering_group_by:
|
||||||
if col not in grouping])
|
if col not in grouping:
|
||||||
|
grouping.append(str(col))
|
||||||
|
gb_params.extend(col_params)
|
||||||
else:
|
else:
|
||||||
ordering = self.connection.ops.force_no_ordering()
|
ordering = self.connection.ops.force_no_ordering()
|
||||||
result.append('GROUP BY %s' % ', '.join(grouping))
|
result.append('GROUP BY %s' % ', '.join(grouping))
|
||||||
|
params.extend(gb_params)
|
||||||
|
|
||||||
if having:
|
if having:
|
||||||
result.append('HAVING %s' % having)
|
result.append('HAVING %s' % having)
|
||||||
|
@ -710,17 +713,22 @@ class BaseQuery(object):
|
||||||
Returns a tuple representing the SQL elements in the "group by" clause.
|
Returns a tuple representing the SQL elements in the "group by" clause.
|
||||||
"""
|
"""
|
||||||
qn = self.quote_name_unless_alias
|
qn = self.quote_name_unless_alias
|
||||||
result = []
|
result, params = [], []
|
||||||
if self.group_by is not None:
|
if self.group_by is not None:
|
||||||
group_by = self.group_by or []
|
group_by = self.group_by or []
|
||||||
for col in group_by + self.related_select_cols + self.extra_select.keys():
|
|
||||||
|
extra_selects = []
|
||||||
|
for extra_select, extra_params in self.extra_select.itervalues():
|
||||||
|
extra_selects.append(extra_select)
|
||||||
|
params.extend(extra_params)
|
||||||
|
for col in group_by + self.related_select_cols + extra_selects:
|
||||||
if isinstance(col, (list, tuple)):
|
if isinstance(col, (list, tuple)):
|
||||||
result.append('%s.%s' % (qn(col[0]), qn(col[1])))
|
result.append('%s.%s' % (qn(col[0]), qn(col[1])))
|
||||||
elif hasattr(col, 'as_sql'):
|
elif hasattr(col, 'as_sql'):
|
||||||
result.append(col.as_sql(qn))
|
result.append(col.as_sql(qn))
|
||||||
else:
|
else:
|
||||||
result.append(str(col))
|
result.append(str(col))
|
||||||
return result
|
return result, params
|
||||||
|
|
||||||
def get_ordering(self):
|
def get_ordering(self):
|
||||||
"""
|
"""
|
||||||
|
@ -768,7 +776,7 @@ class BaseQuery(object):
|
||||||
else:
|
else:
|
||||||
order = asc
|
order = asc
|
||||||
result.append('%s %s' % (field, order))
|
result.append('%s %s' % (field, order))
|
||||||
group_by.append(field)
|
group_by.append((field, []))
|
||||||
continue
|
continue
|
||||||
col, order = get_order_dir(field, asc)
|
col, order = get_order_dir(field, asc)
|
||||||
if col in self.aggregate_select:
|
if col in self.aggregate_select:
|
||||||
|
@ -783,7 +791,7 @@ class BaseQuery(object):
|
||||||
processed_pairs.add((table, col))
|
processed_pairs.add((table, col))
|
||||||
if not distinct or elt in select_aliases:
|
if not distinct or elt in select_aliases:
|
||||||
result.append('%s %s' % (elt, order))
|
result.append('%s %s' % (elt, order))
|
||||||
group_by.append(elt)
|
group_by.append((elt, []))
|
||||||
elif get_order_dir(field)[0] not in self.extra_select:
|
elif get_order_dir(field)[0] not in self.extra_select:
|
||||||
# 'col' is of the form 'field' or 'field1__field2' or
|
# 'col' is of the form 'field' or 'field1__field2' or
|
||||||
# '-field1__field2__field', etc.
|
# '-field1__field2__field', etc.
|
||||||
|
@ -795,13 +803,13 @@ class BaseQuery(object):
|
||||||
if distinct and elt not in select_aliases:
|
if distinct and elt not in select_aliases:
|
||||||
ordering_aliases.append(elt)
|
ordering_aliases.append(elt)
|
||||||
result.append('%s %s' % (elt, order))
|
result.append('%s %s' % (elt, order))
|
||||||
group_by.append(elt)
|
group_by.append((elt, []))
|
||||||
else:
|
else:
|
||||||
elt = qn2(col)
|
elt = qn2(col)
|
||||||
if distinct and col not in select_aliases:
|
if distinct and col not in select_aliases:
|
||||||
ordering_aliases.append(elt)
|
ordering_aliases.append(elt)
|
||||||
result.append('%s %s' % (elt, order))
|
result.append('%s %s' % (elt, order))
|
||||||
group_by.append(elt)
|
group_by.append(self.extra_select[col])
|
||||||
self.ordering_aliases = ordering_aliases
|
self.ordering_aliases = ordering_aliases
|
||||||
return result, group_by
|
return result, group_by
|
||||||
|
|
||||||
|
|
|
@ -230,6 +230,12 @@ FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, conta
|
||||||
>>> Book.objects.annotate(num_authors=Count('authors')).filter(num_authors=2).dates('pubdate', 'day')
|
>>> Book.objects.annotate(num_authors=Count('authors')).filter(num_authors=2).dates('pubdate', 'day')
|
||||||
[datetime.datetime(1995, 1, 15, 0, 0), datetime.datetime(2007, 12, 6, 0, 0)]
|
[datetime.datetime(1995, 1, 15, 0, 0), datetime.datetime(2007, 12, 6, 0, 0)]
|
||||||
|
|
||||||
|
# Regression for #10290 - extra selects with parameters can be used for
|
||||||
|
# grouping.
|
||||||
|
>>> qs = Book.objects.all().annotate(mean_auth_age=Avg('authors__age')).extra(select={'sheets' : '(pages + %s) / %s'}, select_params=[1, 2]).order_by('sheets').values('sheets')
|
||||||
|
>>> [int(x['sheets']) for x in qs]
|
||||||
|
[150, 175, 224, 264, 473, 566]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue