Skip to content

Commit 64684de

Browse files
committed
Change named param binding to re-use value for same name
Relates to crate/crate#19193
1 parent 93b3ba6 commit 64684de

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

src/crate/client/cursor.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,25 @@ def _convert_named_to_positional(
4949
params = {"a": 1, "b": 2}
5050
# returns: ("SELECT * FROM t WHERE a = ? AND b = ?", [1, 2])
5151
"""
52-
positional: t.List[t.Any] = []
52+
positions = {}
53+
idx = 1
54+
new_params = []
55+
for k, v in params.items():
56+
positions[k] = idx
57+
new_params.append(v)
58+
idx += 1
5359

5460
def _replace(match: "re.Match[str]") -> str:
5561
name = match.group(1)
5662
if name not in params:
5763
raise ProgrammingError(
5864
f"Named parameter '{name}' not found in the parameters dict"
5965
)
60-
positional.append(params[name])
61-
return "?"
66+
position = positions[name]
67+
return f"${position}"
6268

6369
converted_sql = _NAMED_PARAM_RE.sub(_replace, sql)
64-
return converted_sql, positional
70+
return converted_sql, new_params
6571

6672

6773
class Cursor:

tests/client/test_cursor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ def test_execute_with_named_params(mocked_connection):
503503
{"a": 1, "b": 2},
504504
)
505505
mocked_connection.client.sql.assert_called_once_with(
506-
"SELECT * FROM t WHERE a = ? AND b = ?", [1, 2], None
506+
"SELECT * FROM t WHERE a = $1 AND b = $2", [1, 2], None
507507
)
508508

509509

@@ -515,7 +515,7 @@ def test_execute_with_named_params_repeated(mocked_connection):
515515
cursor = mocked_connection.cursor()
516516
cursor.execute("SELECT %(x)s, %(x)s", {"x": 42})
517517
mocked_connection.client.sql.assert_called_once_with(
518-
"SELECT ?, ?", [42, 42], None
518+
"SELECT $1, $1", [42], None
519519
)
520520

521521

0 commit comments

Comments
 (0)