kokhlo opened a new pull request, #45180:
URL: https://github.com/apache/superset/pull/45180
### Summary
Fixes #38453.
duckdb-engine subclasses the psycopg2 PostgreSQL dialect, whose class-level
`_backslash_escapes` default is `True`. Unlike PostgreSQL, the DuckDB dialect
never runs `_set_backslash_escapes` against a live connection (there is no
`standard_conforming_strings` knob), so the flag stays `True` for the engine's
whole lifetime. Every string literal compiled with `literal_binds` — which is
how Superset renders filter values on the main query path
(`Database.compile_sqla_query`) — therefore doubles its backslashes:
```python
column("columnA").in_(["name\\email"]).compile(engine,
compile_kwargs={"literal_binds": True})
# renders: columnA IN ('name\\email') <- a literal double backslash
```
DuckDB has no escape character at all, so it reads `'name\\email'` as a
two-backslash value that never equals the original `name\email` — filters
silently match zero rows (the reporter's case: DuckDB 1.3.0, duckdb-engine
0.17.0, Superset 6.0).
The fix overrides `register_engine_events` on `DuckDBEngineSpec` (the
sanctioned hook called right after `create_engine`) to set
`engine.dialect._backslash_escapes = False`. MotherDuck inherits it. This
mirrors the existing `_normalize_postgresql_backslash_escapes` correction in
`superset/jinja_context.py` for the Jinja/PostgreSQL path — but the main
compile path had no such correction for duckdb.
Verified against a live in-process DuckDB instance (probe on sqlalchemy
2.0.52 + duckdb-engine 0.17.0, the pinned versions): pre-fix `SELECT
'name\\email' = 'name\email'` → False (zero-row match); post-fix the compiled
literal round-trips and matches.
### Testing
- RED→GREEN: both new tests fail without the spec change, pass with it.
- `pytest tests/unit_tests/db_engine_specs/test_duckdb.py -q` → **19
passed** (17 pre-existing + 2 new):
- `test_register_engine_events_disables_backslash_escaping` — the dialect
flag is off after the hook.
- `test_backslash_filter_value_compiles_verbatim_and_matches` — end-to-end
against live in-process DuckDB: the compiled IN literal actually matches the
row containing the original value.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]