Opened 4 years ago
Closed 4 years ago
#32116 closed Bug (fixed)
QuerySet.order_by() crashes on union() queryset with a single non-empty query.
Reported by: | Hannes Ljungberg | Owned by: | hannes ljungberg |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I noticed this error while implementing a dynamic union like this:
union = reduce( lambda qs1, qs2: qs1.union(qs2), querysets, queryset.none(), )
If len(querysets) == 1
it will result in a pretty weird query throwing a database error when both querysets are ordered, another example recreating this in the test suite:
qs1 = Number.objects.all().order_by(‘pk’) qs2 = Number.objects.none().union(qs1).order_by(‘pk’)
Executing qs2
result in the following query:
(SELECT "queries_number"."id", "queries_number"."num", "queries_number"."other_num", "queries_number"."another_num" FROM "queries_number" ORDER BY "queries_number"."id" ASC) ORDER BY (1) ASC
Result in the following error on PostgresSQL:
psycopg2.errors.SyntaxError: multiple ORDER BY clauses not allowed LINE 1: ...umber" ORDER BY "queries_number"."id" DESC) ORDER BY (1) ASC
And sqlite:
django.db.utils.DatabaseError: ORDER BY not allowed in subqueries of compound statements.
MySQL seems to accept this query but it's most likely not the query the user expects the be executed.
My proposal is to simply return the non-empty query and make the union
a no-op set in this case.
Change History (8)
comment:1 by , 4 years ago
comment:2 by , 4 years ago
Has patch: | set |
---|
comment:3 by , 4 years ago
Description: | modified (diff) |
---|---|
Summary: | EmptyQuerySet union with a single other queryset results in DatabaseError → EmptyQuerySet union with a single other queryset and order by results in DatabaseError |
comment:4 by , 4 years ago
Summary: | EmptyQuerySet union with a single other queryset and order by results in DatabaseError → QuerySet.order_by() crashes on combined queryset with a single non-empty query. |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:5 by , 4 years ago
Raising django.db.utils.DatabaseError: ORDER BY not allowed in subqueries of compound statements.
is not a big issue IMO, I would say that is a cleanup. However it generates and incorrect SQL after 2cbd3967e0a51eab993df89679046d25ec78baec which should be fixed as a bug.
comment:6 by , 4 years ago
Summary: | QuerySet.order_by() crashes on combined queryset with a single non-empty query. → QuerySet.order_by() crashes on union() queryset with a single non-empty query. |
---|
comment:7 by , 4 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
PR: https://github.com/django/django/pull/13553