Skip to content

v1.3.0 — DDL that gives up instead of piling up

Choose a tag to compare

@MR-TABATA MR-TABATA released this 08 Aug 13:20
· 10 commits to main since this release

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 short lock_timeout (2s; lock_wait_timeout on MySQL, whose own default is a full year). A DDL statement waiting for its exclusive lock parks every later query behind it, plain SELECTs 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 CONCURRENTLY are 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, so write=1 was 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 VALID and *_id columns 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 (\dx unioned with pg_available_extensions), with an update-available badge.
  • JSON shape — an on-demand sampled view of a json/jsonb column'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