#23622: Subquery doesn't respect order when not bound to a __pk__ field.
----------------------------------------------+----------------------------
Reporter: ris | Owner: nobody
Type: Bug | Status: new
Component: Database layer (models, ORM) | Version: 1.7
Severity: Normal | Keywords: subquery order
Triage Stage: Unreviewed | distinct
Easy pickings: 0 | Has patch: 0
| UI/UX: 0
----------------------------------------------+----------------------------
Fix for bug #20600 doesn't seem to have covered all cases.
Using django git fa4b6482df08d308fe88044b8c8bf981c6225fb8 (stable/1.7.x),
postgres backend.
Example models.py:
{{{
class ModelA ( models.Model ):
pass
class ModelB ( models.Model ):
modela_fk = models.ForeignKey ( ModelA )
field_b0 = models.IntegerField ( null = True )
field_b1 = models.DateField ()
}}}
Enter some data:
{{{
import datetime
a1 = ModelA ()
a1.save ()
a2 = ModelA ()
a2.save ()
ModelB ( modela_fk = a1 , field_b0 = 123 , field_b1 = datetime.date ( 2013
, 1 , 6 ) ).save ()
ModelB ( modela_fk = a1 , field_b0 = 23 , field_b1 = datetime.date ( 2011
, 6 , 6 ) ).save ()
ModelB ( modela_fk = a1 , field_b0 = 234 , field_b1 = datetime.date ( 2011
, 9 , 2 ) ).save ()
ModelB ( modela_fk = a1 , field_b0 = 12 , field_b1 = datetime.date ( 2012
, 9 , 15 ) ).save ()
ModelB ( modela_fk = a2 , field_b0 = 567 , field_b1 = datetime.date ( 2014
, 3 , 1 ) ).save ()
ModelB ( modela_fk = a2 , field_b0 = 76 , field_b1 = datetime.date ( 2011
, 3 , 3 ) ).save ()
ModelB ( modela_fk = a2 , field_b0 = 7 , field_b1 = datetime.date ( 2012 ,
10 , 20 ) ).save ()
ModelB ( modela_fk = a2 , field_b0 = 56 , field_b1 = datetime.date ( 2011
, 1 , 27 ) ).save ()
}}}
Some queries:
{{{
qx = (
Q ( modelb__pk__in = ModelB.objects.order_by ( "modela_fk" ,
"-field_b1" ).distinct ( "modela_fk" ) )
& Q ( modelb__field_b0__gte = 50 )
)
qy = (
Q ( modelb__in = ModelB.objects.order_by ( "modela_fk" ,
"-field_b1" ).distinct ( "modela_fk" ) )
& Q ( modelb__field_b0__gte = 50 )
)
}}}
(only difference being {{{modelb__pk__in}}} vs {{{modelb__in}}})
and...
{{{
>>> frozenset ( ModelA.objects.filter ( qx ).values_list ( "pk" , flat =
True ) ) == frozenset ( ModelA.objects.filter ( qy ).values_list ( "pk" ,
flat = True ) )
False
}}}
We see this is because
{{{
>>> str ( ModelA.objects.filter ( qx ).query )
'SELECT "dummy_modela"."id" FROM "dummy_modela" INNER JOIN "dummy_modelb"
ON ( "dummy_modela"."id" = "dummy_modelb"."modela_fk_id" ) WHERE
("dummy_modelb"."id" IN (SELECT DISTINCT ON
("dummy_modelb"."modela_fk_id") "dummy_modelb"."id" FROM "dummy_modelb"
ORDER BY "dummy_modelb"."modela_fk_id" ASC, "dummy_modelb"."field_b1"
DESC) AND "dummy_modelb"."field_b0" >= 50)'
>>> str ( ModelA.objects.filter ( qy ).query )
'SELECT "dummy_modela"."id" FROM "dummy_modela" INNER JOIN "dummy_modelb"
ON ( "dummy_modela"."id" = "dummy_modelb"."modela_fk_id" ) WHERE
("dummy_modelb"."id" IN (SELECT DISTINCT ON
("dummy_modelb"."modela_fk_id") "dummy_modelb"."id" FROM "dummy_modelb")
AND "dummy_modelb"."field_b0" >= 50)'
}}}
{{{qy}}}'s SQL is missing the ORDER BY clause. This is a bit of an
unexpected gotcha.
--
Ticket URL: <https://code.djangoproject.com/ticket/23622>
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/046.f3a01d7f990d50a8a5fd282d1051f143%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.