Opened 4 years ago

Last modified 4 years ago

#32116 closed Bug

EmptyQuerySet union with a single other queryset and order by results in DatabaseError — at Version 3

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 Hannes Ljungberg)

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 (3)

comment:2 by Hannes Ljungberg, 4 years ago

Has patch: set

comment:3 by Hannes Ljungberg, 4 years ago

Description: modified (diff)
Summary: EmptyQuerySet union with a single other queryset results in DatabaseErrorEmptyQuerySet union with a single other queryset and order by results in DatabaseError
Note: See TracTickets for help on using tickets.
Back to Top