A preprocessor for the internal _add_q(). Responsible for doing final join promotion.
(self, q_object, reuse_all=False)
| 1660 | self.add_q(Q((filter_lhs, filter_rhs))) |
| 1661 | |
| 1662 | def add_q(self, q_object, reuse_all=False): |
| 1663 | """ |
| 1664 | A preprocessor for the internal _add_q(). Responsible for doing final |
| 1665 | join promotion. |
| 1666 | """ |
| 1667 | # For join promotion this case is doing an AND for the added q_object |
| 1668 | # and existing conditions. So, any existing inner join forces the join |
| 1669 | # type to remain inner. Existing outer joins can however be demoted. |
| 1670 | # (Consider case where rel_a is LOUTER and rel_a__col=1 is added - if |
| 1671 | # rel_a doesn't produce any rows, then the whole condition must fail. |
| 1672 | # So, demotion is OK. |
| 1673 | existing_inner = { |
| 1674 | a for a in self.alias_map if self.alias_map[a].join_type == INNER |
| 1675 | } |
| 1676 | if reuse_all: |
| 1677 | can_reuse = set(self.alias_map) |
| 1678 | else: |
| 1679 | can_reuse = self.used_aliases |
| 1680 | clause, _ = self._add_q(q_object, can_reuse) |
| 1681 | if clause: |
| 1682 | self.where.add(clause, AND) |
| 1683 | self.demote_joins(existing_inner) |
| 1684 | |
| 1685 | def build_where(self, filter_expr): |
| 1686 | return self.build_filter(filter_expr, allow_joins=False)[0] |
no test coverage detected