Skip to content

feat(compat): four more wire-compatible engines, measured rather than assumed (#424) - #442

Merged
cevheri merged 1 commit into
mainfrom
feat/phase0-timescale-yugabyte
Aug 20, 2026
Merged

cevheri merged 1 commit into
mainfrom
feat/phase0-timescale-yugabyte

Conversation

@cevheri

@cevheri cevheri commented Aug 20, 2026

Copy link
Copy Markdown
Member

Phase 0 of #424 (wire-compatible labelling) — no driver code, only verification and honest
publishing. Four engines the epic recorded as unmeasurable have now been probed live.

Why these four were open, and why they are not any more

Engine Recorded reason What happened
TimescaleDB "image pull did not complete" A property of that day's link, not of the engine. Pulled in seconds.
YugabyteDB "image pull exceeded budget twice" Same.
StarRocks "multi-GB allin1 image on a degraded link" Accurate at the time; expired with the link.
TiDB "needs a PD + TiKV cluster, no single-container path" Never true. --store=unistore runs it in one container with no PD and no TiKV.

A deferral records a reason, and the reason ages at a different rate than the decision. Three of
these four had expired.

What was measured

Probed through the real providers via createDatabaseProvider, every introspection surface called
separately, against a plain PostgreSQL 18 and MySQL 8 baseline so every number is a delta.

Engine Via Tier Probed version
TimescaleDB postgres full TimescaleDB 2.29.2 on PostgreSQL 17.11
YugabyteDB postgres full YugabyteDB 2.25.2.0-b0 (advertises PostgreSQL 15.12)
TiDB mysql full 8.0.11-TiDB-v8.5.1
StarRocks mysql partial StarRocks 3.3.22-753696f (version() reports 5.1.0)

The caveats that matter are the ones that mislead rather than fail:

  • TimescaleDB — a hypertable reports 0 rows / 24 KB where the table holds 5000 rows and
    2.4 MB. The statistics describe the empty parent; the data lives in 31 chunks. Same class as the
    Citus caveat already recorded. The explorer also shows 61 objects for 2 user tables.
  • YugabyteDB — 0 rows / 0 bytes until ANALYZE. Measured on a 20000-row table: 0 before,
    20000 rows and 7878 kB after. A full database looks empty.
  • StarRocks — version() returns a fictitious 5.1.0, so the product displays "MySQL 5.1"
    for a StarRocks 3.3.22 server. Overview, health, sessions and monitoring all unavailable.
  • TiDB — storage stats list a phantom InnoDB entry on a server that has no InnoDB.

Gate 5 found what the harness could not

TiDB and StarRocks both reject EXPLAIN FORMAT='json', so the Explain panel fails while the query
itself runs normally. The provider harness never calls explain; only driving the editor in a browser
surfaced it. Both now carry the caveat.

Gate 7, including the one that fails

Grounded plan runs, each against the live container behind gate 4:

  • TiDB — captured 2 tables, drafted on the real orders.country, ran unmodified, answered TR.
  • YugabyteDB — captured 2 tables, drafted on public.orders.
  • StarRocks — captured 2 tables, drafted on orders.
  • TimescaleDB — does not ground. Recorded as B52 rather than glossed.

The composed PostgreSQL grounding capture is one row per COLUMN against maxResultRows: 200 and
refuses rather than truncates. A stock TimescaleDB answers 478 rows from
information_schema.columns, of which 473 belong to the extension
(timescaledb_information 163,
_timescaledb_internal 146, _timescaledb_catalog 139, _timescaledb_config 17,
timescaledb_experimental 8) and 5 to the user. So the agent is unusable there before the user
creates a table.

Verified extension-caused rather than path-caused, with three controls: plain PostgreSQL 18 captured
3 tables, fingerprint ctx_0d63 under the same least-privilege role; YugabyteDB captured its schema
too; and granting the agent role USAGE and SELECT on the three internal schemas changed nothing. The
existing code comment estimates this limit as "roughly 25 tables of eight columns", which frames it
as a big-schema problem — B52 records the measurement that reframes it as a catalog-heavy-extension
problem.

Counts and incidental fixes

Verified count 23 → 27 (14 shipped drivers + 13 probed relatives); the README's relatives line
moves from "Nine more engines" to "Thirteen more engines". Two stale numbers in
WireCompatibilityHint corrected on the way: the dialog offers fourteen drivers rather than
eleven, and the caveat-count rhetoric ("sixteen caveat lines", true of neither the old registry nor
the new one) is now count-free so it stops ageing.

database-compose.yml gains all four under profiles: ["compat"], and every browser check in this
description was run against those compose services rather than hand-started containers.

Gates

format · lint (0 errors) · typecheck · knip · test (all 30 groups) · build — all green.
Coverage 39181/39181 lines (100.00%). The repo's bidirectional agent-documentation guard caught
B52 missing from docs/AGENT.md and it is now cited in both files.

Closes nothing; ticks four boxes in #424.

… assumed (#424)

Phase 0 of #424 recorded TimescaleDB, YugabyteDB, TiDB and StarRocks as unmeasurable.
Three of those four reasons no longer hold, and one was never true: TiDB was recorded
as needing "a PD + TiKV cluster, no single-container path", and `--store=unistore`
runs it in one container with neither. TimescaleDB and YugabyteDB were recorded
against a failed image pull, which is a property of that day's link and not of the
engine. Only StarRocks' reason was accurate, and it expired with the link.

All four were probed live through the real providers, every introspection surface
called separately against a plain PostgreSQL 18 and MySQL 8 baseline, then re-run in
a browser against the compose services added here.

  TimescaleDB 2.29.2 / PG 17.11   via postgres  full
  YugabyteDB 2.25.2.0            via postgres  full
  TiDB v8.5.1                    via mysql     full
  StarRocks 3.3.22               via mysql     partial (11 of 15 surfaces)

Every caveat is measured. The ones worth naming here are the ones that mislead rather
than fail: a TimescaleDB hypertable reports 0 rows and 24 KB for 5000 rows and 2.4 MB,
because the statistics describe the empty parent and the data lives in 31 chunks;
YugabyteDB reports 0 rows and 0 bytes until someone runs ANALYZE; and StarRocks'
version() returns a fictitious 5.1.0, so the product displays "MySQL 5.1" for a
3.3.22 server. Confirmed in the UI, not just the harness: the TimescaleDB explorer
shows 61 objects for 2 user tables, with metrics at 0 beside plain_rows at 100.

Two caveats exist only because gate 5 ran: TiDB and StarRocks both reject
EXPLAIN FORMAT='json', so the Explain panel fails while the query itself runs.

Gate 7 passes on TiDB (grounded on the real orders.country, ran unmodified, answered
TR), YugabyteDB and StarRocks. It does NOT pass on TimescaleDB, and that is recorded
as B52 rather than glossed: the composed PostgreSQL grounding capture is one row per
column against a 200-row budget, and the extension's own catalogs answer 473 of 478
rows before the user creates anything. Verified extension-caused, not path-caused --
plain PostgreSQL 18 and YugabyteDB both captured their schemas under the same
least-privilege role, and granting that role the internal schemas changed nothing.

Verified count 23 -> 27 (14 shipped drivers + 13 probed relatives). Two stale numbers
in WireCompatibilityHint corrected on the way: the dialog offers fourteen drivers, not
eleven, and the caveat-count rhetoric is now count-free so it stops ageing.
@sonarqubecloud

Copy link
Copy Markdown

@cevheri
cevheri merged commit fe28ed7 into main Aug 20, 2026
24 checks passed
@cevheri
cevheri deleted the feat/phase0-timescale-yugabyte branch August 20, 2026 12:35
cevheri added a commit that referenced this pull request Aug 20, 2026
…two thirteens colliding (#424) (#444)

Phase 0's wrap-up asks that the published engine claims agree. They did not, and the
sharpest case was one this repo created for itself: taking the wire-compatible
relatives from nine to thirteen in #442 put a second, disjoint "thirteen" next to the
thirteen shipped drivers, in both README.md and DOCKERHUB.md, with only the word
"more" separating them. Both now say which thirteen they mean, and the README states
the total the two make - thirteen drivers reaching twenty-six named engines.

DOCKERHUB carried the same fault twice over: "Thirteen engines" sat above a table with
fourteen rows, the fourteenth being the embedded LibreDB store, and the relatives table
below it stated no number at all while rendering thirteen engines in ten rows. Both are
now explicit about their denominator and about the merged rows.

Genuinely stale copy, each verified against the code rather than assumed:

- The two chart READMEs still named SEVEN engines while their own sibling Chart.yaml
  named thirteen. That is the string ArtifactHub shows, so it undersold the product to
  exactly the reader who checks. Fixed to Chart.yaml's own enumeration so the two cannot
  drift apart again.
- The operator CSV keywords named seven engines, leaving Couchbase, ClickHouse, Druid,
  Elasticsearch, OpenSearch and Trino invisible to OperatorHub search. Added to
  operator/config and propagated with `make -C operator bundle`; the bundle diff is the
  six keywords and nothing else.
- deploy/rancher/E2E_VALIDATION_TASK.md told a human tester to expect Chart.yaml to name
  seven engines against an app-readme of ten. Chart.yaml names thirteen. The instruction
  now describes the mismatch that actually exists.
- The winget locale contradicted itself inside one file: ShortDescription said thirteen
  engines, the body enumerated seven as though complete.

Deliberately NOT changed: the Rancher catalog prose still says ten engines. That wording
is version-scoped and frozen on purpose - the catalog page describes a released version
and waits for a tag to carry Elasticsearch, OpenSearch and Trino - and its own accuracy
gate says so. A sweep that reads "ten" as staleness would undo a decision.

Two relatives are now named in the marketplace listings, under a rule the owner settled:
a relative is named only where its caveats are cosmetic. So TiDB and FerretDB join
MariaDB and the three Redis forks in the flatpak/flatpark metainfo and the Azure
description, and Citus, TimescaleDB and YugabyteDB stay out despite being full-tier,
because they report row counts that are wrong rather than missing. StarRocks,
CockroachDB, Materialize and RisingWave stay out on their tiers.

Chart version 0.1.40 -> 0.1.41: charts/libredb-studio/README.md is a packaged file and
0.1.40 is already published, so #167 requires the bump. appVersion stays 0.12.0. The
operator's chart copy moves with it, being byte-identical under two guards.

B53 records what this PR deliberately did not fix: ten sites say the composed grounding
path leaves "the other nine engines" to their providers, which is stale, but the
replacement is not the obvious one. Nine was fourteen type-ids ago; the external reading
gives eleven and the original basis gives twelve, the sites never say which they count,
and B49 means one of the twelve cannot be grounded at all. Picking a digit silently
would repeat the fault this PR exists to fix.
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.

1 participant