Skip to content

force_index and use_index PRIMARY clarify #1137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/django_mysql/models/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ def _index_hint(

if len(index_names) == 0:
indexes = "NONE"
elif len(index_names) == 1 and index_names[0] == "PRIMARY":
indexes = "PRIMARY"
else:
indexes = "`" + "`,`".join(index_names) + "`"

Expand Down
2 changes: 1 addition & 1 deletion src/django_mysql/rewrite_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
(?P<for_what>JOIN|ORDER\ BY|GROUP\ BY)
\ # space
)?
(?P<index_names>(`[^`]+`(,`[^`]+`)*)|NONE)
(?P<index_names>(`[^`]+`(,`[^`]+`)*)|NONE|PRIMARY)
""",
re.VERBOSE,
)
Expand Down
18 changes: 11 additions & 7 deletions tests/testapp/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ def test_use_index(self):
def test_use_index_primary(self):
with CaptureLastQuery() as cap:
list(Author.objects.use_index("PRIMARY"))
assert ("USE INDEX (`PRIMARY`)") in cap.query
assert ("USE INDEX (PRIMARY)") in cap.query
used = used_indexes(cap.query)
assert len(used) == 0 or "PRIMARY" in used

Expand Down Expand Up @@ -273,10 +273,10 @@ def test_force_index(self):

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

def test_force_index_inner_query(self):
title_idx = index_name(Book, "title")
Expand Down Expand Up @@ -319,8 +319,12 @@ def test_ignore_index_multiple(self):

def test_ignore_index_primary(self):
with CaptureLastQuery() as cap:
list(Author.objects.filter(name__gt="").ignore_index("PRIMARY"))
assert "IGNORE INDEX (`PRIMARY`)" in cap.query
list(
Author.objects.filter(name__gt="")
.ignore_index("PRIMARY")
.order_by("pk")
)
assert "IGNORE INDEX (PRIMARY)" in cap.query
assert "PRIMARY" not in used_indexes(cap.query)

def test_force_index_at_least_one(self):
Expand Down Expand Up @@ -355,7 +359,7 @@ def test_use_index_table_name(self):
"PRIMARY", table_name=extra_table
)
)
assert ("`" + extra_table + "` USE INDEX (`PRIMARY`) ") in cap.query
assert ("`" + extra_table + "` USE INDEX (PRIMARY) ") in cap.query

def test_force_index_table_name_doesnt_exist_ignored(self):
with CaptureLastQuery() as cap:
Expand Down
8 changes: 8 additions & 0 deletions tests/testapp/test_rewrite_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,14 @@ def test_index_hint_for_order_by(self):
+ "WHERE (1) ORDER BY col_a"
)

def test_index_hint_primary(self):
assert rewrite_query(
"SELECT col_a, col_b FROM `sometable` "
+ "WHERE (/*QueryRewrite':index=`sometable` FORCE PRIMARY */1)"
) == (
"SELECT col_a, col_b FROM `sometable` " + "FORCE INDEX (PRIMARY) WHERE (1)"
)

def test_it_is_instrumented(self):
with CaptureLastQuery() as cap, connection.cursor() as cursor:
cursor.execute(
Expand Down