diff --git a/ietf/context_processors.py b/ietf/context_processors.py
index d101483f5..7f5062cd5 100644
--- a/ietf/context_processors.py
+++ b/ietf/context_processors.py
@@ -18,6 +18,12 @@ def debug_mark_queries_from_view(request):
if settings.DEBUG and request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:
from django.db import connection
for query in connection.queries:
- query['where'] = 'V' # V is for 'view'
+ query['loc'] = 'V' # V is for 'view'
return context_extras
+
+def sql_debug(request):
+ if settings.DEBUG and request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:
+ return {'sql_debug': True }
+ else:
+ return {'sql_debug': False }
diff --git a/ietf/templates/debug.html b/ietf/templates/debug.html
index 1a8300efd..2b7c0d694 100644
--- a/ietf/templates/debug.html
+++ b/ietf/templates/debug.html
@@ -1,43 +1,49 @@
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}{% origin %}
{% if debug %}
- {% load debug_filters %}
- {% load future %}
+ {% if sql_debug %}
+ {% load debug_filters %}
+ {% load future %}
-
-
-
- {{ sql_queries|length }} queries ({{ sql_queries|timesum }}s)
- {% if sql_queries|length != 0 %}
- Show
- {% endif %}
-
-
-
-
- # |
- SQL |
- Count |
- View/ Templ. |
- Time |
- Acc. |
-
-
-
- {% with sql_queries|annotate_sql_queries as sql_query_info %}
- {% for query in sql_query_info %}
-
- {{ forloop.counter }} |
- {{ query.sql|expand_comma|escape }} |
- {{ query.count }} |
- {{ query.where }} |
- {{ query.time }} |
- {{ query.time_accum }} |
-
- {% endfor %}
- {% endwith %}
-
-
-
+
+
+
+ {{ sql_queries|length }} queries ({{ sql_queries|timesum }}s)
+ {% if sql_queries|length != 0 %}
+ Show
+ {% endif %}
+
+
+
+
+ # |
+ SQL |
+ Count |
+ WHERE |
+ View/ Templ. |
+ Time |
+ Acc. |
+
+
+
+ {% with sql_queries|annotate_sql_queries as sql_query_info %}
+ {% for query in sql_query_info %}
+
+ {{ forloop.counter }} |
+ {{ query.sql|expand_comma|escape }} |
+ {{ query.count }} |
+ {{ query.where }} |
+ {{ query.loc }} |
+ {{ query.time }} |
+ {{ query.time_accum }} |
+
+ {% endfor %}
+ {% endwith %}
+
+
+
+ {% else %}
+ Add 'ietf.context_processors.sql_debug' to settings.TEMPLATE_CONTECT_PROCESSORS to turn on the SQL statement table
+ {% endif %}
{% endif %}
diff --git a/ietf/utils/templatetags/debug_filters.py b/ietf/utils/templatetags/debug_filters.py
index 3f8b63f86..209d52fa8 100644
--- a/ietf/utils/templatetags/debug_filters.py
+++ b/ietf/utils/templatetags/debug_filters.py
@@ -1,3 +1,6 @@
+import sys
+import sqlparse
+
from django import template
register = template.Library()
@@ -20,12 +23,43 @@ def expand_comma(value):
return value.replace(",", ", ")
+def get_sql_parts(sql):
+ q = {}
+ s = sqlparse.parse(sql)[0] # assuming there's only one statement
+ q['where'] = None
+ q['from'] = None
+ # use sqlparse to pick out some interesting parts of the statement
+ state = None
+ for e in s:
+ if e.is_whitespace:
+ continue
+ if state == None:
+ if e.is_keyword:
+ key = e.normalized.lower()
+ state = 'value'
+ elif e.is_group and e[0].is_keyword:
+ key = e[0].normalized.lower()
+ val = str(e)
+ state = 'store'
+ else:
+ pass
+ elif state == 'value':
+ val = str(e)
+ state = 'store'
+ else:
+ sys.stderr.write("Unexpected sqlparse iteration state in annotate_sql_queries(): '%s'" % state )
+ if state == 'store':
+ q[key] = val
+ state = None
+ return q
+
@register.filter()
def annotate_sql_queries(queries):
counts = {}
timeacc = {}
for q in queries:
sql = q['sql']
+ q.update(get_sql_parts(sql))
if not sql in counts:
counts[sql] = 0;
counts[sql] += 1
@@ -33,8 +67,8 @@ def annotate_sql_queries(queries):
timeacc[sql] = 0.0;
timeacc[sql] += float(q['time'])
for q in queries:
- if q.get('where', None) == None:
- q['where'] = 'T' # template
+ if q.get('loc', None) == None:
+ q['loc'] = 'T' # template
sql = q['sql']
q['count'] = str(counts[sql])
q['time_accum'] = "%4.3f" % timeacc[sql]