summaryrefslogtreecommitdiff
path: root/django/db/models/sql/query.py
AgeCommit message (Collapse)Author
2013-03-26Fixed #20091 -- Oracle null promotion for empty stringsAnssi Kääriäinen
2013-03-24Fixed #19385 again, now with real code changesAnssi Kääriäinen
The commit of 266de5f9ae9e9f2fbfaec3b7e4b5fb9941967801 included only tests, this time also code changes included...
2013-03-21Removed unused importAnssi Kääriäinen
2013-03-17Fixed #19635 -- Made fields pickleableAnssi Kääriäinen
2013-03-13Refactored qs.add_q() and utils/tree.pyAnssi Kääriäinen
The sql/query.py add_q method did a lot of where/having tree hacking to get complex queries to work correctly. The logic was refactored so that it should be simpler to understand. The new logic should also produce leaner WHERE conditions. The changes cascade somewhat, as some other parts of Django (like add_filter() and WhereNode) expect boolean trees in certain format or they fail to work. So to fix the add_q() one must fix utils/tree.py, some things in add_filter(), WhereNode and so on. This commit also fixed add_filter to see negate clauses up the path. A query like .exclude(Q(reversefk__in=a_list)) didn't work similarly to .filter(~Q(reversefk__in=a_list)). The reason for this is that only the immediate parent negate clauses were seen by add_filter, and thus a tree like AND: (NOT AND: (AND: condition)) will not be handled correctly, as there is one intermediary AND node in the tree. The example tree is generated by .exclude(~Q(reversefk__in=a_list)). Still, aggregation lost connectors in OR cases, and F() objects and aggregates in same filter clause caused GROUP BY problems on some databases. Fixed #17600, fixed #13198, fixed #17025, fixed #17000, fixed #11293.
2013-03-12Fixed #19964 -- Removed relabel_aliases from some structsAnssi Kääriäinen
Before there was need to have both .relabel_aliases() and .clone() for many structs. Now there is only relabeled_clone() for those structs where alias is the only mutable attribute.
2013-02-28Fixed #12823 -- Was already fixed in master, tests addedAnssi Kääriäinen
Also added a little improvement to sql/query.py to get rid of non-necessary IS NOT NULL check.
2013-02-20Cleaned up join promotion in query.combine() with ORAnssi Kääriäinen
Refs #19849
2013-02-20Removed join() promote kwargAnssi Kääriäinen
The join promote=True was over-aggressive in select_related handling. After that was removed, the only other user was query.combine(). That use case is very easy to handle locally, so there is no more need for the join(promote=True) flag. Refs #19849.
2013-02-20Refactored negated IS NULL handlingAnssi Kääriäinen
This one cleaned up add_filter() negated filter generation. As a side effect split_exclude() was cleaned up, too. Refs #19849
2013-02-19Fixed #19837 -- Refactored split_exclude() join generationAnssi Kääriäinen
The refactoring mainly concentrates on making sure the inner and outer query agree about the split position. The split position is where the multijoin happens, and thus the split position also determines the columns used in the "WHERE col1 IN (SELECT col2 from ...)" condition. This commit fixes a regression caused by #10790 and commit 69597e5bcc89aadafd1b76abf7efab30ee0b8b1a. The regression was caused by wrong cols in the split position.
2013-02-10Made Query.clear_ordering force_empty arg mandatoryAnssi Kääriäinen
Previously it was possible to call clear_ordering without the force_empty argument. The result was that the query was still ordered by model's meta ordering if that was defined. By making the arg mandatory it will be easier to spot possible errors caused by assuming clear_ordering will remove all ordering. Thanks to Dylan Klomparens for the suggestion. Refs #19720.
2013-01-08Fixed #16759 -- Remove use of __deepcopy__ in qs.clone()Anssi Kääriäinen
The original problem was that queryset cloning was really expensive when filtering with F() clauses. The __deepcopy__ went too deep copying _meta attributes of the models used. To fix this the use of __deepcopy__ in qs cloning was removed. This commit results in some speed improvements across the djangobench benchmark suite. Most query_* tests are 20-30% faster, save() is 50% faster and finally complex filtering situations can see 2x to order of magnitude improvments. Thanks to Suor, Alex and lrekucki for valuable feedback.
2013-01-06Fixed #19173 -- Made EmptyQuerySet a marker class onlyAnssi Kääriäinen
The guarantee that no queries will be made when accessing results is done by new EmptyWhere class which is used for query.where and having. Thanks to Simon Charette for reviewing and valuable suggestions.
2012-12-30Minor improvement to proxy model handlingAnssi Kääriäinen
Refs #19385
2012-12-30Made use of PathInfo.direct flag in trim_joinsAnssi Kääriäinen
Refs #19385
2012-12-30Added Query.join_parent_model()Anssi Kääriäinen
This simplifies especially compiler.py a lot, where almost the same code was repeated multiple times. Refs #19385
2012-12-30Moved join path generation to FieldAnssi Kääriäinen
Refs #19385
2012-12-30Made sure join_field is always available in .join()Anssi Kääriäinen
Refs #19385
2012-12-20Fixed #18854 -- Join promotion in disjunction casesAnssi Kääriäinen
The added promotion logic is based on promoting any joins used in only some of the childs of an OR clause unless the join existed before the OR clause addition.
2012-12-20Fixed #19500 -- Solved a regression in join reuseAnssi Kääriäinen
The ORM didn't reuse joins for direct foreign key traversals when using chained filters. For example: qs.filter(fk__somefield=1).filter(fk__somefield=2)) produced two joins. As a bonus, reverse onetoone filters can now reuse joins correctly The regression was caused by the join() method refactor in commit 68847135bc9acb2c51c2d36797d0a85395f0cd35 Thanks for Simon Charette for spotting some issues with the first draft of the patch.
2012-12-17Replaced '__' with LOOKUP_SEP in sql/query.pyAnssi Kääriäinen
Thanks to Simon Charette for report.
2012-12-16Fixed #10790 -- Refactored sql.Query.setup_joins()Anssi Kääriäinen
This is a rather large refactoring. The "lookup traversal" code was splitted out from the setup_joins. There is now names_to_path() method which does the lookup traveling, the actual work of setup_joins() is calling names_to_path() and then adding the joins found into the query. As a side effect it was possible to remove the "process_extra" functionality used by genric relations. This never worked for left joins. Now the extra restriction is appended directly to the join condition instead of the where clause. To generate the extra condition we need to have the join field available in the compiler. This has the side-effect that we need more ugly code in Query.__getstate__ and __setstate__ as Field objects aren't pickleable. The join trimming code got a big change - now we trim all direct joins and never trim reverse joins. This also fixes the problem in #10790 which was join trimming in null filter cases.
2012-12-16Fixed #18816 -- Removed "trim" argument from add_filter()Anssi Kääriäinen
The trim argument was used by split_exclude() only to trim the last join from the given lookup. It is cleaner to just trim the last part from the lookup in split_exclude() directly so that there is no need to burden add_filter() with the logic needed for only split_exclude().
2012-11-28Fixed #14694 -- Made ``defer()`` work with reverse relationsTai Lee
Reverse o2o fields are now usable with defer.
2012-11-24Updated stale docstring of setup_joinsAnssi Kääriäinen
2012-11-23Fixed #18375 -- Removed dict-ordering dependency for F-expressionsAnssi Kääriäinen
F() expressions reuse joins like any lookup in a .filter() call - reuse multijoins generated in the same .filter() call else generate new joins. Also, lookups can now reuse joins generated by F(). This change is backwards incompatible, but it is required to prevent dict randomization from generating different queries depending on .filter() kwarg ordering. The new way is also more consistent in how joins are reused.
2012-11-13Removed use of SortedDict for query.alias_refcountAnssi Kääriäinen
This will have a smallish impact on performance. Refs #19276.
2012-10-31Removed dupe_avoidance from sql/query and sql/compiler.pyAnssi Kääriäinen
The dupe avoidance logic was removed as it doesn't seem to do anything, it is complicated, and it has nearly zero documentation. The removal of dupe_avoidance allowed for refactoring of both the implementation and signature of Query.join(). This refactoring cascades again to some other parts. The most significant of them is the changes in qs.combine(), and compiler.select_related_descent().
2012-10-27Fixed #19190 -- Refactored Query select clause attributesAnssi Kääriäinen
The Query.select and Query.select_fields were collapsed into one list because the attributes had to be always in sync. Now that they are in one attribute it is impossible to edit them out of sync. Similar collapse was done for Query.related_select_cols and Query.related_select_fields.
2012-10-25Fixed regression caused by #19102Anssi Kääriäinen
2012-10-25Fixed #19102 -- Fixed fast-path delete for modified SELECT clause casesAnssi Kääriäinen
There was a bug introduced in #18676 which caused fast-path deletes implemented as "DELETE WHERE pk IN <subquery>" to fail if the SELECT clause contained additional stuff (for example extra() and annotate()). Thanks to Trac alias pressureman for spotting this regression.
2012-10-08Fixed #19087 -- Ensured query's base table is never LOUTER joinedAnssi Kääriäinen
This fixes a regression created by join promotion logic refactoring: 01b9c3d5193fe61b82ae8b26242a13fdec22f211 Thanks to Ivan Virabyan for the report.
2012-09-08Internal refactoring; moving LOOKUP_SEP up one level.Malcolm Tredinnick
In an ideal world, nothing except django.db.models.query should have to import stuff from django.models.sql.*. A few things were needing to get hold of sql.constants.LOOKUP_SEP, so this commit moves it up to django.db.models.constants.LOOKUP_SEP. There are still a couple of places (admin) poking into sql.* to get QUERY_TERMS, which is unfortunate, but a slightly different issue and harder to adjust.
2012-09-07Cleaned up some small bits of the ORM, including removing an import *.Alex Gaynor
2012-08-25Fixed #16715 -- Fixed join promotion logic for nested nullable FKsAnssi Kääriäinen
The joins for nested nullable foreign keys were often created as INNER when they should have been OUTER joins. The reason was that only the first join in the chain was promoted correctly. There were also issues with select_related etc. The basic structure for this problem was: A -[nullable]-> B -[nonnull]-> C And the basic problem was that the A->B join was correctly LOUTER, the B->C join not. The major change taken in this patch is that now if we promote a join A->B, we will automatically promote joins B->X for all X in the query. Also, we now make sure there aren't ever join chains like: a LOUTER b INNER c If the a -> b needs to be LOUTER, then the INNER at the end of the chain will cancel the LOUTER join and we have a broken query. Sebastian reported this problem and did also major portions of the patch.
2012-08-21Fixed #17886 -- Fixed join promotion in ORed nullable queriesAnssi Kääriäinen
The ORM generated a query with INNER JOIN instead of LEFT OUTER JOIN in a somewhat complicated case. The main issue was that there was a chain of nullable FK -> non-nullble FK, and the join promotion logic didn't see the need to promote the non-nullable FK even if the previous nullable FK was already promoted to LOUTER JOIN. This resulted in a query like a LOUTER b INNER c, which incorrectly prunes results.
2012-08-12Fixed #18731 -- Cleaned up split_exclude's use of can_reuseAnssi Kääriäinen
The outer query's set of reusable joins (can_reuse) was passed to the inner query's add_filter call. This was incorrect.
2012-08-08remove a bunch of unnescesarry iterkeys() callsAlex Gaynor
2012-08-07[py3] Ported django.utils.encoding.Aymeric Augustin
* Renamed smart_unicode to smart_text (but kept the old name under Python 2 for backwards compatibility). * Renamed smart_str to smart_bytes. * Re-introduced smart_str as an alias for smart_text under Python 3 and smart_bytes under Python 2 (which is backwards compatible). Thus smart_str always returns a str objects. * Used the new smart_str in a few places where both Python 2 and 3 want a str.
2012-08-07[py3] Fixed access to dict keys/values/items.Aymeric Augustin
2012-07-17Switched to use a more idiomatic construct.Alex Gaynor
2012-07-17Fixed #17497 -- Corrected FieldError message in add_fields()Anssi Kääriäinen
The erroneous message was user visible in values_list() calls. Thanks to ojii for report and review, and to antoviaque for the patch.
2012-06-26Fixed #17485 -- Made defer work with select_relatedAnssi Kääriäinen
This commit tackles a couple of issues. First, in certain cases there were some mixups if field.attname or field.name should be deferred. Field.attname is now always used. Another issue tackled is a case where field is both deferred by .only(), and selected by select_related. This case is now an error. A lot of thanks to koniiiik (Michal Petrucha) for the patch, and to Andrei Antoukh for review.
2012-05-10Replaced foo.next() by next(foo).Claude Paroz
This new syntax for next() has been introduced in Python 2.6 and is compatible with Python 3.
2012-05-09Fix proxy model Query.remove_inherited_models()Anssi Kääriäinen
Fixed #18248 -- proxy models were added to included_inherited_models in sql.query.Query. The variable is meant to be used for multitable inheritance only. This mistake caused problems in situations where proxy model's query was reused.
2012-04-29Fixed #17644 -- Changed Query.alias_map to use namedtuplesAdrian Holovaty
This makes the code easier to understand and may even have a benefit in memory usage (namedtuples instead of dicts). Thanks, lrekucki and akaariai
2012-04-29Fixed #18013 -- Use the new 'as' syntax for exceptions.Claude Paroz
Thanks Clueless for the initial patch. Note that unittest has been purposely left out (external package only used by Python 2.6).
2012-04-29Removed unused variable from sql/query.pyAnssi Kääriäinen
2012-04-29Prevent Oracle from changing field.null to TrueAnssi Kääriäinen
Fixed #17957 -- when using Oracle and character fields, the fields were set null = True to ease the handling of empty strings. This caused problems when using multiple databases from different vendors, or when the character field happened to be also a primary key. The handling was changed so that NOT NULL is not emitted on Oracle even if field.null = False, and field.null is not touched otherwise. Thanks to bhuztez for the report, ramiro for triaging & comments, ikelly for the patch and alex for reviewing.