Just like normal queries, combined queries' outer references might fully
resolve before their reference is assigned its final alias.
Refs #29338.
Thanks Antony_K for the report and example, and thanks Mariusz Felisiak
for the review.
While refs #34125 focused on the SQL correctness of slicing of union of
potentially empty queries it missed an optimization opportunity to avoid
performing a query at all when all queries are empty.
Thanks Lucidiot for the report.
Previously the order was always extra_fields + model_fields + annotations with
respective local ordering inferred from the insertion order of *selected.
This commits introduces a new `Query.selected` propery that keeps tracks of the
global select order as specified by on values assignment. This is crucial
feature to allow the combination of queries mixing annotations and table
references.
It also allows the removal of the re-ordering shenanigans perform by
ValuesListIterable in order to re-map the tuples returned from the database
backend to the order specified by values_list() as they'll be in the right
order at query compilation time.
Refs #28553 as the initially reported issue that was only partially fixed
for annotations by d6b6e5d0fd.
Thanks Mariusz Felisiak and Sarah Boyce for review.
The implementation of some core types differ between CPython and PyPy
and this may affect the way that pickling works such that errors are
raised in differing locations in the interpreter or not at all.
Use our own custom non-pickleable type instead to avoid these quirks.
Adjusting WhereNode.as_sql() to raise an exception when encoutering a
full match just like with empty matches ensures that all case are
explicitly handled.
The bug existed since sliced query union was added but was elevated to
query union slices by moving the .exists() optimization to the compiler
in 3d734c09ff.
Thanks Stefan Hammer for the report.
Columns of the left outer most select statement in a combined query
can be referenced by alias just like by index.
This removes combined query ordering by column index and avoids an
unnecessary usage of RawSQL which causes issues for backends that
specialize the treatment of null ordering.
This makes QuerySet.order_by() no longer ignore trailing transforms for
models with Meta.ordering. As a consequence, FieldError is raised in
such cases for non-existent fields.
Thanks to Klaas van Schelven for the report and Mariusz Felisiak for the
review and advice.
Node.create() which has a compatible signature with Node.__init__()
takes in a single `children` argument rather than relying in unpacking
*args in Q.__init__() which calls Node.__init__().
In addition, we were often needing to unpack iterables into *args and
can instead pass a list direct to Node.create().