Repository: adamchainz/django-perf-rec

Issue:
Don't replace selected columns with "..."
These 2 queries produce the same result:

```python
list(Author.objects.all())
list(Author.objects.only('pk'))
```
result:
```
- db: SELECT ... FROM "testapp_author"
- db: SELECT ... FROM "testapp_author"
```

It will be helpfull to not hide selected columns, because without reading the code in parallel we don't know how many fields are concerned by the query.

I will propose a PR.


Discussion:

Resolving patch:
diff --git a/django_perf_rec/settings.py b/django_perf_rec/settings.py
--- a/django_perf_rec/settings.py
+++ b/django_perf_rec/settings.py
@@ -8,6 +8,7 @@ class Settings(object):
 
     defaults = {
         'MODE': 'once',
+        'HIDE_COLUMNS': True,
     }
 
     def get_setting(self, key):
@@ -20,5 +21,9 @@ def get_setting(self, key):
     def MODE(self):
         return self.get_setting('MODE')
 
+    @property
+    def HIDE_COLUMNS(self):
+        return self.get_setting('HIDE_COLUMNS')
+
 
 perf_rec_settings = Settings()
diff --git a/django_perf_rec/sql.py b/django_perf_rec/sql.py
--- a/django_perf_rec/sql.py
+++ b/django_perf_rec/sql.py
@@ -6,6 +6,8 @@
 from sqlparse import parse, tokens
 from sqlparse.sql import IdentifierList, Token
 
+from .settings import perf_rec_settings
+
 
 @lru_cache(maxsize=500)
 def sql_fingerprint(query):
@@ -70,8 +72,10 @@ def sql_recursively_simplify(node):
         match_by = match_keyword(one_before, ["BY"])
         match_having = match_keyword(one_before, ["HAVING"])
         inside_order_group_having = (match_order_or_group and match_by) or match_having
+        hide_columns = perf_rec_settings.HIDE_COLUMNS
+        replace_columns = not inside_order_group_having and hide_columns
 
-        if isinstance(token, IdentifierList) and not inside_order_group_having:
+        if isinstance(token, IdentifierList) and replace_columns:
             token.tokens = [Token(tokens.Punctuation, '...')]
         elif hasattr(token, 'tokens'):
             sql_recursively_simplify(token)


Test patch:
diff --git a/tests/test_api.perf.yml b/tests/test_api.perf.yml
old mode 100644
new mode 100755
--- a/tests/test_api.perf.yml
+++ b/tests/test_api.perf.yml
@@ -1,14 +1,8 @@
-FileNameTests.test_default_filename:
-- cache|get: foo
-RecordPathTests.test_default_filename:
-- cache|get: foo
 RecordTests.test_delete_on_cascade_called_twice:
 - db: DELETE FROM "testapp_book" WHERE "testapp_book"."author_id" IN (#)
 - db: DELETE FROM "testapp_award" WHERE "testapp_award"."author_id" IN (#)
 - db: DELETE FROM "testapp_contract_author" WHERE "testapp_contract_author"."author_id" IN (#)
 - db: DELETE FROM "testapp_author" WHERE "testapp_author"."id" IN (#)
-RecordTests.test_file_name_is_deprecated:
-- cache|get: foo
 RecordTests.test_multiple_cache_ops:
 - cache|set: foo
 - cache|second|get_many:
@@ -40,8 +34,3 @@ other:
 - cache|get: foo
 test_diff:
 - cache|get: foo
-null:
-- db: DELETE FROM "testapp_book" WHERE "testapp_book"."author_id" IN (#)
-- db: DELETE FROM "testapp_award" WHERE "testapp_award"."author_id" IN (#)
-- db: DELETE FROM "testapp_contract_author" WHERE "testapp_contract_author"."author_id" IN (#)
-- db: DELETE FROM "testapp_author" WHERE "testapp_author"."id" IN (#)
diff --git a/tests/test_sql.py b/tests/test_sql.py
--- a/tests/test_sql.py
+++ b/tests/test_sql.py
@@ -1,9 +1,16 @@
 # -*- coding:utf-8 -*-
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+import pytest
+
 from django_perf_rec.sql import sql_fingerprint
 
 
+@pytest.fixture(autouse=True)
+def clear_lru_cache():
+    sql_fingerprint.cache_clear()
+
+
 def test_select():
     assert (
         sql_fingerprint("SELECT `f1`, `f2` FROM `b`") ==
@@ -11,6 +18,15 @@ def test_select():
     )
 
 
+def test_select_show_columns(settings):
+    settings.PERF_REC = {'HIDE_COLUMNS': False}
+
+    assert (
+        sql_fingerprint("SELECT `f1`, `f2` FROM `b`") ==
+        "SELECT `f1`, `f2` FROM `b`"
+    )
+
+
 def test_select_where():
     assert (
         sql_fingerprint("SELECT DISTINCT `table`.`field` FROM `table` WHERE `table`.`id` = 1") ==
@@ -18,6 +34,15 @@ def test_select_where():
     )
 
 
+def test_select_where_show_columns(settings):
+    settings.PERF_REC = {'HIDE_COLUMNS': False}
+
+    assert (
+        sql_fingerprint("SELECT DISTINCT `table`.`field` FROM `table` WHERE `table`.`id` = 1") ==
+        "SELECT DISTINCT `table`.`field` FROM `table` WHERE `table`.`id` = #"
+    )
+
+
 def test_select_comment():
     assert (
         sql_fingerprint("SELECT /* comment */ `f1`, `f2` FROM `b`") ==
@@ -25,6 +50,15 @@ def test_select_comment():
     )
 
 
+def test_select_comment_show_columns(settings):
+    settings.PERF_REC = {'HIDE_COLUMNS': False}
+
+    assert (
+        sql_fingerprint("SELECT /* comment */ `f1`, `f2` FROM `b`") ==
+        "SELECT /* comment */ `f1`, `f2` FROM `b`"
+    )
+
+
 def test_select_join():
     assert (
         sql_fingerprint('SELECT f1, f2 FROM a INNER JOIN b ON (a.b_id = b.id) WHERE a.f2 = 1') ==
@@ -32,6 +66,15 @@ def test_select_join():
     )
 
 
+def test_select_join_show_columns(settings):
+    settings.PERF_REC = {'HIDE_COLUMNS': False}
+
+    assert (
+        sql_fingerprint('SELECT f1, f2 FROM a INNER JOIN b ON (a.b_id = b.id) WHERE a.f2 = 1') ==
+        'SELECT f1, f2 FROM a INNER JOIN b ON (a.b_id = b.id) WHERE a.f2 = #'
+    )
+
+
 def test_select_order_by():
     assert (
         sql_fingerprint('SELECT f1, f2 FROM a ORDER BY f3') ==
@@ -39,6 +82,15 @@ def test_select_order_by():
     )
 
 
+def test_select_order_by_show_columns(settings):
+    settings.PERF_REC = {'HIDE_COLUMNS': False}
+
+    assert (
+        sql_fingerprint('SELECT f1, f2 FROM a ORDER BY f3') ==
+        'SELECT f1, f2 FROM a ORDER BY f3'
+    )
+
+
 def test_select_order_by_multiple():
     assert (
         sql_fingerprint('SELECT f1, f2 FROM a ORDER BY f3, f4') ==
@@ -53,6 +105,15 @@ def test_select_group_by():
     )
 
 
+def test_select_group_by_show_columns(settings):
+    settings.PERF_REC = {'HIDE_COLUMNS': False}
+
+    assert (
+        sql_fingerprint('SELECT f1, f2 FROM a GROUP BY f1') ==
+        'SELECT f1, f2 FROM a GROUP BY f1'
+    )
+
+
 def test_select_group_by_multiple():
     assert (
         sql_fingerprint('SELECT f1, f2 FROM a GROUP BY f1, f2') ==
@@ -67,6 +128,15 @@ def test_select_group_by_having():
     )
 
 
+def test_select_group_by_having_show_columns(settings):
+    settings.PERF_REC = {'HIDE_COLUMNS': False}
+
+    assert (
+        sql_fingerprint('SELECT f1, f2 FROM a GROUP BY f1 HAVING f1 > 21') ==
+        'SELECT f1, f2 FROM a GROUP BY f1 HAVING f1 > #'
+    )
+
+
 def test_select_group_by_having_multiple():
     assert (
         sql_fingerprint('SELECT f1, f2 FROM a GROUP BY f1 HAVING f1 > 21, f2 < 42') ==
@@ -81,6 +151,15 @@ def test_insert():
     )
 
 
+def test_insert_show_columns(settings):
+    settings.PERF_REC = {'HIDE_COLUMNS': False}
+
+    assert (
+        sql_fingerprint("INSERT INTO `table` (`f1`, `f2`) VALUES ('v1', 2)") ==
+        "INSERT INTO `table` (`f1`, `f2`) VALUES (#, #)"
+    )
+
+
 def test_update():
     assert (
         sql_fingerprint("UPDATE `table` SET `foo` = 'bar' WHERE `table`.`id` = 1") ==