Repository: django/django
File: tests/aggregation/tests.py (Python)

Code before:
        )
        self.assertCountEqual(books["ratings"].split(","), ["3", "4", "4.5", "5"])

    @skipIfDBFeature("supports_aggregate_distinct_multiple_argument")
    def test_raises_error_on_multiple_argument_distinct(self):
        message = (
            "StringAgg does not support distinct with multiple expressions on this "
            "database backend."
        )
        with self.assertRaisesMessage(NotSupportedError, message):
            Book.objects.aggregate(
                ratings=StringAgg(
                    Cast(F("rating"), CharField()),
                    Value(";"),
                    distinct=True,
                )
            )

    def test_string_agg_distinct_with_default_delimiter(self):
        books = Book.objects.aggregate(
            pages_list=StringAgg(
                Cast(F("pages"), CharField()),
                Value(","),
                distinct=True,
            )
        )

        expected_pages = set(
            str(p) for p in Book.objects.values_list("pages", flat=True)
        )
        self.assertEqual(set(books["pages_list"].split(",")), expected_pages)

    def test_non_grouped_annotation_not_in_group_by(self):
        """
        An annotation not included in values() before an aggregate should be
        excluded from the group by clause.
        """
        qs = (
            Book.objects.annotate(xprice=F("price"))
            .filter(rating=4.0)
            .values("rating")
            .annotate(count=Count("publisher_id", distinct=True))
            .values("count", "rating")
            .order_by("count")
        )
        self.assertEqual(list(qs), [{"rating": 4.0, "count": 2}])

    def test_grouped_annotation_in_group_by(self):
        """
        An annotation included in values() before an aggregate should be
        included in the group by clause.

Review comment (suggestion):
It's too bad we can't provide a better hint for SQLite users in this case, but I don't know what we can do about it without departing from our existing patterns.

Code after:
        books = Book.objects.aggregate(
            ratings=StringAgg(Cast(F("rating"), CharField()), Value(","), distinct=True)
        )
        self.assertCountEqual(books["ratings"].split(","), ["3", "4", "4.5", "5"])

    @skipUnless(connection.vendor == "sqlite", "Special default case for SQLite.")
    def test_distinct_on_stringagg_sqlite_special_case(self):
        """
        Value(",") is the only delimiter usable on SQLite with distinct=True.
        """
        books = Book.objects.aggregate(
            ratings=StringAgg(Cast(F("rating"), CharField()), Value(","), distinct=True)
        )
        self.assertCountEqual(books["ratings"].split(","), ["3.0", "4.0", "4.5", "5.0"])

    @skipIfDBFeature("supports_aggregate_distinct_multiple_argument")
    def test_raises_error_on_multiple_argument_distinct(self):
        message = (
            "StringAgg does not support distinct with multiple expressions on this "
            "database backend."
        )
        with self.assertRaisesMessage(NotSupportedError, message):
            Book.objects.aggregate(
                ratings=StringAgg(
                    Cast(F("rating"), CharField()),
                    Value(";"),
                    distinct=True,
                )
            )

    def test_non_grouped_annotation_not_in_group_by(self):
        """
        An annotation not included in values() before an aggregate should be
        excluded from the group by clause.
        """
        qs = (
            Book.objects.annotate(xprice=F("price"))
            .filter(rating=4.0)
            .values("rating")
            .annotate(count=Count("publisher_id", distinct=True))
            .values("count", "rating")
            .order_by("count")
        )
        self.assertEqual(list(qs), [{"rating": 4.0, "count": 2}])

    def test_grouped_annotation_in_group_by(self):
        """
        An annotation included in values() before an aggregate should be
        included in the group by clause.
        """
        qs = (