# Path: tests/compat.py
# def wrap_testdata(func):
#     return func
# 
# Path: tests/testapp/models.py
# class Author(Model):
#     name = CharField(max_length=32, db_index=True)
#     tutor = ForeignKey("self", on_delete=CASCADE, null=True, related_name="tutees")
#     bio = TextField()
#     birthday = DateTimeField(null=True)
#     deathday = DateTimeField(null=True)
# 
# class AuthorExtra(Model):
#     author = OneToOneField(Author, on_delete=CASCADE, primary_key=True)
#     legs = IntegerField(default=2)
# 
# class AuthorMultiIndex(Model):
#     class Meta:
#         index_together = ("name", "country")
# 
#     name = CharField(max_length=32, db_index=True)
#     country = CharField(max_length=32)
# 
# class Book(Model):
#     title = CharField(max_length=32, db_index=True)
#     author = ForeignKey(Author, on_delete=CASCADE, related_name="books")
# 
# class NameAuthor(Model):
#     name = CharField(max_length=32, primary_key=True)
# 
# class NameAuthorExtra(Model):
#     name = OneToOneField(NameAuthor, on_delete=CASCADE, primary_key=True)
# 
# class VanillaAuthor(VanillaModel):
#     name = CharField(max_length=32)
# 
# Path: tests/testapp/utils.py
# class CaptureLastQuery:
#     def __init__(self, conn=None):
#         if conn is None:  # pragma: no branch
#             conn = connection
#         self.conn = conn
# 
#     def __enter__(self):
#         self.capturer = CaptureQueriesContext(self.conn)
#         self.capturer.__enter__()
#         return self
# 
#     def __exit__(self, a, b, c):
#         self.capturer.__exit__(a, b, c)
# 
#     @property
#     def query(self):
#         return self.capturer.captured_queries[-1]["sql"]
# 
# @contextmanager
# def skip_if_mysql_8_plus():
#     if not connection_is_mariadb(connection) and connection.mysql_version >= (8,):
#         pytest.skip("Requires MySQL<8 or MariaDB")
#     yield
# 
# def used_indexes(query, using=DEFAULT_DB_ALIAS):
#     """
#     Given SQL 'query', run EXPLAIN and return the names of the indexes used
#     """
#     connection = connections[using]
#     with connection.cursor() as cursor:
#         cursor.execute("EXPLAIN " + query)
# 
#         return {row["key"] for row in fetchall_dicts(cursor) if row["key"] is not None}


import pickle
import re
import pytest
from unittest import mock, skipUnless
from django.contrib.contenttypes.models import ContentType
from django.db import DEFAULT_DB_ALIAS, connections
from django.db.models import Exists, OuterRef
from django.db.models.query import QuerySet
from django.template import Context, Template
from django.test import TestCase
from django.test.utils import captured_stdout, override_settings
from django_mysql.models import ApproximateInt, SmartIterator, add_QuerySetMixin
from django_mysql.utils import have_program, index_name
from tests.compat import wrap_testdata
from tests.testapp.models import (
    Author,
    AuthorExtra,
    AuthorMultiIndex,
    Book,
    NameAuthor,
    NameAuthorExtra,
    VanillaAuthor,
)
from tests.testapp.utils import CaptureLastQuery, skip_if_mysql_8_plus, used_indexes

    def test_approx_count_with_label(self):
        # It should be possible to approx count a query set with a query hint
        # as none of them affect the result
        assert Author.objects.label("bla").approx_count(fall_back=False) == 10

    def test_approx_count_with_straight_join(self):
        # It should be possible to approx count a query set with a query hint
        # as none of them affect the result
        assert Author.objects.straight_join().approx_count(fall_back=False) == 10


class QueryHintTests(TestCase):
    def test_label(self):
        with CaptureLastQuery() as cap:
            list(Author.objects.label("QueryHintTests.test_label").all())
        assert cap.query.startswith("SELECT /*QueryHintTests.test_label*/ ")

    def test_label_twice(self):
        with CaptureLastQuery() as cap:
            list(Author.objects.label("QueryHintTests").label("test_label_twice").all())
        assert cap.query.startswith("SELECT /*QueryHintTests*/ /*test_label_twice*/ ")

    def test_label_star(self):
        with CaptureLastQuery() as cap:
            list(Author.objects.label("I'ma*").label("*").all())
        assert cap.query.startswith("SELECT /*I'ma**/ /***/ ")

    def test_label_update(self):
        Author.objects.create(name="UPDATEME")

# Path: tests/compat.py
# def wrap_testdata(func):
#     return func
# 
# Path: tests/testapp/models.py
# class Author(Model):
#     name = CharField(max_length=32, db_index=True)
#     tutor = ForeignKey("self", on_delete=CASCADE, null=True, related_name="tutees")
#     bio = TextField()
#     birthday = DateTimeField(null=True)
#     deathday = DateTimeField(null=True)
# 
# class AuthorExtra(Model):
#     author = OneToOneField(Author, on_delete=CASCADE, primary_key=True)
#     legs = IntegerField(default=2)
# 
# class AuthorMultiIndex(Model):
#     class Meta:
#         index_together = ("name", "country")
# 
#     name = CharField(max_length=32, db_index=True)
#     country = CharField(max_length=32)
# 
# class Book(Model):
#     title = CharField(max_length=32, db_index=True)
#     author = ForeignKey(Author, on_delete=CASCADE, related_name="books")
# 
# class NameAuthor(Model):
#     name = CharField(max_length=32, primary_key=True)
# 
# class NameAuthorExtra(Model):
#     name = OneToOneField(NameAuthor, on_delete=CASCADE, primary_key=True)
# 
# class VanillaAuthor(VanillaModel):
#     name = CharField(max_length=32)
# 
# Path: tests/testapp/utils.py
# class CaptureLastQuery:
#     def __init__(self, conn=None):
#         if conn is None:  # pragma: no branch
#             conn = connection
#         self.conn = conn
# 
#     def __enter__(self):
#         self.capturer = CaptureQueriesContext(self.conn)
#         self.capturer.__enter__()
#         return self
# 
#     def __exit__(self, a, b, c):
#         self.capturer.__exit__(a, b, c)
# 
#     @property
#     def query(self):
#         return self.capturer.captured_queries[-1]["sql"]
# 
# @contextmanager
# def skip_if_mysql_8_plus():
#     if not connection_is_mariadb(connection) and connection.mysql_version >= (8,):
#         pytest.skip("Requires MySQL<8 or MariaDB")
#     yield
# 
# def used_indexes(query, using=DEFAULT_DB_ALIAS):
#     """
#     Given SQL 'query', run EXPLAIN and return the names of the indexes used
#     """
#     connection = connections[using]
#     with connection.cursor() as cursor:
#         cursor.execute("EXPLAIN " + query)
# 
#         return {row["key"] for row in fetchall_dicts(cursor) if row["key"] is not None}


# Path: tests/testapp/test_models.py
import pickle
import re
import pytest
from unittest import mock, skipUnless
from django.contrib.contenttypes.models import ContentType
from django.db import DEFAULT_DB_ALIAS, connections
from django.db.models import Exists, OuterRef
from django.db.models.query import QuerySet
from django.template import Context, Template
from django.test import TestCase
from django.test.utils import captured_stdout, override_settings
from django_mysql.models import ApproximateInt, SmartIterator, add_QuerySetMixin
from django_mysql.utils import have_program, index_name
from tests.compat import wrap_testdata
from tests.testapp.models import (
    Author,
    AuthorExtra,
    AuthorMultiIndex,
    Book,
    NameAuthor,
    NameAuthorExtra,
    VanillaAuthor,
)
from tests.testapp.utils import CaptureLastQuery, skip_if_mysql_8_plus, used_indexes


    def test_approx_count_with_label(self):
        # It should be possible to approx count a query set with a query hint
        # as none of them affect the result
        assert Author.objects.label("bla").approx_count(fall_back=False) == 10

    def test_approx_count_with_straight_join(self):
        # It should be possible to approx count a query set with a query hint
        # as none of them affect the result
        assert Author.objects.straight_join().approx_count(fall_back=False) == 10


class QueryHintTests(TestCase):
    def test_label(self):
        with CaptureLastQuery() as cap:
            list(Author.objects.label("QueryHintTests.test_label").all())
        assert cap.query.startswith("SELECT /*QueryHintTests.test_label*/ ")

    def test_label_twice(self):
        with CaptureLastQuery() as cap:
            list(Author.objects.label("QueryHintTests").label("test_label_twice").all())
        assert cap.query.startswith("SELECT /*QueryHintTests*/ /*test_label_twice*/ ")

    def test_label_star(self):
        with CaptureLastQuery() as cap:
            list(Author.objects.label("I'ma*").label("*").all())
        assert cap.query.startswith("SELECT /*I'ma**/ /***/ ")

    def test_label_update(self):
        Author.objects.create(name="UPDATEME")

        with CaptureLastQuery() as cap: