MCPcopy
hub / github.com/django/django / get_qualify_sql

Method get_qualify_sql

django/db/models/sql/compiler.py:660–754  ·  view source on GitHub ↗
(self)

Source from the content-addressed store, hash-verified

658 return part_sql, part_args
659
660 def get_qualify_sql(self):
661 where_parts = []
662 if self.where:
663 where_parts.append(self.where)
664 if self.having:
665 where_parts.append(self.having)
666 inner_query = self.query.clone()
667 inner_query.subquery = True
668 inner_query.where = inner_query.where.__class__(where_parts)
669 # Augment the inner query with any window function references that
670 # might have been masked via values() and alias(). If any masked
671 # aliases are added they'll be masked again to avoid fetching
672 # the data in the `if qual_aliases` branch below.
673 select = {
674 expr: alias for expr, _, alias in self.get_select(with_col_aliases=True)[0]
675 }
676 select_aliases = set(select.values())
677 qual_aliases = set()
678 replacements = {}
679
680 def collect_replacements(expressions):
681 while expressions:
682 expr = expressions.pop()
683 if expr in replacements:
684 continue
685 elif select_alias := select.get(expr):
686 replacements[expr] = select_alias
687 elif isinstance(expr, Lookup):
688 expressions.extend(expr.get_source_expressions())
689 elif isinstance(expr, Ref):
690 if expr.refs not in select_aliases:
691 expressions.extend(expr.get_source_expressions())
692 else:
693 num_qual_alias = len(qual_aliases)
694 select_alias = f"qual{num_qual_alias}"
695 qual_aliases.add(select_alias)
696 inner_query.add_annotation(expr, select_alias)
697 replacements[expr] = select_alias
698
699 collect_replacements(list(self.qualify.leaves()))
700 self.qualify = self.qualify.replace_expressions(
701 {expr: Ref(alias, expr) for expr, alias in replacements.items()}
702 )
703 order_by = []
704 for order_by_expr, *_ in self.get_order_by():
705 collect_replacements(order_by_expr.get_source_expressions())
706 order_by.append(
707 order_by_expr.replace_expressions(
708 {expr: Ref(alias, expr) for expr, alias in replacements.items()}
709 )
710 )
711 inner_query_compiler = inner_query.get_compiler(
712 self.using, connection=self.connection, elide_empty=self.elide_empty
713 )
714 inner_sql, inner_params = inner_query_compiler.as_sql(
715 # The limits must be applied to the outer query to avoid pruning
716 # results too eagerly.
717 with_limits=False,

Callers 1

as_sqlMethod · 0.95

Calls 15

get_selectMethod · 0.95
get_order_byMethod · 0.95
compileMethod · 0.95
RefClass · 0.90
leavesMethod · 0.80
get_compilerMethod · 0.80
extendMethod · 0.80
appendMethod · 0.45
cloneMethod · 0.45
valuesMethod · 0.45
replace_expressionsMethod · 0.45
itemsMethod · 0.45

Tested by

no test coverage detected