Skip to content

support for column names and other names that contain question marks without being flagged as a bound parameter issue #464

@zzzeek

Description

@zzzeek

Describe the bug

we have tests for so-called "difficult column/parameter names" with various funny characters and things in column names and bound parameter names. A column name that includes a question mark seems to produce scenarios where querying against the table is impossible.

Stack trace:

Traceback (most recent call last):
  File "/home/classic/dev/sqlalchemy/test3.py", line 27, in <module>
    cursor.execute(
    ~~~~~~~~~~~~~~^
        "SELECT * FROM t WHERE [q?marks]=%(somename)",
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        {"somename": "thename"}
        ^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/classic/.venv3/lib/python3.14/site-packages/mssql_python/cursor.py", line 1331, in execute
    operation, converted_params = detect_and_convert_parameters(operation, actual_params)
                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/classic/.venv3/lib/python3.14/site-packages/mssql_python/parameter_helper.py", line 325, in detect_and_convert_parameters
    raise TypeError(
    ...<4 lines>...
    )
TypeError: Parameter style mismatch: query uses positional placeholders (?), but dict was provided. Use tuple/list for positional parameters. Example: cursor.execute(sql, (value1, value2))


To reproduce

from mssql_python import connect

conn_str = "UID=scott;PWD=tiger^5HHH;Server=mssql2022;Database=test;Encrypt=No"
conn = connect(conn_str)
cursor = conn.cursor()

cursor.execute("drop table if exists t")

# statement that has no parameter dictionary, this works because
# it isn't trying to do anything with parameters
cursor.execute("""

CREATE TABLE t (
	id INTEGER NOT NULL IDENTITY,
	[q?marks] VARCHAR(50) NOT NULL,
	PRIMARY KEY (id)
)

""")

# statement that has a parameter dictionary, we get the error
# "Parameter style mismatch: query uses positional placeholders (?), but dict
# was provided. Use tuple/list for positional parameters."
#
# which is not actually correct, we have a named parameter in there as well.
# but even so, how to indicate the question mark?   some kind of escaping?
cursor.execute(
    "SELECT * FROM t WHERE [q?marks]=%(somename)",
    {"somename": "thename"}
)

Expected behavior

the driver does not assume the ? is attempting to be a parameter placeholder, or some form of escaping (like \?, ?? etc.) is made available so that this character may be used

Further technical details

version 1.4.0 of the driver

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinginADOtriage doneIssues that are triaged by dev team and are in investigation.

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions