Skip to content

format_group_by_params mishandles escaped %% causing IndexError on queries with GROUP BY #476

@kolatat

Description

@kolatat

Software versions

  • mssql-django: 1.6
  • python: 3.12

Problem description and steps to reproduce
When a MSSQL query cursor is executed with parameters, there is an error.
Conditions:

  • SQL query with a GROUP BY clause
  • an escaped % somewhere in the query (%%)
  • valid parameters

Expected behavior and actual behavior
Expected: query is executed, with correct parameters substituted in, and escaped %% treated correctly as % literal.
Actual: error on query execution, saying replacement arguments # mismatched.

Error message/stack trace

IndexError: Replacement index 10 out of range for positional args tuple
...
Traceback (most recent call last):
...
  File "my/views.py", line 3620, in ***
    cursor.execute(sql, [...])

  File ".../lib/python3.12/site-packages/django/db/backends/utils.py", line 122, in execute
    return super().execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../lib/python3.12/site-packages/django/db/backends/utils.py", line 79, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../lib/python3.12/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../lib/python3.12/site-packages/django/db/backends/utils.py", line 105, in _execute
    return self.cursor.execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../lib/python3.12/site-packages/mssql/base.py", line 672, in execute
    sql, params = self.format_group_by_params(sql, params)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../lib/python3.12/site-packages/mssql/base.py", line 640, in format_group_by_params
    query = ('DECLARE %s \n' % ','.join(variables)) + (query.format(*args))
                                                       ^^^^^^^^^^^^^^^^^^^
IndexError: Replacement index 10 out of range for positional args tuple

Any other details that can be helpful

in mssql/base.py#L624 (def format_group_by_params), regexp %\w+ is used to substitute %s with {}. This does not account for escaped % (%%), resulting in the mismatched replacements.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions