1. import operator
    
  2. 
    
  3. from django.db import DatabaseError, NotSupportedError, connection
    
  4. from django.db.models import Exists, F, IntegerField, OuterRef, Subquery, Value
    
  5. from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
    
  6. from django.test.utils import CaptureQueriesContext
    
  7. 
    
  8. from .models import Author, Celebrity, ExtraInfo, Number, ReservedName
    
  9. 
    
  10. 
    
  11. @skipUnlessDBFeature("supports_select_union")
    
  12. class QuerySetSetOperationTests(TestCase):
    
  13.     @classmethod
    
  14.     def setUpTestData(cls):
    
  15.         Number.objects.bulk_create(Number(num=i, other_num=10 - i) for i in range(10))
    
  16. 
    
  17.     def assertNumbersEqual(self, queryset, expected_numbers, ordered=True):
    
  18.         self.assertQuerysetEqual(
    
  19.             queryset, expected_numbers, operator.attrgetter("num"), ordered
    
  20.         )
    
  21. 
    
  22.     def test_simple_union(self):
    
  23.         qs1 = Number.objects.filter(num__lte=1)
    
  24.         qs2 = Number.objects.filter(num__gte=8)
    
  25.         qs3 = Number.objects.filter(num=5)
    
  26.         self.assertNumbersEqual(qs1.union(qs2, qs3), [0, 1, 5, 8, 9], ordered=False)
    
  27. 
    
  28.     @skipUnlessDBFeature("supports_select_intersection")
    
  29.     def test_simple_intersection(self):
    
  30.         qs1 = Number.objects.filter(num__lte=5)
    
  31.         qs2 = Number.objects.filter(num__gte=5)
    
  32.         qs3 = Number.objects.filter(num__gte=4, num__lte=6)
    
  33.         self.assertNumbersEqual(qs1.intersection(qs2, qs3), [5], ordered=False)
    
  34. 
    
  35.     @skipUnlessDBFeature("supports_select_intersection")
    
  36.     def test_intersection_with_values(self):
    
  37.         ReservedName.objects.create(name="a", order=2)
    
  38.         qs1 = ReservedName.objects.all()
    
  39.         reserved_name = qs1.intersection(qs1).values("name", "order", "id").get()
    
  40.         self.assertEqual(reserved_name["name"], "a")
    
  41.         self.assertEqual(reserved_name["order"], 2)
    
  42.         reserved_name = qs1.intersection(qs1).values_list("name", "order", "id").get()
    
  43.         self.assertEqual(reserved_name[:2], ("a", 2))
    
  44. 
    
  45.     @skipUnlessDBFeature("supports_select_difference")
    
  46.     def test_simple_difference(self):
    
  47.         qs1 = Number.objects.filter(num__lte=5)
    
  48.         qs2 = Number.objects.filter(num__lte=4)
    
  49.         self.assertNumbersEqual(qs1.difference(qs2), [5], ordered=False)
    
  50. 
    
  51.     def test_union_distinct(self):
    
  52.         qs1 = Number.objects.all()
    
  53.         qs2 = Number.objects.all()
    
  54.         self.assertEqual(len(list(qs1.union(qs2, all=True))), 20)
    
  55.         self.assertEqual(len(list(qs1.union(qs2))), 10)
    
  56. 
    
  57.     def test_union_none(self):
    
  58.         qs1 = Number.objects.filter(num__lte=1)
    
  59.         qs2 = Number.objects.filter(num__gte=8)
    
  60.         qs3 = qs1.union(qs2)
    
  61.         self.assertSequenceEqual(qs3.none(), [])
    
  62.         self.assertNumbersEqual(qs3, [0, 1, 8, 9], ordered=False)
    
  63. 
    
  64.     @skipUnlessDBFeature("supports_select_intersection")
    
  65.     def test_intersection_with_empty_qs(self):
    
  66.         qs1 = Number.objects.all()
    
  67.         qs2 = Number.objects.none()
    
  68.         qs3 = Number.objects.filter(pk__in=[])
    
  69.         self.assertEqual(len(qs1.intersection(qs2)), 0)
    
  70.         self.assertEqual(len(qs1.intersection(qs3)), 0)
    
  71.         self.assertEqual(len(qs2.intersection(qs1)), 0)
    
  72.         self.assertEqual(len(qs3.intersection(qs1)), 0)
    
  73.         self.assertEqual(len(qs2.intersection(qs2)), 0)
    
  74.         self.assertEqual(len(qs3.intersection(qs3)), 0)
    
  75. 
    
  76.     @skipUnlessDBFeature("supports_select_difference")
    
  77.     def test_difference_with_empty_qs(self):
    
  78.         qs1 = Number.objects.all()
    
  79.         qs2 = Number.objects.none()
    
  80.         qs3 = Number.objects.filter(pk__in=[])
    
  81.         self.assertEqual(len(qs1.difference(qs2)), 10)
    
  82.         self.assertEqual(len(qs1.difference(qs3)), 10)
    
  83.         self.assertEqual(len(qs2.difference(qs1)), 0)
    
  84.         self.assertEqual(len(qs3.difference(qs1)), 0)
    
  85.         self.assertEqual(len(qs2.difference(qs2)), 0)
    
  86.         self.assertEqual(len(qs3.difference(qs3)), 0)
    
  87. 
    
  88.     @skipUnlessDBFeature("supports_select_difference")
    
  89.     def test_difference_with_values(self):
    
  90.         ReservedName.objects.create(name="a", order=2)
    
  91.         qs1 = ReservedName.objects.all()
    
  92.         qs2 = ReservedName.objects.none()
    
  93.         reserved_name = qs1.difference(qs2).values("name", "order", "id").get()
    
  94.         self.assertEqual(reserved_name["name"], "a")
    
  95.         self.assertEqual(reserved_name["order"], 2)
    
  96.         reserved_name = qs1.difference(qs2).values_list("name", "order", "id").get()
    
  97.         self.assertEqual(reserved_name[:2], ("a", 2))
    
  98. 
    
  99.     def test_union_with_empty_qs(self):
    
  100.         qs1 = Number.objects.all()
    
  101.         qs2 = Number.objects.none()
    
  102.         qs3 = Number.objects.filter(pk__in=[])
    
  103.         self.assertEqual(len(qs1.union(qs2)), 10)
    
  104.         self.assertEqual(len(qs2.union(qs1)), 10)
    
  105.         self.assertEqual(len(qs1.union(qs3)), 10)
    
  106.         self.assertEqual(len(qs3.union(qs1)), 10)
    
  107.         self.assertEqual(len(qs2.union(qs1, qs1, qs1)), 10)
    
  108.         self.assertEqual(len(qs2.union(qs1, qs1, all=True)), 20)
    
  109.         self.assertEqual(len(qs2.union(qs2)), 0)
    
  110.         self.assertEqual(len(qs3.union(qs3)), 0)
    
  111. 
    
  112.     def test_empty_qs_union_with_ordered_qs(self):
    
  113.         qs1 = Number.objects.order_by("num")
    
  114.         qs2 = Number.objects.none().union(qs1).order_by("num")
    
  115.         self.assertEqual(list(qs1), list(qs2))
    
  116. 
    
  117.     def test_limits(self):
    
  118.         qs1 = Number.objects.all()
    
  119.         qs2 = Number.objects.all()
    
  120.         self.assertEqual(len(list(qs1.union(qs2)[:2])), 2)
    
  121. 
    
  122.     def test_ordering(self):
    
  123.         qs1 = Number.objects.filter(num__lte=1)
    
  124.         qs2 = Number.objects.filter(num__gte=2, num__lte=3)
    
  125.         self.assertNumbersEqual(qs1.union(qs2).order_by("-num"), [3, 2, 1, 0])
    
  126. 
    
  127.     def test_ordering_by_alias(self):
    
  128.         qs1 = Number.objects.filter(num__lte=1).values(alias=F("num"))
    
  129.         qs2 = Number.objects.filter(num__gte=2, num__lte=3).values(alias=F("num"))
    
  130.         self.assertQuerysetEqual(
    
  131.             qs1.union(qs2).order_by("-alias"),
    
  132.             [3, 2, 1, 0],
    
  133.             operator.itemgetter("alias"),
    
  134.         )
    
  135. 
    
  136.     def test_ordering_by_f_expression(self):
    
  137.         qs1 = Number.objects.filter(num__lte=1)
    
  138.         qs2 = Number.objects.filter(num__gte=2, num__lte=3)
    
  139.         self.assertNumbersEqual(qs1.union(qs2).order_by(F("num").desc()), [3, 2, 1, 0])
    
  140. 
    
  141.     def test_ordering_by_f_expression_and_alias(self):
    
  142.         qs1 = Number.objects.filter(num__lte=1).values(alias=F("other_num"))
    
  143.         qs2 = Number.objects.filter(num__gte=2, num__lte=3).values(alias=F("other_num"))
    
  144.         self.assertQuerysetEqual(
    
  145.             qs1.union(qs2).order_by(F("alias").desc()),
    
  146.             [10, 9, 8, 7],
    
  147.             operator.itemgetter("alias"),
    
  148.         )
    
  149.         Number.objects.create(num=-1)
    
  150.         self.assertQuerysetEqual(
    
  151.             qs1.union(qs2).order_by(F("alias").desc(nulls_last=True)),
    
  152.             [10, 9, 8, 7, None],
    
  153.             operator.itemgetter("alias"),
    
  154.         )
    
  155. 
    
  156.     def test_union_with_values(self):
    
  157.         ReservedName.objects.create(name="a", order=2)
    
  158.         qs1 = ReservedName.objects.all()
    
  159.         reserved_name = qs1.union(qs1).values("name", "order", "id").get()
    
  160.         self.assertEqual(reserved_name["name"], "a")
    
  161.         self.assertEqual(reserved_name["order"], 2)
    
  162.         reserved_name = qs1.union(qs1).values_list("name", "order", "id").get()
    
  163.         self.assertEqual(reserved_name[:2], ("a", 2))
    
  164.         # List of columns can be changed.
    
  165.         reserved_name = qs1.union(qs1).values_list("order").get()
    
  166.         self.assertEqual(reserved_name, (2,))
    
  167. 
    
  168.     def test_union_with_two_annotated_values_list(self):
    
  169.         qs1 = (
    
  170.             Number.objects.filter(num=1)
    
  171.             .annotate(
    
  172.                 count=Value(0, IntegerField()),
    
  173.             )
    
  174.             .values_list("num", "count")
    
  175.         )
    
  176.         qs2 = (
    
  177.             Number.objects.filter(num=2)
    
  178.             .values("pk")
    
  179.             .annotate(
    
  180.                 count=F("num"),
    
  181.             )
    
  182.             .annotate(
    
  183.                 num=Value(1, IntegerField()),
    
  184.             )
    
  185.             .values_list("num", "count")
    
  186.         )
    
  187.         self.assertCountEqual(qs1.union(qs2), [(1, 0), (2, 1)])
    
  188. 
    
  189.     def test_union_with_extra_and_values_list(self):
    
  190.         qs1 = (
    
  191.             Number.objects.filter(num=1)
    
  192.             .extra(
    
  193.                 select={"count": 0},
    
  194.             )
    
  195.             .values_list("num", "count")
    
  196.         )
    
  197.         qs2 = Number.objects.filter(num=2).extra(select={"count": 1})
    
  198.         self.assertCountEqual(qs1.union(qs2), [(1, 0), (2, 1)])
    
  199. 
    
  200.     def test_union_with_values_list_on_annotated_and_unannotated(self):
    
  201.         ReservedName.objects.create(name="rn1", order=1)
    
  202.         qs1 = Number.objects.annotate(
    
  203.             has_reserved_name=Exists(ReservedName.objects.filter(order=OuterRef("num")))
    
  204.         ).filter(has_reserved_name=True)
    
  205.         qs2 = Number.objects.filter(num=9)
    
  206.         self.assertCountEqual(qs1.union(qs2).values_list("num", flat=True), [1, 9])
    
  207. 
    
  208.     def test_union_with_values_list_and_order(self):
    
  209.         ReservedName.objects.bulk_create(
    
  210.             [
    
  211.                 ReservedName(name="rn1", order=7),
    
  212.                 ReservedName(name="rn2", order=5),
    
  213.                 ReservedName(name="rn0", order=6),
    
  214.                 ReservedName(name="rn9", order=-1),
    
  215.             ]
    
  216.         )
    
  217.         qs1 = ReservedName.objects.filter(order__gte=6)
    
  218.         qs2 = ReservedName.objects.filter(order__lte=5)
    
  219.         union_qs = qs1.union(qs2)
    
  220.         for qs, expected_result in (
    
  221.             # Order by a single column.
    
  222.             (union_qs.order_by("-pk").values_list("order", flat=True), [-1, 6, 5, 7]),
    
  223.             (union_qs.order_by("pk").values_list("order", flat=True), [7, 5, 6, -1]),
    
  224.             (union_qs.values_list("order", flat=True).order_by("-pk"), [-1, 6, 5, 7]),
    
  225.             (union_qs.values_list("order", flat=True).order_by("pk"), [7, 5, 6, -1]),
    
  226.             # Order by multiple columns.
    
  227.             (
    
  228.                 union_qs.order_by("-name", "pk").values_list("order", flat=True),
    
  229.                 [-1, 5, 7, 6],
    
  230.             ),
    
  231.             (
    
  232.                 union_qs.values_list("order", flat=True).order_by("-name", "pk"),
    
  233.                 [-1, 5, 7, 6],
    
  234.             ),
    
  235.         ):
    
  236.             with self.subTest(qs=qs):
    
  237.                 self.assertEqual(list(qs), expected_result)
    
  238. 
    
  239.     def test_union_with_values_list_and_order_on_annotation(self):
    
  240.         qs1 = Number.objects.annotate(
    
  241.             annotation=Value(-1),
    
  242.             multiplier=F("annotation"),
    
  243.         ).filter(num__gte=6)
    
  244.         qs2 = Number.objects.annotate(
    
  245.             annotation=Value(2),
    
  246.             multiplier=F("annotation"),
    
  247.         ).filter(num__lte=5)
    
  248.         self.assertSequenceEqual(
    
  249.             qs1.union(qs2).order_by("annotation", "num").values_list("num", flat=True),
    
  250.             [6, 7, 8, 9, 0, 1, 2, 3, 4, 5],
    
  251.         )
    
  252.         self.assertQuerysetEqual(
    
  253.             qs1.union(qs2)
    
  254.             .order_by(
    
  255.                 F("annotation") * F("multiplier"),
    
  256.                 "num",
    
  257.             )
    
  258.             .values("num"),
    
  259.             [6, 7, 8, 9, 0, 1, 2, 3, 4, 5],
    
  260.             operator.itemgetter("num"),
    
  261.         )
    
  262. 
    
  263.     def test_union_multiple_models_with_values_list_and_order(self):
    
  264.         reserved_name = ReservedName.objects.create(name="rn1", order=0)
    
  265.         qs1 = Celebrity.objects.all()
    
  266.         qs2 = ReservedName.objects.all()
    
  267.         self.assertSequenceEqual(
    
  268.             qs1.union(qs2).order_by("name").values_list("pk", flat=True),
    
  269.             [reserved_name.pk],
    
  270.         )
    
  271. 
    
  272.     def test_union_multiple_models_with_values_list_and_order_by_extra_select(self):
    
  273.         reserved_name = ReservedName.objects.create(name="rn1", order=0)
    
  274.         qs1 = Celebrity.objects.extra(select={"extra_name": "name"})
    
  275.         qs2 = ReservedName.objects.extra(select={"extra_name": "name"})
    
  276.         self.assertSequenceEqual(
    
  277.             qs1.union(qs2).order_by("extra_name").values_list("pk", flat=True),
    
  278.             [reserved_name.pk],
    
  279.         )
    
  280. 
    
  281.     def test_union_in_subquery(self):
    
  282.         ReservedName.objects.bulk_create(
    
  283.             [
    
  284.                 ReservedName(name="rn1", order=8),
    
  285.                 ReservedName(name="rn2", order=1),
    
  286.                 ReservedName(name="rn3", order=5),
    
  287.             ]
    
  288.         )
    
  289.         qs1 = Number.objects.filter(num__gt=7, num=OuterRef("order"))
    
  290.         qs2 = Number.objects.filter(num__lt=2, num=OuterRef("order"))
    
  291.         self.assertCountEqual(
    
  292.             ReservedName.objects.annotate(
    
  293.                 number=Subquery(qs1.union(qs2).values("num")),
    
  294.             )
    
  295.             .filter(number__isnull=False)
    
  296.             .values_list("order", flat=True),
    
  297.             [8, 1],
    
  298.         )
    
  299. 
    
  300.     def test_union_in_subquery_related_outerref(self):
    
  301.         e1 = ExtraInfo.objects.create(value=7, info="e3")
    
  302.         e2 = ExtraInfo.objects.create(value=5, info="e2")
    
  303.         e3 = ExtraInfo.objects.create(value=1, info="e1")
    
  304.         Author.objects.bulk_create(
    
  305.             [
    
  306.                 Author(name="a1", num=1, extra=e1),
    
  307.                 Author(name="a2", num=3, extra=e2),
    
  308.                 Author(name="a3", num=2, extra=e3),
    
  309.             ]
    
  310.         )
    
  311.         qs1 = ExtraInfo.objects.order_by().filter(value=OuterRef("num"))
    
  312.         qs2 = ExtraInfo.objects.order_by().filter(value__lt=OuterRef("extra__value"))
    
  313.         qs = (
    
  314.             Author.objects.annotate(
    
  315.                 info=Subquery(qs1.union(qs2).values("info")[:1]),
    
  316.             )
    
  317.             .filter(info__isnull=False)
    
  318.             .values_list("name", flat=True)
    
  319.         )
    
  320.         self.assertCountEqual(qs, ["a1", "a2"])
    
  321.         # Combined queries don't mutate.
    
  322.         self.assertCountEqual(qs, ["a1", "a2"])
    
  323. 
    
  324.     @skipUnlessDBFeature("supports_slicing_ordering_in_compound")
    
  325.     def test_union_in_with_ordering(self):
    
  326.         qs1 = Number.objects.filter(num__gt=7).order_by("num")
    
  327.         qs2 = Number.objects.filter(num__lt=2).order_by("num")
    
  328.         self.assertNumbersEqual(
    
  329.             Number.objects.exclude(id__in=qs1.union(qs2).values("id")),
    
  330.             [2, 3, 4, 5, 6, 7],
    
  331.             ordered=False,
    
  332.         )
    
  333. 
    
  334.     @skipUnlessDBFeature(
    
  335.         "supports_slicing_ordering_in_compound", "allow_sliced_subqueries_with_in"
    
  336.     )
    
  337.     def test_union_in_with_ordering_and_slice(self):
    
  338.         qs1 = Number.objects.filter(num__gt=7).order_by("num")[:1]
    
  339.         qs2 = Number.objects.filter(num__lt=2).order_by("-num")[:1]
    
  340.         self.assertNumbersEqual(
    
  341.             Number.objects.exclude(id__in=qs1.union(qs2).values("id")),
    
  342.             [0, 2, 3, 4, 5, 6, 7, 9],
    
  343.             ordered=False,
    
  344.         )
    
  345. 
    
  346.     def test_count_union(self):
    
  347.         qs1 = Number.objects.filter(num__lte=1).values("num")
    
  348.         qs2 = Number.objects.filter(num__gte=2, num__lte=3).values("num")
    
  349.         self.assertEqual(qs1.union(qs2).count(), 4)
    
  350. 
    
  351.     def test_count_union_empty_result(self):
    
  352.         qs = Number.objects.filter(pk__in=[])
    
  353.         self.assertEqual(qs.union(qs).count(), 0)
    
  354. 
    
  355.     @skipUnlessDBFeature("supports_select_difference")
    
  356.     def test_count_difference(self):
    
  357.         qs1 = Number.objects.filter(num__lt=10)
    
  358.         qs2 = Number.objects.filter(num__lt=9)
    
  359.         self.assertEqual(qs1.difference(qs2).count(), 1)
    
  360. 
    
  361.     @skipUnlessDBFeature("supports_select_intersection")
    
  362.     def test_count_intersection(self):
    
  363.         qs1 = Number.objects.filter(num__gte=5)
    
  364.         qs2 = Number.objects.filter(num__lte=5)
    
  365.         self.assertEqual(qs1.intersection(qs2).count(), 1)
    
  366. 
    
  367.     def test_exists_union(self):
    
  368.         qs1 = Number.objects.filter(num__gte=5)
    
  369.         qs2 = Number.objects.filter(num__lte=5)
    
  370.         with CaptureQueriesContext(connection) as context:
    
  371.             self.assertIs(qs1.union(qs2).exists(), True)
    
  372.         captured_queries = context.captured_queries
    
  373.         self.assertEqual(len(captured_queries), 1)
    
  374.         captured_sql = captured_queries[0]["sql"]
    
  375.         self.assertNotIn(
    
  376.             connection.ops.quote_name(Number._meta.pk.column),
    
  377.             captured_sql,
    
  378.         )
    
  379.         self.assertEqual(
    
  380.             captured_sql.count(connection.ops.limit_offset_sql(None, 1)),
    
  381.             3 if connection.features.supports_slicing_ordering_in_compound else 1,
    
  382.         )
    
  383. 
    
  384.     def test_exists_union_empty_result(self):
    
  385.         qs = Number.objects.filter(pk__in=[])
    
  386.         self.assertIs(qs.union(qs).exists(), False)
    
  387. 
    
  388.     @skipUnlessDBFeature("supports_select_intersection")
    
  389.     def test_exists_intersection(self):
    
  390.         qs1 = Number.objects.filter(num__gt=5)
    
  391.         qs2 = Number.objects.filter(num__lt=5)
    
  392.         self.assertIs(qs1.intersection(qs1).exists(), True)
    
  393.         self.assertIs(qs1.intersection(qs2).exists(), False)
    
  394. 
    
  395.     @skipUnlessDBFeature("supports_select_difference")
    
  396.     def test_exists_difference(self):
    
  397.         qs1 = Number.objects.filter(num__gte=5)
    
  398.         qs2 = Number.objects.filter(num__gte=3)
    
  399.         self.assertIs(qs1.difference(qs2).exists(), False)
    
  400.         self.assertIs(qs2.difference(qs1).exists(), True)
    
  401. 
    
  402.     def test_get_union(self):
    
  403.         qs = Number.objects.filter(num=2)
    
  404.         self.assertEqual(qs.union(qs).get().num, 2)
    
  405. 
    
  406.     @skipUnlessDBFeature("supports_select_difference")
    
  407.     def test_get_difference(self):
    
  408.         qs1 = Number.objects.all()
    
  409.         qs2 = Number.objects.exclude(num=2)
    
  410.         self.assertEqual(qs1.difference(qs2).get().num, 2)
    
  411. 
    
  412.     @skipUnlessDBFeature("supports_select_intersection")
    
  413.     def test_get_intersection(self):
    
  414.         qs1 = Number.objects.all()
    
  415.         qs2 = Number.objects.filter(num=2)
    
  416.         self.assertEqual(qs1.intersection(qs2).get().num, 2)
    
  417. 
    
  418.     @skipUnlessDBFeature("supports_slicing_ordering_in_compound")
    
  419.     def test_ordering_subqueries(self):
    
  420.         qs1 = Number.objects.order_by("num")[:2]
    
  421.         qs2 = Number.objects.order_by("-num")[:2]
    
  422.         self.assertNumbersEqual(qs1.union(qs2).order_by("-num")[:4], [9, 8, 1, 0])
    
  423. 
    
  424.     @skipIfDBFeature("supports_slicing_ordering_in_compound")
    
  425.     def test_unsupported_ordering_slicing_raises_db_error(self):
    
  426.         qs1 = Number.objects.all()
    
  427.         qs2 = Number.objects.all()
    
  428.         qs3 = Number.objects.all()
    
  429.         msg = "LIMIT/OFFSET not allowed in subqueries of compound statements"
    
  430.         with self.assertRaisesMessage(DatabaseError, msg):
    
  431.             list(qs1.union(qs2[:10]))
    
  432.         msg = "ORDER BY not allowed in subqueries of compound statements"
    
  433.         with self.assertRaisesMessage(DatabaseError, msg):
    
  434.             list(qs1.order_by("id").union(qs2))
    
  435.         with self.assertRaisesMessage(DatabaseError, msg):
    
  436.             list(qs1.union(qs2).order_by("id").union(qs3))
    
  437. 
    
  438.     @skipIfDBFeature("supports_select_intersection")
    
  439.     def test_unsupported_intersection_raises_db_error(self):
    
  440.         qs1 = Number.objects.all()
    
  441.         qs2 = Number.objects.all()
    
  442.         msg = "intersection is not supported on this database backend"
    
  443.         with self.assertRaisesMessage(NotSupportedError, msg):
    
  444.             list(qs1.intersection(qs2))
    
  445. 
    
  446.     def test_combining_multiple_models(self):
    
  447.         ReservedName.objects.create(name="99 little bugs", order=99)
    
  448.         qs1 = Number.objects.filter(num=1).values_list("num", flat=True)
    
  449.         qs2 = ReservedName.objects.values_list("order")
    
  450.         self.assertEqual(list(qs1.union(qs2).order_by("num")), [1, 99])
    
  451. 
    
  452.     def test_order_raises_on_non_selected_column(self):
    
  453.         qs1 = (
    
  454.             Number.objects.filter()
    
  455.             .annotate(
    
  456.                 annotation=Value(1, IntegerField()),
    
  457.             )
    
  458.             .values("annotation", num2=F("num"))
    
  459.         )
    
  460.         qs2 = Number.objects.filter().values("id", "num")
    
  461.         # Should not raise
    
  462.         list(qs1.union(qs2).order_by("annotation"))
    
  463.         list(qs1.union(qs2).order_by("num2"))
    
  464.         msg = "ORDER BY term does not match any column in the result set"
    
  465.         # 'id' is not part of the select
    
  466.         with self.assertRaisesMessage(DatabaseError, msg):
    
  467.             list(qs1.union(qs2).order_by("id"))
    
  468.         # 'num' got realiased to num2
    
  469.         with self.assertRaisesMessage(DatabaseError, msg):
    
  470.             list(qs1.union(qs2).order_by("num"))
    
  471.         with self.assertRaisesMessage(DatabaseError, msg):
    
  472.             list(qs1.union(qs2).order_by(F("num")))
    
  473.         with self.assertRaisesMessage(DatabaseError, msg):
    
  474.             list(qs1.union(qs2).order_by(F("num").desc()))
    
  475.         # switched order, now 'exists' again:
    
  476.         list(qs2.union(qs1).order_by("num"))
    
  477. 
    
  478.     @skipUnlessDBFeature("supports_select_difference", "supports_select_intersection")
    
  479.     def test_qs_with_subcompound_qs(self):
    
  480.         qs1 = Number.objects.all()
    
  481.         qs2 = Number.objects.intersection(Number.objects.filter(num__gt=1))
    
  482.         self.assertEqual(qs1.difference(qs2).count(), 2)
    
  483. 
    
  484.     def test_order_by_same_type(self):
    
  485.         qs = Number.objects.all()
    
  486.         union = qs.union(qs)
    
  487.         numbers = list(range(10))
    
  488.         self.assertNumbersEqual(union.order_by("num"), numbers)
    
  489.         self.assertNumbersEqual(union.order_by("other_num"), reversed(numbers))
    
  490. 
    
  491.     def test_unsupported_operations_on_combined_qs(self):
    
  492.         qs = Number.objects.all()
    
  493.         msg = "Calling QuerySet.%s() after %s() is not supported."
    
  494.         combinators = ["union"]
    
  495.         if connection.features.supports_select_difference:
    
  496.             combinators.append("difference")
    
  497.         if connection.features.supports_select_intersection:
    
  498.             combinators.append("intersection")
    
  499.         for combinator in combinators:
    
  500.             for operation in (
    
  501.                 "alias",
    
  502.                 "annotate",
    
  503.                 "defer",
    
  504.                 "delete",
    
  505.                 "distinct",
    
  506.                 "exclude",
    
  507.                 "extra",
    
  508.                 "filter",
    
  509.                 "only",
    
  510.                 "prefetch_related",
    
  511.                 "select_related",
    
  512.                 "update",
    
  513.             ):
    
  514.                 with self.subTest(combinator=combinator, operation=operation):
    
  515.                     with self.assertRaisesMessage(
    
  516.                         NotSupportedError,
    
  517.                         msg % (operation, combinator),
    
  518.                     ):
    
  519.                         getattr(getattr(qs, combinator)(qs), operation)()
    
  520.             with self.assertRaisesMessage(
    
  521.                 NotSupportedError,
    
  522.                 msg % ("contains", combinator),
    
  523.             ):
    
  524.                 obj = Number.objects.first()
    
  525.                 getattr(qs, combinator)(qs).contains(obj)
    
  526. 
    
  527.     def test_get_with_filters_unsupported_on_combined_qs(self):
    
  528.         qs = Number.objects.all()
    
  529.         msg = "Calling QuerySet.get(...) with filters after %s() is not supported."
    
  530.         combinators = ["union"]
    
  531.         if connection.features.supports_select_difference:
    
  532.             combinators.append("difference")
    
  533.         if connection.features.supports_select_intersection:
    
  534.             combinators.append("intersection")
    
  535.         for combinator in combinators:
    
  536.             with self.subTest(combinator=combinator):
    
  537.                 with self.assertRaisesMessage(NotSupportedError, msg % combinator):
    
  538.                     getattr(qs, combinator)(qs).get(num=2)
    
  539. 
    
  540.     def test_operator_on_combined_qs_error(self):
    
  541.         qs = Number.objects.all()
    
  542.         msg = "Cannot use %s operator with combined queryset."
    
  543.         combinators = ["union"]
    
  544.         if connection.features.supports_select_difference:
    
  545.             combinators.append("difference")
    
  546.         if connection.features.supports_select_intersection:
    
  547.             combinators.append("intersection")
    
  548.         operators = [
    
  549.             ("|", operator.or_),
    
  550.             ("&", operator.and_),
    
  551.             ("^", operator.xor),
    
  552.         ]
    
  553.         for combinator in combinators:
    
  554.             combined_qs = getattr(qs, combinator)(qs)
    
  555.             for operator_, operator_func in operators:
    
  556.                 with self.subTest(combinator=combinator):
    
  557.                     with self.assertRaisesMessage(TypeError, msg % operator_):
    
  558.                         operator_func(qs, combined_qs)
    
  559.                     with self.assertRaisesMessage(TypeError, msg % operator_):
    
  560.                         operator_func(combined_qs, qs)