- Remove WITH from _READ_ONLY_COMMANDS; scan CTE body for write keywords so
writable CTEs like `WITH d AS (DELETE …) SELECT …` are blocked in read-only mode.
- EXPLAIN ANALYZE/ANALYSE now resolves the underlying command; EXPLAIN ANALYZE DELETE
is treated as a write and blocked in read-only mode.
- execute_sql commit decision now checks ALL semicolon-separated statements so
a SELECT-first batch like `SELECT 1; DROP TABLE t` still triggers a commit
when allow_dml=True.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>