mirror of
				https://github.com/django/django.git
				synced 2025-11-04 05:35:37 +00:00 
			
		
		
		
	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
					
				
					 2 changed files with 27 additions and 7 deletions
				
			
		| 
						 | 
					@ -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,7 +644,9 @@ 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)
 | 
				
			||||||
 | 
					                if (table, col) not in processed_pairs:
 | 
				
			||||||
                    elt = '%s.%s' % (qn(table), col)
 | 
					                    elt = '%s.%s' % (qn(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))
 | 
				
			||||||
            elif get_order_dir(field)[0] not in self.extra_select:
 | 
					            elif get_order_dir(field)[0] not in self.extra_select:
 | 
				
			||||||
| 
						 | 
					@ -646,7 +654,9 @@ class Query(object):
 | 
				
			||||||
                # '-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):
 | 
				
			||||||
 | 
					                    if (table, col) not in processed_pairs:
 | 
				
			||||||
                        elt = '%s.%s' % (qn(table), qn2(col))
 | 
					                        elt = '%s.%s' % (qn(table), qn2(col))
 | 
				
			||||||
 | 
					                        processed_pairs.add((table, col))
 | 
				
			||||||
                        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))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue