#22434 closed Bug (fixed)
Ordering is cleared in Subqueries with limits
Reported by: | Owned by: | justhamade | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
This can lead to unexpected and unpredictable results. In my case I had a method on ModelManager that returned custom query. I was interested only in the most recent result:
In [76]: pr = Program.objects.get_all_for_user(98,True) In [77]: print pr[:1].query SELECT "training_program"."id", "training_program"."name", "training_program"."d escription", "training_program"."created", "training_program"."modified", "train ing_program"."created_by_id", "training_program"."status" FROM "training_program " INNER JOIN "training_programuser" ON ( "training_program"."id" = "training_pro gramuser"."program_id" ) WHERE ("training_program"."status" = published AND "tr aining_programuser"."user_id" IN (98) AND "training_programuser"."available_sinc e" <= 2014-04-11 08:40:19.680000 ) ORDER BY "training_programuser"."user_id" DES C, "training_programuser"."available_since" DESC LIMIT 1
The resulting query is as expected. Unfortunately when using this query in another query produces sql which does not give results as expected:
In [78]: print Session.objects.filter(programs__in=pr[:1]).query SELECT "training_session"."id", "training_session"."name", "training_session"."d escription", "training_session"."created", "training_session"."modified", "train ing_session"."created_by_id", "training_session"."areas" FROM "training_session" INNER JOIN "training_program_sessions" ON ( "training_session"."id" = "training _program_sessions"."session_id" ) WHERE "training_program_sessions"."program_id" IN (SELECT "training_program"."id" FROM "training_program" INNER JOIN "training _programuser" ON ( "training_program"."id" = "training_programuser"."program_id" ) WHERE ("training_program"."status" = published AND "training_programuser"."u ser_id" IN (98) AND "training_programuser"."available_since" <= 2014-04-10 13:48 :57.228000 ) LIMIT 1)
There is no ORDER BY clause in sql, so the resulting Program is different then the one in previous example.
Quick fix that worked for me was changing line 408 in django/db/modelse/sql/where.py, to:
if query.low_mark == 0 and query.high_mark is None: query.clear_ordering(True)
Change History (7)
comment:1 by , 11 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 11 years ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Version: | 1.6 → master |
comment:4 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:6 by , 10 years ago
This bug represents a regression; we just upgraded to from Django 1.4 to Django 1.6, we hit this bug, and we had to manually apply the patch to fix it; is there any plan to apply the patch to the 1.6 serie?
comment:7 by , 10 years ago
If the tests that were added here pass on 1.4 we can do the backport. The backport isn't clean though, could you send a PR along with an added mention in the 1.6.6 release notes?
Wrote test and fix in pull request https://github.com/django/django/pull/2550