Skip to content

feat(location): sync every state table without waking a suspended warehouse - #1419

Merged
kvlonge merged 14 commits into
mainfrom
feat/sync-all-state-tables
Nov 11, 2026
Merged

kvlonge merged 14 commits into
mainfrom
feat/sync-all-state-tables

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Why

A code location's metadata sync kept a suspended Snowflake warehouse running and could loop forever on slow statistics reads. It also mirrored only 7 of the 10 state tables SQLBuild writes. This combines three fixes so they share one CI run. Each was reviewed and passed checks on its own.

Changes

  • Statistics paging: statistics pages have their own statistics_limit, which halves after a failed read and survives the rewind through catalog. A page too large to deliver halves the current kind's limit.
  • Snowflake without a running warehouse: the catalog page uses the adapter's schema-scoped listings (SHOW TABLES, SHOW VIEWS, SHOW COLUMNS IN SCHEMA). schema_exists uses SHOW SCHEMAS LIKE … IN DATABASE with an exact, case-insensitive match. Other adapters are unchanged.
  • All state tables: new sync kinds column_migrations, node_results and consumption. A test fails if a name in STATE_TABLE_NAMES has no kind. Rows without an event ID get one derived from their identity columns.
  • Fix: state tables without event_id can now be paged on Snowflake and SQL Server.
  • warehouse_metadata/main is split into ingest, location-read and person-read modules.
  • New control-store tables: as with every pre-release schema change, existing control stores must be recreated.

DuckShop: new state-table fixtures. The paging and adapter-listing changes are not project shapes.

Verification

  • Combined branch: 52 warehouse metadata, catalog and statistics integration tests pass, and make check-ci passes.
  • Before combining: 127 orchestration tests on SQLite and PostgreSQL, the CLI location_metadata tests, and the Snowflake unit tests.
  • Live Snowflake X-Small check with all three changes: three full sync cycles of all 12 kinds ran with the warehouse suspended throughout. The first statistics sync completed at a page size of 25, after timeouts at 100 and 50.

…cs read

A statistics read that timed out halved the shared page limit and rewound to
catalog. Finishing catalog reset that limit to the maximum, so statistics
retried at full size, timed out again and looped, keeping the warehouse busy.
Statistics now has its own page limit: it survives the rewind and returns to
the maximum once a statistics scan completes.
…warehouse

A code location's catalog sync listed relations and columns through
information_schema, and every Snowflake connection checked its session
schema through information_schema.schemata. Both need a running warehouse,
so each sync cycle resumed it and kept it from suspending.

The catalog page now uses the schema-scoped SHOW listings the build already
uses when the adapter provides them, and schema_exists asks SHOW SCHEMAS,
falling back to the information schema for names SHOW LIKE cannot express.
…n state

The location sync now reads every state table SQLBuild writes. Column
migrations, node results and consumption join the other kinds, ahead of
catalog and statistics. Node result and consumption rows have no event
ID, so the server derives one from their identity columns, and retried
identical rows collapse to one.

Each kind names its source state table, and a test fails when a state
table has no kind. The janitor's built-in exclusions now use the same
list. The warehouse_metadata main modules are grouped into ingest,
location-read and person-read buckets.
…Server

A table without an event_id column pages with a NULL placeholder key.
The history SQL wrapped that key in the adapter's binary conversion, and
Snowflake rejects TO_BINARY(NULL, 'UTF-8'). The placeholder now stays a
bare NULL and is left out of ORDER BY, where SQL Server rejects
constants.
@kvlonge kvlonge added the full-verify Run the full Verify matrix on this pull request label Nov 11, 2026
@kvlonge
kvlonge enabled auto-merge (squash) November 11, 2026 15:21
@kvlonge kvlonge changed the title feat(location): sync every SQLBuild state table to the control server feat(location): sync every state table without waking a suspended warehouse Nov 11, 2026
@kvlonge
kvlonge added this pull request to the merge queue Nov 11, 2026
@kvlonge
kvlonge removed this pull request from the merge queue due to a manual request Nov 11, 2026
@kvlonge
kvlonge added this pull request to the merge queue Nov 11, 2026
Merged via the queue into main with commit 55dd0de Nov 11, 2026
56 checks passed
@kvlonge
kvlonge deleted the feat/sync-all-state-tables branch November 11, 2026 23:01

kvlonge commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

Correction to the description above, where "without waking a suspended warehouse" overstates what this PR does.

  • Only the catalog and statistics reads avoid the warehouse. They use SHOW TABLES, SHOW VIEWS, SHOW COLUMNS IN SCHEMA, SHOW SCHEMAS and SHOW OBJECTS, which run in cloud services.
  • State-table reads can resume it. All ten state-table sync kinds work the same way. The sync connects with the target's warehouse (USE WAREHOUSE) and checks the table with SHOW. It then runs SELECT … FROM <state table> WHERE <keyset cursor> [AND <timestamp> >= <watermark>] ORDER BY … LIMIT n. With auto-resume on, any such SELECT that Snowflake's result cache can't answer resumes the warehouse. A new watermark or cursor changes the query text, and so does new state. Nothing checks whether a table changed before its SELECT runs.
  • What the live X-Small check proved: with an unchanged store and repeated query text, three sync cycles left the warehouse suspended, because the state-table SELECTs came from the result cache.
  • What it didn't prove: syncing new state without a resume. The same session resumed the warehouse twice on the first, uncached consumption reads. Only two state tables held rows, and nothing wrote new state during the quiet window. The check sampled SHOW WAREHOUSES about a minute apart and read no warehouse event or metering history.

A follow-up will skip each state-table SELECT when the table's last-altered time hasn't moved since the last sync. It will verify both cases, no new state and new state, with warehouse event and metering history.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

full-verify Run the full Verify matrix on this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant