#19720: Invalid SQL statement generated when deleting rows in Meta ordered 
tables
(found using Oracle)
----------------------------------------------+----------------------------
     Reporter:  dylan.klomparens@…            |      Owner:  nobody
         Type:  Bug                           |     Status:  new
    Component:  Database layer (models, ORM)  |    Version:  1.5-beta-1
     Severity:  Normal                        |   Keywords:  ORM SQL
 Triage Stage:  Unreviewed                    |  ordering Meta
Easy pickings:  1                             |  Has patch:  1
                                              |      UI/UX:  0
----------------------------------------------+----------------------------
 Given the following example model, invalid SQL deletes are composed in
 Django's ORM. This breaks Django's interaction with Oracle, producing
 error 'ORA-00907'.

 {{{
 from django.db import models
 class OrderedModel(models.Model):
         name = models.CharField(max_length=100)
         class Meta:
                 ordering = ['name']
         def __unicode__(self):
                 return unicode(self.name)
 }}}

 Django's source code comments state that a QuerySet delete is broken into
 two SQL queries: one to find the items to delete, and the second to
 perform the deletion. The general form of this is:

 {{{DELETE FROM "TABLE" WHERE "ID" IN (SEARCH_STATEMENT)}}}

 Thus, there is no reason to order {{{SEARCH_STATEMENT}}}. However, Django
 provides an {{{ORDER BY}}} clause in the {{{SEARCH_STATEMENT}}} when Meta
 ordering is specified. Using the example model shown above, deleting an
 object from the admin interface produces this SQL {{{SEARCH_STATEMENT}}}:

 {{{SELECT "Test_orderedmodel"."id", "Test_orderedmodel"."name" FROM
 "Test_orderedmodel" WHERE "Test_orderedmodel"."id" IN (5, 6) ORDER BY
 "Test_orderedmodel"."name" ASC}}}

 This bug can be remedied by patching function {{{delete()}}} in class
 {{{QuerySet}}} in file {{{$DJANGO_HOME/db/models/query.py}}}, line 525.

 The buggy line is: {{{del_query.query.clear_ordering()}}}
 And it should be: {{{del_query.query.clear_ordering(force_empty=True)}}}

 After the code is patched the example SQL statement becomes:

 {{{SELECT "Test_orderedmodel"."id", "Test_orderedmodel"."name" FROM
 "Test_orderedmodel" WHERE "Test_orderedmodel"."id" IN (5, 6)}}}

 -----

 Further testing reveals that this is an isolated bug.

 I looked for other uses of the {{{clear_ordering()}}} function in Django's
 source code that might cause similar bugs. I found two other usage of the
 function in {{{$DJANGO_HOME/db/models/query.py}}}: one in the
 {{{latest()}}} function and the other in the {{{order_by()}}} function.
 After extensive testing I concluded that Meta ordering '''does not'''
 adversely affect these functions. That said, it may be prudent to make the
 {{{force_empty}}} parameter of the {{{clear_ordering()}}} function an
 explicit parameter instead of providing a default of {{{False}}}. All
 other uses of the {{{clear_ordering()}}} function that I found specify
 {{{force_empty=True}}}.

 I am 99% confident this bug does not adversely affect any other portions
 of Django's code.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/19720>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to