|
13 | 13 | from django.db.models.sql import compiler |
14 | 14 | from django.db.models.sql.constants import GET_ITERATOR_CHUNK_SIZE, MULTI, SINGLE |
15 | 15 | from django.db.models.sql.datastructures import BaseTable |
16 | | -from django.db.models.sql.where import AND, OR, XOR, WhereNode |
| 16 | +from django.db.models.sql.where import AND, OR, XOR, NothingNode, WhereNode |
17 | 17 | from django.utils.functional import cached_property |
18 | 18 | from pymongo import ASCENDING, DESCENDING |
19 | 19 |
|
@@ -660,34 +660,41 @@ def get_combinator_queries(self): |
660 | 660 |
|
661 | 661 | def _get_pushable_conditions(self): |
662 | 662 | def collect_pushable(expr, negated=False): |
| 663 | + if isinstance(expr, NothingNode): |
| 664 | + return {} |
663 | 665 | if isinstance(expr, WhereNode): |
664 | | - pushable_expressions = ( |
665 | | - collect_pushable(sub_expr, negated=negated != expr.negated) |
666 | | - for sub_expr in expr.children |
667 | | - ) |
| 666 | + negated = negated != expr.negated |
| 667 | + pushable_expressions = [ |
| 668 | + collect_pushable(sub_expr, negated=negated) for sub_expr in expr.children |
| 669 | + ] |
668 | 670 | operator = expr.connector |
669 | 671 | if operator == XOR: |
670 | 672 | return {} |
671 | 673 | if negated: |
672 | 674 | operator = OR if operator == AND else AND |
673 | | - result = next(pushable_expressions, {}) |
674 | | - shared_alias = set(result) |
| 675 | + alias_children = defaultdict(list) |
| 676 | + shared_alias = None |
| 677 | + result = {} |
675 | 678 | for pe in pushable_expressions: |
676 | | - shared_alias &= set(pe) |
| 679 | + if not shared_alias: |
| 680 | + shared_alias = set(pe) |
| 681 | + else: |
| 682 | + shared_alias &= set(pe) |
677 | 683 | for alias, expressions in pe.items(): |
678 | | - children = [expressions] |
679 | | - if alias in result: |
680 | | - children.append(result[alias]) |
681 | | - result[alias] = WhereNode( |
682 | | - children=children, |
683 | | - negated=negated, |
684 | | - connector=operator, |
685 | | - ) |
| 684 | + alias_children[alias].append(expressions) |
| 685 | + for alias, children in alias_children.items(): |
| 686 | + result[alias] = WhereNode( |
| 687 | + children=children, |
| 688 | + negated=False, |
| 689 | + connector=operator, |
| 690 | + ) |
686 | 691 | if operator == AND: |
687 | 692 | return result |
688 | 693 | return {k: v for k, v in result.items() if k in shared_alias} |
689 | | - if expr.lhs.is_simple_column and ( |
690 | | - is_constant_value(expr.rhs) or expr.rhs.is_simple_column |
| 694 | + if ( |
| 695 | + expr is not None |
| 696 | + and isinstance(expr.lhs, Col) |
| 697 | + and (is_constant_value(expr.rhs) or getattr(expr.rhs, "is_simple_column", False)) |
691 | 698 | ): |
692 | 699 | alias = expr.lhs.alias |
693 | 700 | expr = WhereNode(children=[expr], negated=negated) |
|
0 commit comments