@@ -869,49 +869,49 @@ def test_explain_with_union(self):
869869 query = self .panel ._queries [0 ]
870870 self .assertTrue (query ["is_select" ])
871871
872- @override_settings (
873- DEBUG_TOOLBAR_CONFIG = {"SQL_PRETTIFY_MAX_LENGTH" : 100 , "PRETTIFY_SQL" : True }
874- )
875- def test_sql_prettify_max_length (self ):
872+ @override_settings (DEBUG_TOOLBAR_CONFIG = {"PRETTIFY_SQL" : True })
873+ def test_sql_parse_error_graceful_degradation (self ):
876874 """
877- Test that SQL formatting is skipped for queries exceeding the max length threshold .
875+ Test that SQLParseError is handled gracefully by disabling grouping .
878876 """
879- from debug_toolbar . panels . sql . utils import reformat_sql
877+ from unittest . mock import patch
880878
881- # Short SQL should be formatted normally
882- short_sql = "SELECT * FROM auth_user WHERE id = 1"
883- result = reformat_sql (short_sql , with_toggle = True )
884- self .assertNotIn ("SQL formatting skipped" , result )
885- self .assertIn ("SELECT" , result )
879+ from sqlparse .exceptions import SQLParseError
886880
887- # Long SQL should skip formatting and show a message
888- long_sql = (
889- "SELECT * FROM auth_user WHERE id IN ("
890- + ", " .join ([f"'{ i } '" for i in range (100 )])
891- + ")"
892- )
893- result = reformat_sql (long_sql , with_toggle = True )
894- self .assertIn ("SQL formatting skipped" , result )
895- self .assertIn ("exceeds threshold" , result )
881+ from debug_toolbar .panels .sql .utils import parse_sql
896882
897- def test_sql_prettify_max_length_disabled (self ):
898- """
899- Test that SQL_PRETTIFY_MAX_LENGTH=0 or None disables the length check.
900- """
901- from debug_toolbar .panels .sql .utils import reformat_sql
883+ # Clear the cache to ensure our mock is used
884+ parse_sql .cache_clear ()
902885
903- long_sql = (
904- "SELECT * FROM auth_user WHERE id IN ("
905- + ", " .join ([f"'{ i } '" for i in range (100 )])
906- + ")"
907- )
886+ # Mock the filter stack to raise SQLParseError on first call
887+ call_count = 0
888+ original_run = None
889+
890+ def mock_run (sql ):
891+ nonlocal call_count , original_run
892+ call_count += 1
893+ if call_count == 1 :
894+ raise SQLParseError ("Token limit exceeded" )
895+ # On retry, return a simple result
896+ return [sql ]
897+
898+ with patch (
899+ "debug_toolbar.panels.sql.utils.get_filter_stack"
900+ ) as mock_get_stack :
901+ mock_stack = mock_get_stack .return_value
902+ mock_stack .run = mock_run
903+ mock_stack ._grouping = True
904+
905+ result = parse_sql ("SELECT * FROM test" )
906+
907+ # Should have been called twice (once for error, once for retry)
908+ self .assertEqual (call_count , 2 )
909+ # On retry, _grouping should be set to False
910+ self .assertFalse (mock_stack ._grouping )
911+ self .assertIn ("SELECT" , result )
908912
909- with override_settings (
910- DEBUG_TOOLBAR_CONFIG = {"SQL_PRETTIFY_MAX_LENGTH" : 0 , "PRETTIFY_SQL" : True }
911- ):
912- result = reformat_sql (long_sql , with_toggle = True )
913- # When max_length is 0 (falsy), formatting should not be skipped
914- self .assertNotIn ("SQL formatting skipped" , result )
913+ # Clear the cache after the test
914+ parse_sql .cache_clear ()
915915
916916
917917class SQLPanelMultiDBTestCase (BaseMultiDBTestCase ):
0 commit comments