Skip to content

Commit f6e0a1a

Browse files
authored
fix: driver parameter normalization (#333)
Corrected a few issues with the driver normalization configs and functions.
1 parent de7b813 commit f6e0a1a

File tree

25 files changed

+2534
-344
lines changed

25 files changed

+2534
-344
lines changed

sqlspec/adapters/asyncmy/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def build_profile() -> "DriverParameterProfile":
125125
return DriverParameterProfile(
126126
name="AsyncMy",
127127
default_style=ParameterStyle.QMARK,
128-
supported_styles={ParameterStyle.QMARK, ParameterStyle.POSITIONAL_PYFORMAT},
128+
supported_styles={ParameterStyle.QMARK},
129129
default_execution_style=ParameterStyle.POSITIONAL_PYFORMAT,
130130
supported_execution_styles={ParameterStyle.POSITIONAL_PYFORMAT},
131131
has_native_list_expansion=False,

sqlspec/adapters/asyncpg/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def build_profile() -> "DriverParameterProfile":
121121
return DriverParameterProfile(
122122
name="AsyncPG",
123123
default_style=ParameterStyle.NUMERIC,
124-
supported_styles={ParameterStyle.NUMERIC, ParameterStyle.POSITIONAL_PYFORMAT},
124+
supported_styles={ParameterStyle.NUMERIC, ParameterStyle.NAMED_COLON},
125125
default_execution_style=ParameterStyle.NUMERIC,
126126
supported_execution_styles={ParameterStyle.NUMERIC},
127127
has_native_list_expansion=True,

sqlspec/adapters/bigquery/core.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
ParameterProfile,
1919
ParameterStyle,
2020
StatementConfig,
21+
build_null_pruning_transform,
2122
build_statement_config_from_profile,
2223
)
2324
from sqlspec.exceptions import (
@@ -612,6 +613,7 @@ def build_profile() -> "DriverParameterProfile":
612613
list: _identity,
613614
type(None): _return_none,
614615
},
616+
default_ast_transformer=build_null_pruning_transform(dialect="bigquery"),
615617
extras={"json_tuple_strategy": "tuple", "type_coercion_overrides": {list: _identity, tuple: _tuple_to_list}},
616618
default_dialect="bigquery",
617619
)

sqlspec/adapters/duckdb/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def build_profile() -> "DriverParameterProfile":
145145
default_style=ParameterStyle.QMARK,
146146
supported_styles={ParameterStyle.QMARK, ParameterStyle.NUMERIC, ParameterStyle.NAMED_DOLLAR},
147147
default_execution_style=ParameterStyle.QMARK,
148-
supported_execution_styles={ParameterStyle.QMARK},
148+
supported_execution_styles={ParameterStyle.QMARK, ParameterStyle.NUMERIC},
149149
has_native_list_expansion=True,
150150
preserve_parameter_format=True,
151151
needs_static_script_compilation=False,

sqlspec/adapters/mysqlconnector/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def build_profile() -> "DriverParameterProfile":
108108
return DriverParameterProfile(
109109
name="mysql-connector",
110110
default_style=ParameterStyle.QMARK,
111-
supported_styles={ParameterStyle.QMARK, ParameterStyle.POSITIONAL_PYFORMAT},
111+
supported_styles={ParameterStyle.QMARK},
112112
default_execution_style=ParameterStyle.POSITIONAL_PYFORMAT,
113113
supported_execution_styles={ParameterStyle.POSITIONAL_PYFORMAT},
114114
has_native_list_expansion=False,

sqlspec/adapters/oracledb/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,8 @@ def build_profile() -> "DriverParameterProfile":
531531
"""Create the OracleDB driver parameter profile."""
532532
return DriverParameterProfile(
533533
name="OracleDB",
534-
default_style=ParameterStyle.POSITIONAL_COLON,
535-
supported_styles={ParameterStyle.NAMED_COLON, ParameterStyle.POSITIONAL_COLON, ParameterStyle.QMARK},
534+
default_style=ParameterStyle.NAMED_COLON,
535+
supported_styles={ParameterStyle.NAMED_COLON, ParameterStyle.NUMERIC, ParameterStyle.QMARK},
536536
default_execution_style=ParameterStyle.NAMED_COLON,
537537
supported_execution_styles={ParameterStyle.NAMED_COLON, ParameterStyle.POSITIONAL_COLON},
538538
has_native_list_expansion=False,

sqlspec/adapters/psycopg/core.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,8 @@ def build_profile() -> "DriverParameterProfile":
160160

161161
return DriverParameterProfile(
162162
name="Psycopg",
163-
default_style=ParameterStyle.POSITIONAL_PYFORMAT,
164-
supported_styles={
165-
ParameterStyle.POSITIONAL_PYFORMAT,
166-
ParameterStyle.NAMED_PYFORMAT,
167-
ParameterStyle.NUMERIC,
168-
ParameterStyle.QMARK,
169-
},
163+
default_style=ParameterStyle.NUMERIC,
164+
supported_styles={ParameterStyle.NUMERIC, ParameterStyle.NAMED_COLON},
170165
default_execution_style=ParameterStyle.POSITIONAL_PYFORMAT,
171166
supported_execution_styles={ParameterStyle.POSITIONAL_PYFORMAT, ParameterStyle.NAMED_PYFORMAT},
172167
has_native_list_expansion=True,

sqlspec/adapters/pymysql/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def build_profile() -> "DriverParameterProfile":
108108
return DriverParameterProfile(
109109
name="PyMySQL",
110110
default_style=ParameterStyle.QMARK,
111-
supported_styles={ParameterStyle.QMARK, ParameterStyle.POSITIONAL_PYFORMAT},
111+
supported_styles={ParameterStyle.QMARK},
112112
default_execution_style=ParameterStyle.POSITIONAL_PYFORMAT,
113113
supported_execution_styles={ParameterStyle.POSITIONAL_PYFORMAT},
114114
has_native_list_expansion=False,

sqlspec/adapters/spanner/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ def _create_pool(self) -> AbstractSessionPool:
272272
def _close_pool(self) -> None:
273273
if self.connection_instance and supports_close(self.connection_instance):
274274
self.connection_instance.close()
275+
if self._client and supports_close(self._client):
276+
self._client.close()
277+
self._client = None
278+
self._database = None
275279

276280
def provide_connection(self, *args: Any, transaction: "bool" = False, **kwargs: Any) -> "SpannerConnectionContext":
277281
"""Yield a Snapshot (default) or Transaction context from the configured pool.

sqlspec/core/parameters/_alignment.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,17 @@ def collect_null_parameter_ordinals(parameters: Any, profile: "ParameterProfile"
106106

107107
def _collect_expected_identifiers(parameter_profile: "ParameterProfile") -> "set[tuple[str, int | str]]":
108108
identifiers: set[tuple[str, int | str]] = set()
109-
for parameter in parameter_profile.parameters:
109+
parameters = parameter_profile.parameters
110+
if not parameters:
111+
return identifiers
112+
113+
# Check if we have mixed styles - if so, use ordinal-based counting for positional styles
114+
styles = {p.style for p in parameters}
115+
has_mixed_positional_styles = len(styles) > 1 and any(
116+
s in styles for s in {ParameterStyle.QMARK, ParameterStyle.POSITIONAL_PYFORMAT}
117+
)
118+
119+
for parameter in parameters:
110120
style = parameter.style
111121
name = parameter.name
112122
if style in {
@@ -117,7 +127,10 @@ def _collect_expected_identifiers(parameter_profile: "ParameterProfile") -> "set
117127
}:
118128
identifiers.add(("named", name or f"param_{parameter.ordinal}"))
119129
elif style in {ParameterStyle.NUMERIC, ParameterStyle.POSITIONAL_COLON}:
120-
if name and name.isdigit():
130+
# When mixed with ordinal styles (like QMARK), use ordinal instead of explicit index
131+
if has_mixed_positional_styles:
132+
identifiers.add(("index", parameter.ordinal))
133+
elif name and name.isdigit():
121134
identifiers.add(("index", int(name) - 1))
122135
else:
123136
identifiers.add(("index", parameter.ordinal))

0 commit comments

Comments
 (0)