Skip to content

Packed MergeTree format support - #289

Draft
fuziontech wants to merge 7 commits into
mainfrom
feat/packed-mergetree
Draft

fuziontech wants to merge 7 commits into
mainfrom
feat/packed-mergetree

Conversation

@fuziontech

Copy link
Copy Markdown
Member

Summary

Adds first-scope native ClickHouse packed MergeTree support to Hoglake:

  • New file format clickhouse-mergetree-packed (one immutable data.packed object per hog_data_file)
  • Server contract/migration (V25), OpenAPI, upload/commit validation, fixed-schema enforcement, and maintenance (compaction/hydration) exclusions
  • Default-disabled rollout gate HOGLAKE_PACKED_MERGETREE_ENABLED
  • Python adapter (pyhoglake.packed) producing parts via clickhouse local, uploading through fenced claims, and reading exact snapshot part lists into an isolated local table via ATTACH PART + table_readonly
  • Explicit unsupported-format rejection in DuckDB client and Hedgerow

Scope constraints

Append-only, homogeneous, fixed schema. No partition specification, sort order, DVs, explicit row IDs, packed compaction, mixed-format scans, Trino/Iceberg packed reads, or remote-read guarantees.

Testing

  • Server: 2207 passed, 0 failed, 2 skipped; ktlint + OpenAPI checks pass
  • Pyhoglake: 844 passed, 1 skipped (non-integration); ruff/format/mypy/wheel/sdist pass
  • Mandatory CI job runs the real adapter round-trip against pinned clickhouse/clickhouse-server:26.9.8.3 (skips fail the job)
  • DuckDB release build + packed test pass; Hedgerow 225 passed

Rollout

Deploy V25 + new binary fleet-wide with the gate disabled, then enable HOGLAKE_PACKED_MERGETREE_ENABLED=true on all creation-serving replicas before creating packed tables. See server/README.md.

fuziontech and others added 3 commits October 3, 2026 00:21
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
@fuziontech
fuziontech requested a review from a team October 4, 2026 04:50

@bill-ph bill-ph left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked the V25 migration (format column, FK, triggers that block changes to packed tables during rolling deploys), the commit, upload-claim, alter, truncate and table-creation validation, the compaction/hydrator exclusions, and the pyhoglake.packed adapter: subprocess use, path-escape checks, download size limits, ATTACH flow. The server-side design holds together. The DB triggers fence old replicas, registerInitialFiles sends create-with-files through the same packed validation, and the drop/retire paths stay legal because markDropped sets dropped_snapshot before it ends the columns.

P1

  • V25 full-scans hog_data_file under ACCESS EXCLUSIVE (V25__packed_mergetree_format.sql:34). VALIDATE CONSTRAINT runs in the same transaction as the preceding DROP/ADD CONSTRAINT, so the exclusive lock is held for the whole scan of the largest table, blocking all commits and reads. The scan is redundant because the old CHECK only allowed 'parquet'. Leave the new CHECK NOT VALID, as the FK already is.

P2

  • Packed read order across 10+ parts (pyhoglake/src/pyhoglake/packed.py:503). ORDER BY _part sorts part names as strings (all_10_10_0 < all_2_2_0), so rows don't come back in scan-plan order. Order by the numeric block number instead.

Inline comments

  • server/src/main/resources/db/migration/V25__packed_mergetree_format.sql:34 — P1: This VALIDATE runs in the same Flyway transaction as the DROP CONSTRAINT/ADD CONSTRAINT on lines 29-33, and those already hold ACCESS EXCLUSIVE on hog_data_file until commit. So the lower SHARE UPDATE EXCLUSIVE lock that VALIDATE normally takes gives nothing here. It does a full scan of the largest table in the schema while blocking every commit, scan plan and maintenance query in every catalog. lock_timeout only limits lock acquisition, not the scan. The scan is also unnecessary: V1's inline CHECK only allowed 'parquet', so existing rows already satisfy the new constraint, and a NOT VALID CHECK is still enforced on new writes. That is the same reasoning the file already uses for leaving the FK NOT VALID. Fix: drop this line, or move the validate into a separate migration that runs on its own. The hog_table validate on line 14 has the same shape but the table is small.
  • pyhoglake/src/pyhoglake/packed.py:503 — P2: _part is a string, so with 10+ parts all_10_10_0 sorts before all_2_2_0. Rows then come back out of scan-plan (append) order. Row counts still match, but callers that expect append order get rows from later parts interleaved. Order by the numeric block instead, e.g. ORDER BY toUInt64(splitByChar('_', _part)[2]), _part_offset, and extend the multi-part live test past 9 parts.

— Robo Bill v2 (opus, high reasoning)

@jghoman

jghoman commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

@fuziontech is this an experiment or something you're wanting to ship?

@jghoman

jghoman commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the thorough write-up; the server-side contract and the adapter read cleanly. One structural request before this goes in, and it's about the enforcement mechanism rather than the feature.

Could we rework the trigger-based fencing into service-layer checks? V25 adds four row-level PL/pgSQL triggers (hog_table_version_format_guard, and the hog_packed_*_guard set on hog_column, hog_partition_spec, hog_sort_spec), each doing a hog_table lookup per row, plus a second FK from hog_data_file to hog_table on (catalog_id, table_id, file_format). My concerns, in order:

  1. The guards are a trap for future migrations. hog_packed_column_guard rejects any insert/update/delete on hog_column for a packed table. The stats-layout work (Stats layout redesign: one packed row per file, metrics modes, truncated bounds, inline partition tuple and key slots #271) and anything else that backfills or rewrites column rows will hit check_violation the moment one packed table exists, in a migration, under a lock, on a deploy night. Triggers are also invisible to the Kotlin code, the plan tests and the mutation rule in AGENT.md, so that failure mode has nothing pinning it.
  2. They defend against a sequence the rollout already forbids. The stated purpose is fencing old replicas during a rolling deploy, but creation is gated on HOGLAKE_PACKED_MERGETREE_ENABLED, which the rollout says to enable only once every replica runs the new binary. With that order, no old replica ever sees a packed table. The service layer already enforces the rest: TableMetadata.validateDefinitionForFormat, requireFormatUnchanged, and liveTableFormat on commit.
  3. The FK on hog_data_file adds a second per-row probe on the hottest table in the schema (cheap today, but that table is the one we are trying to slim, not grow), to enforce an invariant the commit path already checks.

Suggested shape: keep hog_table.file_format with its CHECK as the single source of truth, drop the write.format.default mirror property (or derive it at read time), enforce format at creation/alter/commit in code as you already do, and keep the rollout order as the fence. No triggers, no FK on the manifest.

Two smaller things:

  • Robo Bill's P1 stands: the VALIDATE CONSTRAINT on hog_data_file runs under the ACCESS EXCLUSIVE already held by the DROP/ADD CONSTRAINT in the same transaction, so it's a full scan of the largest table while every commit waits. NOT VALID is sufficient since V1 only ever allowed parquet.
  • The per-group format re-query in CompactionService at commit time guards a state that cannot occur once the table-level check runs; it's a round trip per group on the commit path and can go.
  • V25 is also claimed by an open branch (the reindex task). Whichever lands second renumbers; the new migration-chain protection on main will flag it.

Happy to pair on the migration if useful.

@jghoman

jghoman commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

Full review, following up on the trigger comment above. I ran the touched server classes (119 tests incl. V25, MigrationLockWindow, SchemaEquivalence, MapperCoverage), the pyhoglake suite (844 passed, 1 skipped) and the real-ClickHouse test against the pinned 26.9.8.3 image, plus 13 mutations against the branch. Numbers below are measured on PG 18 with the PR schema unless stated.

Blocker

1. V25 scans the whole manifest under ACCESS EXCLUSIVE. V25__packed_mergetree_format.sql:29-34: DROP CONSTRAINT / ADD … NOT VALID take ACCESS EXCLUSIVE on hog_data_file, line 6 already holds it on hog_table, and both are held to commit, so VALIDATE CONSTRAINT is a full seq scan of a 5.5 GB heap (prod-us today; 9M rows during a drain) with every reader and writer blocked: scans, planning, changefeed, sampler, commits. Migrations run on the pool connection that carries statement_timeout = 60s (Database.kt:34/82), so at prod size this most likely times out, rolls back and crash-loops, with each attempt a fleet-wide stall. Even a successful run is a 30–60 s outage. lock_timeout only bounds acquisition, not the scan. The validate is redundant: V1's CHECK only ever allowed 'parquet', and new rows are constrained by the FK and the hog_table CHECK. Drop the column CHECK (metadata-only) or leave it NOT VALID forever, as the FK already is.

Should fix

2. ORDER BY _part sorts part names as strings (packed.py:503). Confirmed on 26.9.8.3 with the adapter's exact flow (12 detached all_i_i_0 parts, attached in plan order, table_readonly=1): rows come back 10, 11, 12, 1, …, 9. ORDER BY _part_data_version, _part_offset returns 1..12. CI and the live test use two parts, so nothing catches it; add a 10+ part case. Note the full sort also runs under the 2 GiB max_memory_usage.

3. Per-row cost on the hot hog_data_file path. 50k-row inserts, 4 interleaved reps: 7.6 µs/row before the PR, 9.0 with the new FK, 9.8 with the claim trigger (V25:173-196), i.e. about +29% per file-row insert inside the commit lock (~0.6 ms per 270-file commit); the end_snapshot guard (V25:164) adds ~3.5 µs per UPDATE, ~7 ms for a 2,048-input compaction commit. The FK already forces file format = table format; the claim trigger only catches "claimed as one format, registered as the other into a table of the registered format", and ties DB logic to the /trino-upload/ path convention (UploadService.kt:91). Drop it, or at least WHEN (strpos(NEW.path, '/trino-upload/') > 0) so parquet rows never enter plpgsql. See the trigger comment above for the hog_column / spec guards.

4. Trino has no packed refusal (trino repo, not this PR, but it gates the feature). plugin/trino-hoglake ignores a data file's file_format; HoglakeSplit carries only the DV format. extra_properties can carry write.format.default, so once the gate is on Trino can create a packed table, and a SELECT hands data.packed to the parquet reader and fails opaquely. "Trino packed reads out of scope" needs a typed refusal before the gate flips.

5. Two sources of truth for the format. Commit path and FK read hog_table.file_format (CommitService.kt:1460, 1575); AlterService:92-110, truncate (CatalogService.kt:534), the compaction ctx (:1344) and every client read properties['write.format.default']. Only the version trigger keeps them aligned. AGENT.md's invariants still assume parquet everywhere ("server never opens the parquet", invariant 2 refusals); the format contract needs to be written there.

6. Maintenance surfaces have no format filter. MaintenanceSummarySampler.kt:277 (tiers and debt), the small-file and debt gauges, and the debt page all count packed files. Packed tables are never compacted, so they show as permanent small-file debt. The planner itself is safe (early return at CompactionService.kt:1511, SQL filter at :1937). Hydrator, expiry, retirement and cleanup are format-agnostic and fine.

7. Packed requires column_stats (CommitService.kt:1605) and pyhoglake ships min/max bounds for every column. That runs against the decided direction for stats (no per-column bounds, hog_file_column_stats goes away). Counts only would be enough.

8. pyhoglake resource defaults (packed.py:81-85, 570-612): a read can stage up to 64 GiB on local temp disk, buffer up to 8 GiB of stdout via capture_output and copy it again into Arrow, and run up to 10,000 ATTACHes in one subprocess under a 120 s timeout. Lower the defaults, stream stdout, or read part by part. Checked and fine: argv-list subprocess use with regex-limited, backtick-quoted identifiers; part dirs index-named and resolved under the temp root; downloads capped at registered size plus a 1-byte overrun probe; temp cleanup; a crash between upload and commit leaves a 24 h claim that cleanup reclaims; Date32 / DateTime64(9) out-of-range round trips are exact.

9. Test gaps from the mutation runs. Pinned (red): file vs table format, the gate, DV refusal, claim format, truncate, fixed-schema alter, the claim trigger, the hydrator filter, the packed footer. Unpinned (suite stays green): removing the hog_sort_spec guard; removing requireFormatUnchanged (the DB trigger masks it and the error turns from a 422 into a check_violation); removing either compaction exclusion (each covers the other). Untested trigger arms: hog_column INSERT at a non-creation snapshot, hog_column DELETE, hog_partition_spec UPDATE/DELETE, hog_delete_file UPDATE. The V25 test asserts only the exception type, not which constraint fired. The live-server packed test is not in CI.

10. Rollback to a pre-V25 binary with a packed table present: the old planner has no format filter, picks packed files, downloads up to 8 GiB each, fails in the rewriter and is blocked by the end guard on every sweep. Forward rolling-deploy fencing is correct (the FK covers any binary; markDropped updates hog_table before hog_column). Document "no rollback past V25 once a packed table exists".

11. Part bytes are persisted with no writer version recorded. Whether a part can be ATTACHed depends on the reader's ClickHouse version relative to the writer's; 26.9.8.3 is pinned only in CI. Record the writer/part-format version per file or as a table property.

Nits

  1. V25:64-72 and TableMetadata.validateProperties are case-sensitive: a retained 'PARQUET' aborts the migration, and SetProperties with it becomes a new 422 on a live path. Before promoting: SELECT count(*) FROM hog_table_version WHERE properties ? 'write.format.default' in all three environments.
  2. The packed-clickhouse CI job runs on every PR touching openapi, pyhoglake, hedgerow or bench and gates the PyPI publish; each run pulls ~300 MB from Docker Hub for a 7 s test. Mirror the image to GHCR or take the job off the publish path.
  3. packed.py:592 runs clickhouse local with the caller's cwd; pass cwd=root. The V17 migration test now applies V25 out of order because UploadService reads hog_upload.file_format.
  4. Rebase: main is at e933717; the branch is off 658ad3e. V25 is also claimed by the reindex branch; whichever lands second renumbers (the new migration-chain check on main enforces it).

What is irreversible

Once one packed row exists, removing the format (FK, triggers, column, or the parquet-only CHECK) means dropping every packed table and waiting for retirement and expiry to purge its rows, and the S3 objects are in a non-interchange, version-coupled format.

Where I land

The boundary is defensible: one object per file row keeps the "file" abstraction, and the catalog gives packed tables snapshots, append concurrency control, liveness and retention. But every parquet-specific invariant (row ids, footer stats, field-id binding, split offsets, DVs, compaction's row-id carrier) now needs a format branch in every planner, client and engine, and this PR covers DuckDB, Hedgerow, pyhoglake, compaction and the hydrator while missing Trino, the sampler/metrics surfaces and AGENT.md. Before the gate flips I'd want: (1) the migration fixed, (2) the trigger/FK rework from the comment above, (3) a Trino refusal, (4) counts-only stats for packed, (5) the AGENT.md contract. Happy to go through any of it on a call.

…dback

- Rework DB triggers and manifest FK into Kotlin service-layer checks
- Leave hog_data_file format check NOT VALID without ACCESS EXCLUSIVE full scan
- Make hog_table.file_format the single source of truth and derive write.format.default
- Filter packed tables from MaintenanceSummarySampler to prevent small-file debt leaks
- Remove per-group format re-query from CompactionService
- Relax packed stats requirement to counts-only (no per-column bounds required)
- Fix pyhoglake numeric block ordering for 10+ parts with test coverage
- Lower pyhoglake resource defaults and stream Arrow output
- Document format invariants and no-rollback constraint in AGENT.md and README.md

Co-authored-by: Shelley <shelley@exe.dev>
@fuziontech

Copy link
Copy Markdown
Member Author

Thanks @jghoman, this is very helpful and concrete architectural feedback. All items have been addressed to your specs in commit 803d035:

  1. Reworked DB triggers and manifest FK into service-layer checks:

    • Dropped the 4 PL/pgSQL row-level triggers (hog_table_version_format_guard, hog_packed_*_guard), the upload-claim trigger, and their associated functions from V25 and schema.sql.
    • Removed the manifest foreign key hog_data_file_table_format_fk and its supporting unique constraint hog_table_format_identity, eliminating the second per-row probe on hog_data_file.
    • Invariants (fixed-schema refusals, unpartitioned/unsorted restrictions, upload claim format matching, table vs file format alignment) are enforced strictly at the Kotlin service layer in TableCreationService, AlterService, CommitService, and UploadService, gated by HOGLAKE_PACKED_MERGETREE_ENABLED.
  2. No full scan under ACCESS EXCLUSIVE on hog_data_file:

    • Dropped VALIDATE CONSTRAINT on hog_data_file from V25; new rows are validated on insert and historical rows only ever admitted Parquet.
  3. Single source of truth:

    • hog_table.file_format is the sole authoritative format column in PostgreSQL.
    • hog_table_version.properties no longer stores write.format.default; TableInfo.properties derives it at read time for client compatibility.
    • Property validation and matching for write.format.default is now case-insensitive.
  4. Maintenance surfaces exclude packed tables:

    • MaintenanceSummarySampler filters out non-Parquet tables from the sampling scan and pool accumulation, preventing packed tables from leaking permanent small-file debt into debt scores, debt pages, or metrics.
    • Removed the redundant per-group format re-query from CompactionService.compactGroup.
  5. Counts-only stats for packed tables:

    • Relaxed CommitService packed file validation so column_stats is optional; pyhoglake passes column_stats: [] without computing per-column min/max bounds.
  6. pyhoglake improvements:

    • Fixed ORDER BY to sort by numeric block (toUInt64(splitByChar('_', _part)[2]), _part_offset) rather than string lexicographical order. Added regression test asserting numeric ordering across 12 attached parts.
    • Lowered default resource limits (max part bytes 2 GiB, max snapshot bytes 8 GiB, max snapshot parts 500, max result bytes 2 GiB).
    • Streamed Arrow results directly via pa.ipc.open_stream(process.stdout) instead of buffering up to 8 GiB in memory.
    • Passed cwd=root to clickhouse local.
  7. Documented invariants & rollback constraints in AGENT.md and server/README.md:

    • Added Invariant 13 covering immutable homogeneous table formats and explicit callout that rolling back past V25 with packed tables present is unsupported.

(Note: we also updated Trino PR PostHog/trino#107 to address Bill's feedback and fix commit message conventions for Trino CI).

fuziontech and others added 3 commits October 6, 2026 16:11
…w gaps

- Merge main (resolves UploadService claim query onto REGISTER_CLAIMS_SQL,
  now selecting file_format); renumber V25__packed_mergetree_format to V26
  since main took V25 for the reindex task.
- Packed registrations are always stats_state='provided': column_stats is
  optional and the hydrator never claims packed files, so 'pending' was
  permanent and inflated the stats-pending gauge.
- TableRepo reads hog_table.file_format directly; drop the per-call
  information_schema probe and the catch-all in the row mapper.
- Packed alter refusal is an allow-list (rename, table comment, properties)
  so new AlterOps fail closed.
- Write responses report write.format.default canonically (absent for
  parquet, lowercase otherwise), matching the next read.
- Tests: sort/partition/rename/drop refusals and format immutability via the
  API, each compaction exclusion pinned separately, sampler excludes packed
  debt, migration test asserts the constraint that fired.
- Docs: AGENT.md invariant 13 no longer claims the server never opens
  Parquet; OpenAPI column_stats text matches counts-only behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pyhoglake packed adapter:
- Read each part into its own Arrow file (INTO OUTFILE, sorted by
  _part_offset within the part) through the bounded _run path. The old
  streamed read never applied its timeout while reading, could deadlock on
  an undrained stderr pipe, leaked the child on a mid-stream failure, and
  sorted the whole snapshot under one memory limit.
- Verify attached parts against the scan plan (block order + per-part row
  counts) instead of assuming ATTACH numbering.
- Squash inserts into one block so appends over ~256 MiB stay one part.
- Coherent defaults: 4 GiB memory, 1 GiB part, 2 GiB snapshot and result.
- Reject column names starting with '_' (they shadow ClickHouse virtual
  columns and silently reorder reads); the server refuses them for packed
  tables too.
- Drop dead min/max stats code; README states counts-only registration,
  the idempotency-key contract and the limits.

CI:
- ci/clickhouse-local.sh is the one digest-pinned ClickHouse wrapper.
  python-live pulls it, enables HOGLAKE_PACKED_MERGETREE_ENABLED on the live
  server and runs the server-backed packed test plus both real-ClickHouse
  tests (now marked integration), where a skip fails the run. This replaces
  the separate packed-clickhouse job, whose test only ran one of the two.
- Dev stack (compose + just server run) opens the packed gate so the
  duckdb-client live suite runs against a default stack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fixture seeds through today's CatalogService at V22, which now reads
hog_table.file_format; same treatment V17's test already gives V26.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fuziontech

Copy link
Copy Markdown
Member Author

@jghoman follow-up after a second pass over your review. Head is 4b04c12, CI green.

CI / chain

  • Merged main and renumbered the migration to V26 (main's reindex task took V25). That was the cause of the red migration-chain / python-live / trino-test runs. (1f4a1d8)

Fixed in this round

  • Web UI improvements: header totals, theme toggle, debt-page tooltips and sorting #7 counts-only stats had a bug: after column_stats became optional, a packed file registered without stats landed as stats_state='pending'. The hydrator never claims packed files, so it stayed pending forever and counted in the stats-pending gauge. Packed rows are now always provided. (1f4a1d8)

  • Adopt -dev version suffixes between releases; enforce spec version lockstep #5 single source of truth: TableRepo had grown a per-call information_schema probe and a catch-all in the row mapper (to tolerate old-schema test fixtures). It now reads t.file_format directly; the fixtures apply V26 out of order instead. Write responses now report write.format.default canonically (absent for parquet, lowercase otherwise), so they match the next read. (1f4a1d8, 4b04c12)

  • Alter rules: packed tables use an allow-list (rename table, table comment, set properties), so a future AlterOp is refused unless it is explicitly allowed. (1f4a1d8)

  • Store decoded column bounds as a per-file jsonb doc #9 mutation gaps, each now pinned by its own test:

    • set_sort_order / set_partition_spec / rename / drop refusals;
    • the requireFormatUnchanged call site (without it, the format change would succeed silently because the format comes from hog_table);
    • each compaction exclusion separately (a packed row in a parquet table pins the SQL predicate; parquet-claiming rows in a packed table pin the early return);
    • the sampler excluding packed debt;
    • the V26 test asserting which constraint fired. (1f4a1d8)
  • Adopt -dev version suffixes between releases; enforce spec version lockstep #5 AGENT.md: invariant 13 claimed the server never opens Parquet. It now states that hydrator and compaction filter to parquet, packed stats are counts-only, and every engine must refuse non-parquet formats. The OpenAPI column_stats text now matches the code. (1f4a1d8)

  • Maintained net-live rollup for instance/catalog totals (hog_catalog_stats) #8 pyhoglake resources: the streamed read from 803d035 had problems.

    • It never applied its timeout while reading.
    • It could deadlock on an undrained stderr pipe.
    • It leaked the child on a mid-stream failure.
    • It still sorted the whole snapshot under one memory limit.

    Reads now go part by part (INTO OUTFILE, ORDER BY _part_offset within the part) through the bounded runner, and check each attached part's row count against its own registration. Other changes:

    • Inserts are squashed into one block, so appends over ~256 MiB stay one part instead of failing as "2 active parts".
    • Defaults are now coherent: 4 GiB memory, 1 GiB part, 2 GiB snapshot/result. At the old 1 GiB, ClickHouse couldn't parse a 400 MB insert.
    • Verified against the pinned 26.9.8.3: a 400 MB append makes one 402 MiB part and reads back in order. (eae212d)
  • Column names starting with _ are refused for packed tables (server + client). A real _part/_part_offset column shadows the virtual column and silently reorders reads. (eae212d)

  • Store decoded column bounds as a per-file jsonb doc #9 / Dev-stack hydrator hydrates nothing: deferred stats stay pending forever #13 CI: the server-backed packed live test was never run in CI (it skipped, and the live server had the gate off). ci/clickhouse-local.sh is now the one digest-pinned wrapper. python-live enables HOGLAKE_PACKED_MERGETREE_ENABLED, and the live server test plus both real-ClickHouse tests run there, where a skip fails the run. The separate packed-clickhouse job is gone (it only ran one of the two real-ClickHouse tests). The dev stack opens the gate so the duckdb-client live suite runs against a default stack. (eae212d)

  • Document /livez + /healthz probe contracts; add a webui health endpoint #4 Trino (Reject unsupported Hoglake file formats trino#107, 66f44de): CREATE OR REPLACE TABLE on a packed table bypassed the refusal. It is now refused, with direct tests of the getTableMetadata / beginInsert / beginMerge guards. CI green there too.

Still open, not addressed here

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants