Ticket #10790: ticket10790.diff

File ticket10790.diff, 5.9 KB (added by lrekucki, 3 years ago)

Rebased patch.

  • django/db/models/sql/compiler.py

    diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
    index 72948f9..d940c97 100644
    a b class SQLCompiler(object): 
    456456        """
    457457        if not alias:
    458458            alias = self.query.get_initial_alias()
    459         field, target, opts, joins, _, _ = self.query.setup_joins(pieces,
     459        field, target, opts, joins, _, _, _ = self.query.setup_joins(pieces,
    460460                opts, alias, False)
    461461        alias = joins[-1]
    462462        col = target.column
  • django/db/models/sql/expressions.py

    diff --git a/django/db/models/sql/expressions.py b/django/db/models/sql/expressions.py
    index 1bbf742..af1ed63 100644
    a b class SQLEvaluator(object): 
    4444            self.cols[node] = query.aggregate_select[node.name]
    4545        else:
    4646            try:
    47                 field, source, opts, join_list, last, _ = query.setup_joins(
     47                field, source, opts, join_list, last, _, _ = query.setup_joins(
    4848                    field_list, query.get_meta(),
    4949                    query.get_initial_alias(), False)
    5050                col, _, join_list = query.trim_joins(source, join_list, last, False)
  • django/db/models/sql/query.py

    diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
    index a78df34..630a270 100644
    a b class Query(object): 
    700700            return True
    701701        return False
    702702
     703    def demote_alias(self, alias):
     704        """
     705        Demotes the join type of an alias to an inner join.
     706        """
     707        data = list(self.alias_map[alias])
     708        data[JOIN_TYPE] = self.INNER
     709        self.alias_map[alias] = tuple(data)
     710
    703711    def promote_alias_chain(self, chain, must_promote=False):
    704712        """
    705713        Walks along a chain of aliases, promoting the first nullable join and
    class Query(object): 
    10071015            #   - this is an annotation over a model field
    10081016            # then we need to explore the joins that are required.
    10091017
    1010             field, source, opts, join_list, last, _ = self.setup_joins(
     1018            field, source, opts, join_list, last, _, _ = self.setup_joins(
    10111019                field_list, opts, self.get_initial_alias(), False)
    10121020
    10131021            # Process the join chain to see if it can be trimmed
    class Query(object): 
    11191127        allow_many = trim or not negate
    11201128
    11211129        try:
    1122             field, target, opts, join_list, last, extra_filters = self.setup_joins(
     1130            field, target, opts, join_list, last, extra_filters, allow_trim_join = self.setup_joins(
    11231131                    parts, opts, alias, True, allow_many, allow_explicit_fk=True,
    11241132                    can_reuse=can_reuse, negate=negate,
    11251133                    process_extras=process_extras)
    class Query(object): 
    11391147            self.promote_alias_chain(join_list)
    11401148            join_promote = True
    11411149
     1150        # If we have a one2one or many2one field, we can trim the left outer
     1151        # join from the end of a list of joins.
     1152        # In order to do this, we convert alias join type back to INNER and
     1153        # trim_joins later will do the strip for us.
     1154        if allow_trim_join and field.rel:
     1155            self.demote_alias(join_list[-1])
     1156
    11421157        # Process the join list to see if we can remove any inner joins from
    11431158        # the far end (fewer tables in a query is better).
    11441159        nonnull_comparison = (lookup_type == 'isnull' and value is False)
    class Query(object): 
    12951310        dupe_set = set()
    12961311        exclusions = set()
    12971312        extra_filters = []
     1313        allow_trim_join = True
    12981314        int_alias = None
    12991315        for pos, name in enumerate(names):
    13001316            if int_alias is not None:
    class Query(object): 
    13181334                    raise FieldError("Cannot resolve keyword %r into field. "
    13191335                            "Choices are: %s" % (name, ", ".join(names)))
    13201336
     1337            # presence of indirect field in the filter requires
     1338            # left outer join for isnull
     1339            if not direct and allow_trim_join:
     1340                allow_trim_join = False
     1341
    13211342            if not allow_many and (m2m or not direct):
    13221343                for alias in joins:
    13231344                    self.unref_alias(alias)
    class Query(object): 
    13591380                extra_filters.extend(field.extra_filters(names, pos, negate))
    13601381            if direct:
    13611382                if m2m:
     1383                    # null query on m2mfield requires outer join
     1384                    allow_trim_join = False
    13621385                    # Many-to-many field defined on the current model.
    13631386                    if cached_data:
    13641387                        (table1, from_col1, to_col1, table2, from_col2,
    class Query(object): 
    14791502            else:
    14801503                raise FieldError("Join on field %r not permitted." % name)
    14811504
    1482         return field, target, opts, joins, last, extra_filters
     1505        return field, target, opts, joins, last, extra_filters, allow_trim_join
    14831506
    14841507    def trim_joins(self, target, join_list, last, trim, nonnull_check=False):
    14851508        """
    class Query(object): 
    16481671
    16491672        try:
    16501673            for name in field_names:
    1651                 field, target, u2, joins, u3, u4 = self.setup_joins(
     1674                field, target, u2, joins, u3, u4, allow_trim_join = self.setup_joins(
    16521675                        name.split(LOOKUP_SEP), opts, alias, False, allow_m2m,
    16531676                        True)
    16541677                final_alias = joins[-1]
    class Query(object): 
    19301953        """
    19311954        opts = self.model._meta
    19321955        alias = self.get_initial_alias()
    1933         field, col, opts, joins, last, extra = self.setup_joins(
     1956        field, col, opts, joins, last, extra, allow_trim_join = self.setup_joins(
    19341957                start.split(LOOKUP_SEP), opts, alias, False)
    19351958        select_col = self.alias_map[joins[1]][LHS_JOIN_COL]
    19361959        select_alias = alias
Back to Top