v1.3.0 — DDL that gives up instead of piling up
A safety release. Structural changes now bound how long they wait for a lock, and write mode in the SQL runner works from the UI for the first time.
Changed
- DDL gives up instead of piling up — every
ALTER/DROP/TRUNCATE/ rename on a table, column, schema or role runs under a shortlock_timeout(2s;lock_wait_timeouton MySQL, whose own default is a full year). A DDL statement waiting for its exclusive lock parks every later query behind it, plainSELECTs included, until the connection pool runs dry — so the wait is now bounded, and a change that can't get its lock fails in seconds saying nothing was changed. It bounds the wait, not the hold: a rewrite still keeps its lock while it runs.CREATE/DROP INDEX CONCURRENTLYare deliberately exempt — they block nobody, and timing them out is what leaves an invalid index behind. - Write mode offers the same guard — hand-written DDL can park a table exactly like the buttons can, so write mode runs under the same
lock_timeout, shown in the header and turned off with a checkbox when you mean to wait.
Fixed
- Write mode never reached the server — the runner's mode toggles sit outside its
<form>, and htmx only serializes a form's own descendants, sowrite=1was dropped from every request: the panel showed write mode armed while the server ran the statement read-only, and the safety snapshot that precedes a write never ran. The form now includes the toggles explicitly. - Unindexed foreign keys no longer counts a partial or invalid index as covering a foreign key.
Added
- Locks: head-blocker chains — the wait-for graph folded into trees rooted at the session that is holding a lock and waiting on nothing, so the highest-leverage cancel is at the top. Cycles are detected and flagged. Engine-agnostic.
- Health: orphan rows — foreign keys left
NOT VALIDand*_idcolumns with no FK that name-match a primary key, each with an on-demand read-only anti-join count that never validates or changes anything. - Extensions panel — what's installed and what the server could install (
\dxunioned withpg_available_extensions), with an update-available badge. - JSON shape — an on-demand sampled view of a
json/jsonbcolumn's top-level keys, value types, nesting depth and GIN coverage. - Replication: replay lag in time, not just bytes.
- Opt-in Airlines demo database for realistic data volume.
Full changelog: https://github.com/MR-TABATA/cli2ui/blob/main/CHANGELOG.md