Skip to content

Commit 28ee021

Browse files
authored
Fix named parameter regex to allow non-identifier characters and add test (#809)
1 parent 644ff79 commit 28ee021

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

src/crate/client/cursor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from .converter import Converter, DataType
2727
from .exceptions import ProgrammingError
2828

29-
_NAMED_PARAM_RE = re.compile(r"%\((\w+)\)s")
29+
_NAMED_PARAM_RE = re.compile(r"%\(([^)]+)\)s")
3030

3131

3232
def _convert_named_to_positional(

tests/client/test_cursor.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,24 @@ def test_execute_with_named_params_missing(mocked_connection):
565565
mocked_connection.client.sql.assert_not_called()
566566

567567

568+
def test_execute_with_named_params_non_identifier_keys(mocked_connection):
569+
"""
570+
Verify that %(name)s placeholders whose name contains characters outside
571+
[a-zA-Z0-9_] are still converted to positional $N markers.
572+
573+
"""
574+
cursor = mocked_connection.cursor()
575+
576+
cursor.execute(
577+
"UPDATE characters SET data['x'] = %(data['x'])s WHERE name = %(name)s",
578+
{"data['x']": 42, "name": "Berlin"},
579+
)
580+
sql, args, _ = mocked_connection.client.sql.call_args[0]
581+
assert "%" not in sql
582+
assert sql == "UPDATE characters SET data['x'] = $1 WHERE name = $2"
583+
assert args == [42, "Berlin"]
584+
585+
568586
def test_cursor_close(mocked_connection):
569587
"""
570588
Verify that a cursor is not closed if not specifically closed.

0 commit comments

Comments
 (0)