Skip to content

Commit 950ba51

Browse files
Close regexp_match in the dialect requirements
SQLAlchemy's portable ``col.regexp_match(pattern)`` operator compiles to ``col REGEXP ?``, which SQLite dispatches to a user-defined ``regexp`` function. pysqlite installs that function via ``create_function`` on every new connection; dqlitedbapi is a network DBAPI and has no equivalent hook — registering a server-side function would require persisting into Raft state across all nodes, which the dqlite protocol does not expose. The compliance suite would otherwise exercise regexp_match and fail with ``no such function: regexp``; close the requirement so those cases are skipped instead. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3752729 commit 950ba51

2 files changed

Lines changed: 27 additions & 0 deletions

File tree

src/sqlalchemydqlite/requirements.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,21 @@ def emulated_lastrowid(self) -> Any:
137137
def supports_empty_inserts(self) -> Any:
138138
"""INSERT INTO t DEFAULT VALUES. SQLite supports it; dqlite inherits."""
139139
return exclusions.open()
140+
141+
@property
142+
def regexp_match(self) -> Any:
143+
"""The portable ``col.regexp_match(pattern)`` operator compiles
144+
to ``col REGEXP ?``, which SQLite dispatches to a user-defined
145+
``regexp`` function. pysqlite registers that function via
146+
``dbapi_connection.create_function`` on every new connection
147+
(see ``SQLiteDialect_pysqlite.on_connect``); dqlite is a network
148+
DBAPI and has no ``create_function`` hook — registering a
149+
server-side function would require persisting into Raft state
150+
across all nodes, which is not part of the dqlite protocol.
151+
152+
Running the compliance suite's ``regexp_match`` cases against
153+
dqlite would therefore hit ``OperationalError: no such function:
154+
regexp``. Close the requirement so the suite skips those cases
155+
instead of failing.
156+
"""
157+
return exclusions.closed()

tests/test_requirements.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def test_properties_return_exclusion_objects(self) -> None:
1919
"sane_multi_rowcount",
2020
"emulated_lastrowid",
2121
"supports_empty_inserts",
22+
"regexp_match",
2223
]
2324
for prop_name in properties:
2425
value = getattr(req, prop_name)
@@ -30,3 +31,11 @@ def test_properties_return_exclusion_objects(self) -> None:
3031
assert hasattr(value, "enabled_for_config"), (
3132
f"Requirements.{prop_name} return value lacks enabled_for_config method"
3233
)
34+
35+
def test_regexp_match_is_closed(self) -> None:
36+
"""dqlite has no server-side REGEXP function and no
37+
``create_function`` hook on the DBAPI, so the compliance suite
38+
must skip ``regexp_match`` cases rather than run them and fail.
39+
"""
40+
req = Requirements()
41+
assert req.regexp_match.enabled is False

0 commit comments

Comments
 (0)