Add meta.find_schema_problems(); every install runs 00-10; drop migrations

09_schema_check.sql adds meta.find_schema_problems(), a read-only check
any client (Python, C++, psql) can call:

    SELECT * FROM meta.find_schema_problems();   -- zero rows = usable

One row per problem (object, problem): missing schemas, extension,
sequences, tables, columns, wrong column type or NOT NULL, missing
constraints, indexes, views, stored-function bodies that differ from the
DDL (whitespace-insensitive md5 fingerprint), a missing/disabled/
misdirected event trigger, short reference data, no version row. It
mirrors 00-08 and must change in the same commit as they do; the
release test (a fresh install returns zero rows) enforces that.

10_schema_version.sql records VERSION in meta.schema_version. Before,
only the Python client wrote that row, so databases provisioned by
run_setup.py recorded no version at all.

run_setup.py now runs 00-10. It skipped 08_script_log.sql, so its
databases lacked a table the Python client uses; every fresh install is
now identical regardless of provisioner.

sql/migrate/ is removed: databases are re-provisioned, not migrated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
peter 2026-10-06 11:01:28 +01:00
parent 6dde987cfb
commit 1f5cfeceeb
7 changed files with 367 additions and 269 deletions

View file

@ -30,13 +30,15 @@ TSAPI_SERIESDB_SCHEMA/
├── 04_indexes.sql # indexes + registry constraints
├── 05_procedures.sql # meta.* / log.* stored procedures
├── 06_triggers.sql # prevent_series_drops event trigger
├── 07_reference_data.sql # timezones + currencies reference data
├── 08_script_log.sql # auxiliary (not part of a fresh install)
└── migrate/ # one-off migration scripts (run manually)
├── 07_reference_data.sql # timezones + currencies + security types
├── 08_script_log.sql # log.script_log table + view
├── 09_schema_check.sql # meta.find_schema_problems()
└── 10_schema_version.sql # records VERSION in meta.schema_version
```
`run_setup.py` executes `00`–`07` in order. `08_script_log.sql` and
`sql/migrate/*.sql` are auxiliary and are **not** run by a fresh install.
Every fresh install runs `00`–`10` in order (`run_setup.py`, and the Python
client's `init_postgres_db()`). There are no migration scripts: a database
from an older schema is re-provisioned, not upgraded.
---
@ -74,6 +76,7 @@ database.
`log.flush_pending_to_event_log`.
- **Event trigger:** `prevent_series_drops` — blocks direct `DROP TABLE` on a
registered series (drops must go through `meta.drop_series*`).
- **Self-check:** `meta.find_schema_problems()` — see below.
Series data tables have **no `UNIQUE` constraint on `timestamp`** — the index is
BRIN. Concurrent writers must serialise per-series with the advisory-lock
@ -82,11 +85,33 @@ the C++ project's `planning/2026-09-02_cpp_locking_interop_plan.md`.
---
## Checking a database
```sql
SELECT * FROM meta.find_schema_problems(); -- zero rows = complete and usable
```
One row per problem, `(object, problem)`, for example
`('table meta.instruments', 'missing columns: sector')`. Read-only. It checks
schemas, the extension, sequences, every table column's type and NOT NULL,
constraints, indexes, views, stored-function bodies (whitespace-insensitive
fingerprint), the event trigger, reference-data row counts and that a version
row exists. If the function itself does not exist, the database is not
initialized or predates it -- re-provision.
`09_schema_check.sql` mirrors `00`–`08`: **change it in the same commit as any
of them**. The release test -- a freshly provisioned database must return
zero rows -- fails until you do. The file's header shows how to refresh the
function-body fingerprints.
---
## Versioning contract
Bump [`VERSION`](VERSION) whenever `sql/` changes in a way clients must know
about, and have each client read `meta.schema_version` on connect and warn/fail
on mismatch. This turns silent schema drift into a loud error.
Bump [`VERSION`](VERSION) -- and the string in `10_schema_version.sql` -- whenever
`sql/` changes in a way clients must know about. Each client compares
`meta.schema_version` with the version it was built for on connect, and calls
`meta.find_schema_problems()` for everything else.
---