Fixed #9406 -- Ensure that each database column is only represented once in the
"ORDER BY" clause of an SQL statement. git-svn-id: http://code.djangoproject.com/svn/django/trunk@9251 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
e3aa9a2828
commit
9319dc496c
|
@ -621,6 +621,12 @@ class Query(object):
|
||||||
asc, desc = ORDER_DIR['ASC']
|
asc, desc = ORDER_DIR['ASC']
|
||||||
else:
|
else:
|
||||||
asc, desc = ORDER_DIR['DESC']
|
asc, desc = ORDER_DIR['DESC']
|
||||||
|
|
||||||
|
# It's possible, due to model inheritance, that normal usage might try
|
||||||
|
# to include the same field more than once in the ordering. We track
|
||||||
|
# the table/column pairs we use and discard any after the first use.
|
||||||
|
processed_pairs = set()
|
||||||
|
|
||||||
for field in ordering:
|
for field in ordering:
|
||||||
if field == '?':
|
if field == '?':
|
||||||
result.append(self.connection.ops.random_function_sql())
|
result.append(self.connection.ops.random_function_sql())
|
||||||
|
@ -638,18 +644,22 @@ class Query(object):
|
||||||
# on verbatim.
|
# on verbatim.
|
||||||
col, order = get_order_dir(field, asc)
|
col, order = get_order_dir(field, asc)
|
||||||
table, col = col.split('.', 1)
|
table, col = col.split('.', 1)
|
||||||
elt = '%s.%s' % (qn(table), col)
|
if (table, col) not in processed_pairs:
|
||||||
if not distinct or elt in select_aliases:
|
elt = '%s.%s' % (qn(table), col)
|
||||||
result.append('%s %s' % (elt, order))
|
processed_pairs.add((table, col))
|
||||||
|
if not distinct or elt in select_aliases:
|
||||||
|
result.append('%s %s' % (elt, order))
|
||||||
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.
|
||||||
for table, col, order in self.find_ordering_name(field,
|
for table, col, order in self.find_ordering_name(field,
|
||||||
self.model._meta, default_order=asc):
|
self.model._meta, default_order=asc):
|
||||||
elt = '%s.%s' % (qn(table), qn2(col))
|
if (table, col) not in processed_pairs:
|
||||||
if distinct and elt not in select_aliases:
|
elt = '%s.%s' % (qn(table), qn2(col))
|
||||||
ordering_aliases.append(elt)
|
processed_pairs.add((table, col))
|
||||||
result.append('%s %s' % (elt, order))
|
if distinct and elt not in select_aliases:
|
||||||
|
ordering_aliases.append(elt)
|
||||||
|
result.append('%s %s' % (elt, order))
|
||||||
else:
|
else:
|
||||||
col, order = get_order_dir(field, asc)
|
col, order = get_order_dir(field, asc)
|
||||||
elt = qn2(col)
|
elt = qn2(col)
|
||||||
|
|
|
@ -257,4 +257,14 @@ DoesNotExist: ArticleWithAuthor matching query does not exist.
|
||||||
# without error.
|
# without error.
|
||||||
>>> _ = QualityControl.objects.create(headline="Problems in Django", pub_date=datetime.datetime.now(), quality=10, assignee="adrian")
|
>>> _ = QualityControl.objects.create(headline="Problems in Django", pub_date=datetime.datetime.now(), quality=10, assignee="adrian")
|
||||||
|
|
||||||
|
# Ordering should not include any database column more than once (this is most
|
||||||
|
# likely to ocurr naturally with model inheritance, so we check it here).
|
||||||
|
# Regression test for #9390. This necessarily pokes at the SQL string for the
|
||||||
|
# query, since the duplicate problems are only apparent at that late stage.
|
||||||
|
>>> sql = ArticleWithAuthor.objects.order_by('pub_date', 'pk').query.as_sql()[0]
|
||||||
|
>>> fragment = sql[sql.find('ORDER BY'):]
|
||||||
|
>>> pos = fragment.find('pub_date')
|
||||||
|
>>> fragment.find('pub_date', pos + 1) == -1
|
||||||
|
True
|
||||||
|
|
||||||
"""}
|
"""}
|
||||||
|
|
Loading…
Reference in New Issue