mirror of
https://github.com/element-hq/synapse.git
synced 2026-08-16 02:30:26 +00:00
Synapse's schema setup (`prepare_database.py`) runs `;`-separated SQL scripts via the engine's `executescript`. `Cursor.execute` can't serve those: it `prepare`s the query, and Postgres rejects multiple commands in a prepared statement. Add `Cursor.executescript`, which runs the whole script on the simple-query protocol (`batch_execute`), which does allow multiple statements. It takes no parameters and produces no fetchable rows. The script runs inside the connection's *current* transaction (opened lazily like `execute`) and is left open for the caller to commit. It deliberately does NOT reproduce the commit-any-pending-transaction-first behaviour of `sqlite3.executescript` (which psycopg2's engine mirrors with a leading `COMMIT`). That forced commit actually undercuts the atomicity `prepare_database` sets out to get — it opens a transaction so "upgrades are either applied completely, or not at all", but the first script's implicit commit ends it. Running the script within the ongoing transaction instead lets successive scripts accumulate and be committed once, which is both simpler and more correct. The only engine-level piece left to layer on top is the auto-increment placeholder substitution. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>