Skip to content

Commit aa4484b

Browse files
committed
Fix memory leak in SQLCompiler._get_pushable_conditions()
1 parent fecc776 commit aa4484b

File tree

1 file changed

+49
-49
lines changed

1 file changed

+49
-49
lines changed

django_mongodb_backend/compiler.py

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -661,61 +661,61 @@ def get_combinator_queries(self):
661661
combinator_pipeline.append({"$unset": "_id"})
662662
return combinator_pipeline
663663

664-
def _get_pushable_conditions(self):
665-
"""
666-
Return a dict mapping each alias to a WhereNode holding its pushable
667-
condition.
668-
"""
669-
670-
def collect_pushable(expr, negated=False):
671-
if expr is None or isinstance(expr, NothingNode):
664+
@classmethod
665+
def _collect_pushable(cls, expr, negated=False):
666+
if expr is None or isinstance(expr, NothingNode):
667+
return {}
668+
if isinstance(expr, WhereNode):
669+
# Apply De Morgan: track negation so connectors are flipped
670+
# when needed.
671+
negated ^= expr.negated
672+
pushable_expressions = [
673+
cls._collect_pushable(sub_expr, negated=negated)
674+
for sub_expr in expr.children
675+
if sub_expr is not None
676+
]
677+
operator = expr.connector
678+
if operator == XOR:
672679
return {}
673-
if isinstance(expr, WhereNode):
674-
# Apply De Morgan: track negation so connectors are flipped
675-
# when needed.
676-
negated ^= expr.negated
677-
pushable_expressions = [
678-
collect_pushable(sub_expr, negated=negated)
679-
for sub_expr in expr.children
680-
if sub_expr is not None
681-
]
682-
operator = expr.connector
683-
if operator == XOR:
684-
return {}
685-
if negated:
686-
operator = OR if operator == AND else AND
687-
alias_children = defaultdict(list)
688-
for pe in pushable_expressions:
689-
for alias, expressions in pe.items():
690-
alias_children[alias].append(expressions)
691-
# Build per-alias pushable condition nodes.
692-
if operator == AND:
693-
return {
694-
alias: WhereNode(children=children, negated=False, connector=operator)
695-
for alias, children in alias_children.items()
696-
}
697-
# Only aliases shared across all branches are pushable for OR.
698-
shared_alias = (
699-
set.intersection(*(set(pe) for pe in pushable_expressions))
700-
if pushable_expressions
701-
else set()
702-
)
680+
if negated:
681+
operator = OR if operator == AND else AND
682+
alias_children = defaultdict(list)
683+
for pe in pushable_expressions:
684+
for alias, expressions in pe.items():
685+
alias_children[alias].append(expressions)
686+
# Build per-alias pushable condition nodes.
687+
if operator == AND:
703688
return {
704689
alias: WhereNode(children=children, negated=False, connector=operator)
705690
for alias, children in alias_children.items()
706-
if alias in shared_alias
707691
}
708-
# A leaf is pushable only when comparing a field to a constant or
709-
# simple value.
710-
if isinstance(expr.lhs, Col) and (
711-
is_constant_value(expr.rhs) or getattr(expr.rhs, "is_simple_column", False)
712-
):
713-
alias = expr.lhs.alias
714-
expr = WhereNode(children=[expr], negated=negated)
715-
return {alias: expr}
716-
return {}
692+
# Only aliases shared across all branches are pushable for OR.
693+
shared_alias = (
694+
set.intersection(*(set(pe) for pe in pushable_expressions))
695+
if pushable_expressions
696+
else set()
697+
)
698+
return {
699+
alias: WhereNode(children=children, negated=False, connector=operator)
700+
for alias, children in alias_children.items()
701+
if alias in shared_alias
702+
}
703+
# A leaf is pushable only when comparing a field to a constant or
704+
# simple value.
705+
if isinstance(expr.lhs, Col) and (
706+
is_constant_value(expr.rhs) or getattr(expr.rhs, "is_simple_column", False)
707+
):
708+
alias = expr.lhs.alias
709+
expr = WhereNode(children=[expr], negated=negated)
710+
return {alias: expr}
711+
return {}
717712

718-
return collect_pushable(self.get_where())
713+
def _get_pushable_conditions(self):
714+
"""
715+
Return a dict mapping each alias to a WhereNode holding its pushable
716+
condition.
717+
"""
718+
return self._collect_pushable(self.get_where())
719719

720720
def get_lookup_pipeline(self):
721721
result = []

0 commit comments

Comments
 (0)