diff options
Diffstat (limited to 'django/db/models/sql')
| -rw-r--r-- | django/db/models/sql/query.py | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 550e6e323c..e6d653a46e 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -1197,14 +1197,21 @@ class BaseQuery(object): col = target.column alias = join_list[-1] + if (lookup_type == 'isnull' and value is True and not negate and + len(join_list) > 1): + # If the comparison is against NULL, we may need to use some left + # outer joins when creating the join chain. This is only done when + # needed, as it's less efficient at the database level. + self.promote_alias_chain(join_list) + while final > 1: - # An optimization: if the final join is against the same column as - # we are comparing against, we can go back one step in the join - # chain and compare against the lhs of the join instead (and then - # repeat the optimization). The result, potentially, involves less - # table joins. + # An optimization: if the final join is an inner join against the + # same column as we are comparing against, we can go back one step + # in the join chain and compare against the lhs of the join instead + # (and then repeat the optimization). The result, potentially, + # involves less table joins. join = self.alias_map[alias] - if col != join[RHS_JOIN_COL]: + if col != join[RHS_JOIN_COL] or join[JOIN_TYPE] != self.INNER: break self.unref_alias(alias) alias = join[LHS_ALIAS] @@ -1214,14 +1221,6 @@ class BaseQuery(object): if final == penultimate: penultimate = last.pop() - if (lookup_type == 'isnull' and value is True and not negate and - final > 1): - # If the comparison is against NULL, we need to use a left outer - # join when connecting to the previous model. We make that - # adjustment here. We don't do this unless needed as it's less - # efficient at the database level. - self.promote_alias(join_list[penultimate]) - if connector == OR: # Some joins may need to be promoted when adding a new filter to a # disjunction. We walk the list of new joins and where it diverges |
