# 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
        title_idx = index_name(Book, "title")
        with CaptureLastQuery() as cap:
            list(
                Author.objects.annotate(
                    has_books=Exists(
                        Book.objects.filter(
                            author_id=OuterRef("id"), title__gt=""
                        ).use_index(title_idx, table_name="testapp_book")
                    )
                ).filter(has_books=True)
            )
        assert ("USE INDEX (`" + title_idx + "`)") in cap.query
        used = used_indexes(cap.query)
        assert len(used) == 0 or title_idx in used

    def test_force_index(self):
        name_idx = index_name(Author, "name")
        with CaptureLastQuery() as cap:
            list(Author.objects.filter(name__gt="").force_index(name_idx))
        assert ("FORCE INDEX (`" + name_idx + "`)") in cap.query
        assert name_idx in used_indexes(cap.query)

    def test_force_index_primary(self):
        with CaptureLastQuery() as cap:
            list(Author.objects.force_index("PRIMARY"))
        assert ("FORCE INDEX (`PRIMARY`)") in cap.query
        used = used_indexes(cap.query)
        assert len(used) == 0 or "PRIMARY" in used

    def test_force_index_inner_query(self):

# 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

        title_idx = index_name(Book, "title")
        with CaptureLastQuery() as cap:
            list(
                Author.objects.annotate(
                    has_books=Exists(
                        Book.objects.filter(
                            author_id=OuterRef("id"), title__gt=""
                        ).use_index(title_idx, table_name="testapp_book")
                    )
                ).filter(has_books=True)
            )
        assert ("USE INDEX (`" + title_idx + "`)") in cap.query
        used = used_indexes(cap.query)
        assert len(used) == 0 or title_idx in used

    def test_force_index(self):
        name_idx = index_name(Author, "name")
        with CaptureLastQuery() as cap:
            list(Author.objects.filter(name__gt="").force_index(name_idx))
        assert ("FORCE INDEX (`" + name_idx + "`)") in cap.query
        assert name_idx in used_indexes(cap.query)

    def test_force_index_primary(self):
        with CaptureLastQuery() as cap:
            list(Author.objects.force_index("PRIMARY"))
        assert ("FORCE INDEX (`PRIMARY`)") in cap.query
        used = used_indexes(cap.query)
        assert len(used) == 0 or "PRIMARY" in used

    def test_force_index_inner_query(self):

        title_idx = index_name(Book, "title")