Skip to content

Commit 3b881fb

Browse files
committed
Use better heuristic for select list elision
Instead of only eliding select lists longer than 12 characters, now only elide select lists that contain a dot (from a column expression like `table_name`.`column_name`). The motivation for this is that as of Django 1.10, using .count() on a queryset generates SELECT COUNT(*) AS `__count` FROM ... instead of SELECT COUNT(*) FROM ... queries. This change prevents the new form from being elided.
1 parent 496c97d commit 3b881fb

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

debug_toolbar/panels/sql/utils.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,28 @@ def process(self, stream):
1818

1919
@staticmethod
2020
def elide_until_from(stream):
21-
select_list_characters = 0
22-
select_list_tokens = []
21+
has_dot = False
22+
saved_tokens = []
2323
for token_type, value in stream:
2424
if token_type in T.Keyword and value.upper() == "FROM":
25-
# Do not elide a select list of 12 characters or fewer to preserve
26-
# SELECT COUNT(*) FROM ...
25+
# Do not elide a select lists that do not contain dots (used to separate
26+
# table names from column names) in order to preserve
27+
# SELECT COUNT(*) AS `__count` FROM ...
2728
# and
2829
# SELECT (1) AS `a` FROM ...
2930
# queries.
30-
if select_list_characters <= 12:
31-
yield from select_list_tokens
31+
if not has_dot:
32+
yield from saved_tokens
3233
else:
3334
# U+2022: Unicode character 'BULLET'
3435
yield T.Other, " \u2022\u2022\u2022 "
3536
yield token_type, value
3637
break
37-
if select_list_characters <= 12:
38-
select_list_characters += len(value)
39-
select_list_tokens.append((token_type, value))
38+
if not has_dot:
39+
if token_type in T.Punctuation and value == ".":
40+
has_dot = True
41+
else:
42+
saved_tokens.append((token_type, value))
4043

4144

4245
class BoldKeywordFilter:

tests/panels/test_sql.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,21 @@ def test_prettify_sql(self):
495495
self.assertEqual(len(self.panel._queries), 1)
496496
self.assertEqual(pretty_sql, self.panel._queries[-1]["sql"])
497497

498+
def test_simplification(self):
499+
"""
500+
Test case to validate that select lists for .count() and .exist() queries do not
501+
get elided, but other select lists do.
502+
"""
503+
User.objects.count()
504+
User.objects.exists()
505+
list(User.objects.values_list("id"))
506+
response = self.panel.process_request(self.request)
507+
self.panel.generate_stats(self.request, response)
508+
self.assertEqual(len(self.panel._queries), 3)
509+
self.assertNotIn("\u2022", self.panel._queries[0]["sql"])
510+
self.assertNotIn("\u2022", self.panel._queries[1]["sql"])
511+
self.assertIn("\u2022", self.panel._queries[2]["sql"])
512+
498513
@override_settings(
499514
DEBUG=True,
500515
)

0 commit comments

Comments
 (0)