(self, combinator, all)
| 579 | return sql, params |
| 580 | |
| 581 | def get_combinator_sql(self, combinator, all): |
| 582 | features = self.connection.features |
| 583 | compilers = [ |
| 584 | query.get_compiler(self.using, self.connection, self.elide_empty) |
| 585 | for query in self.query.combined_queries |
| 586 | ] |
| 587 | if not features.supports_slicing_ordering_in_compound: |
| 588 | for compiler in compilers: |
| 589 | if compiler.query.is_sliced: |
| 590 | raise DatabaseError( |
| 591 | "LIMIT/OFFSET not allowed in subqueries of compound statements." |
| 592 | ) |
| 593 | if compiler.get_order_by(): |
| 594 | raise DatabaseError( |
| 595 | "ORDER BY not allowed in subqueries of compound statements." |
| 596 | ) |
| 597 | parts = [] |
| 598 | empty_compiler = None |
| 599 | for compiler in compilers: |
| 600 | try: |
| 601 | parts.append(self._get_combinator_part_sql(compiler)) |
| 602 | except EmptyResultSet: |
| 603 | # Omit the empty queryset with UNION and with DIFFERENCE if the |
| 604 | # first queryset is nonempty. |
| 605 | if combinator == "union" or (combinator == "difference" and parts): |
| 606 | empty_compiler = compiler |
| 607 | continue |
| 608 | raise |
| 609 | if not parts: |
| 610 | raise EmptyResultSet |
| 611 | elif len(parts) == 1 and combinator == "union" and self.query.is_sliced: |
| 612 | # A sliced union cannot be composed of a single component because |
| 613 | # in the event the later is also sliced it might result in invalid |
| 614 | # SQL due to the usage of multiple LIMIT clauses. Prevent that from |
| 615 | # happening by always including an empty resultset query to force |
| 616 | # the creation of an union. |
| 617 | empty_compiler.elide_empty = False |
| 618 | parts.append(self._get_combinator_part_sql(empty_compiler)) |
| 619 | combinator_sql = self.connection.ops.set_operators[combinator] |
| 620 | if all and combinator == "union": |
| 621 | combinator_sql += " ALL" |
| 622 | braces = "{}" |
| 623 | if not self.query.subquery and features.supports_slicing_ordering_in_compound: |
| 624 | braces = "({})" |
| 625 | sql_parts, args_parts = zip( |
| 626 | *((braces.format(sql), args) for sql, args in parts) |
| 627 | ) |
| 628 | result = [" {} ".format(combinator_sql).join(sql_parts)] |
| 629 | params = [] |
| 630 | for part in args_parts: |
| 631 | params.extend(part) |
| 632 | return result, params |
| 633 | |
| 634 | def _get_combinator_part_sql(self, compiler): |
| 635 | features = self.connection.features |
no test coverage detected