Skip to content

Commit 3833499

Browse files
committed
refactor(driver): extract qc_prepare to consolidate sync/async duplication
Move eligibility checks and preparation logic from qc_lookup into new qc_prepare method in _common.py. This eliminates ~15 lines of duplicated logic between sync and async implementations. Before: qc_lookup in both _common.py and _async.py contained identical eligibility checking, cache lookup, rebinding, and statement building. After: qc_prepare does all preparation work, qc_lookup becomes a thin wrapper that calls qc_prepare then qc_execute. Chapter 3 of driver-arch-cleanup_20260203 PRD.
1 parent 61d1ff9 commit 3833499

File tree

2 files changed

+43
-21
lines changed

2 files changed

+43
-21
lines changed

sqlspec/driver/_async.py

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -305,26 +305,19 @@ async def dispatch_special_handling(self, cursor: Any, statement: "SQL") -> "SQL
305305
async def qc_lookup(
306306
self, statement: str, params: "tuple[Any, ...] | list[Any]"
307307
) -> "SQLResult | None":
308-
if not self._qc_enabled:
309-
return None
310-
if self.statement_config.parameter_config.needs_static_script_compilation:
311-
return None
312-
cached = self._qc.get(statement)
313-
if cached is None:
314-
return None
315-
if cached.param_count != len(params):
316-
return None
317-
if isinstance(params, list) and params and isinstance(params[0], (tuple, list, dict)) and len(params) > 1:
318-
return None
308+
"""Attempt fast-path execution for cached query (async).
319309
320-
rebound_params = self.qc_rebind(params, cached)
321-
compiled_sql = cached.compiled_sql
322-
output_transformer = self.statement_config.output_transformer
323-
if output_transformer:
324-
compiled_sql, rebound_params = output_transformer(compiled_sql, rebound_params)
310+
Args:
311+
statement: Raw SQL string.
312+
params: Query parameters.
325313
326-
fast_statement = self.qc_build(statement, params, cached, rebound_params)
327-
return await self.qc_execute(fast_statement, compiled_sql, rebound_params)
314+
Returns:
315+
SQLResult if cache hit and execution succeeds, None otherwise.
316+
"""
317+
prep = self.qc_prepare(statement, params)
318+
if prep is None:
319+
return None
320+
return await self.qc_execute(*prep)
328321

329322
async def qc_execute(self, statement: "SQL", sql: str, params: Any) -> "SQLResult":
330323
_ = (sql, params)

sqlspec/driver/_common.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,13 +1002,24 @@ def qc_build(
10021002
)
10031003
return statement
10041004

1005-
def qc_lookup(
1005+
def qc_prepare(
10061006
self, statement: str, params: "tuple[Any, ...] | list[Any]"
1007-
) -> "SQLResult | None":
1007+
) -> "tuple[SQL, str, Any] | None":
1008+
"""Prepare fast-path execution if cache hit.
1009+
1010+
Args:
1011+
statement: Raw SQL string.
1012+
params: Query parameters (tuple or list).
1013+
1014+
Returns:
1015+
Tuple of (SQL object, compiled SQL, bound params) if cache hit,
1016+
None if cache miss or ineligible.
1017+
"""
10081018
if not self._qc_enabled:
10091019
return None
10101020
if self.statement_config.parameter_config.needs_static_script_compilation:
10111021
return None
1022+
10121023
cached = self._qc.get(statement)
10131024
if cached is None:
10141025
return None
@@ -1019,12 +1030,30 @@ def qc_lookup(
10191030

10201031
rebound_params = self.qc_rebind(params, cached)
10211032
compiled_sql = cached.compiled_sql
1033+
10221034
output_transformer = self.statement_config.output_transformer
10231035
if output_transformer:
10241036
compiled_sql, rebound_params = output_transformer(compiled_sql, rebound_params)
10251037

10261038
fast_statement = self.qc_build(statement, params, cached, rebound_params)
1027-
return cast("SQLResult", self.qc_execute(fast_statement, compiled_sql, rebound_params))
1039+
return fast_statement, compiled_sql, rebound_params
1040+
1041+
def qc_lookup(
1042+
self, statement: str, params: "tuple[Any, ...] | list[Any]"
1043+
) -> "SQLResult | None":
1044+
"""Attempt fast-path execution for cached query.
1045+
1046+
Args:
1047+
statement: Raw SQL string.
1048+
params: Query parameters.
1049+
1050+
Returns:
1051+
SQLResult if cache hit and execution succeeds, None otherwise.
1052+
"""
1053+
prep = self.qc_prepare(statement, params)
1054+
if prep is None:
1055+
return None
1056+
return cast("SQLResult", self.qc_execute(*prep))
10281057

10291058
def qc_execute(self, statement: "SQL", sql: str, params: Any) -> "SQLResult | Awaitable[SQLResult]":
10301059
raise NotImplementedError

0 commit comments

Comments
 (0)