Skip to content

Support ClickHouse 24.8 meta-less result streams in Table view (limited support) #627

Description

@BorisTyshkevich

Goal

Support ClickHouse 24.8 in a deliberately limited but data-safe mode when JSONStringsEachRowWithProgress / JSONEachRowWithProgress returns row records without a meta record.

The support contract for 24.8 is:

Query execution and faithful Table result display are supported. Features that require ClickHouse result-type metadata are not guaranteed on 24.8.

The primary invariant is: never discard query values because result metadata is unavailable.

Problem

applyStreamLine() currently learns both column names and ClickHouse types only from a {"meta":[...]} line. A row is converted to an array by mapping through result.columns:

if (json.meta) {
  result.columns = json.meta.map((m) => ({ name: m.name, type: m.type }));
} else if (json.row) {
  result.rows.push(result.columns.map((c) => row[c.name]));
}

On the confirmed 24.8 servers below, no meta line arrives. result.columns therefore remains empty and every successful row becomes [], so the UI silently renders an empty result despite the wire response containing the data.

Confirmed live on pinned images:

  • 24.8.14.39 (OSS)
  • 24.8.14.10547.altinitystable

The exact first ClickHouse 25.x release that emits meta for these formats has not been established. This issue therefore targets the observed protocol behavior rather than guessing a version boundary.

Required behavior

Meta-first streams

Existing behavior must remain unchanged when meta arrives before rows:

  • column names come from meta;
  • ClickHouse types come from meta;
  • rows are stored in metadata column order;
  • existing typed Table/KPI/chart/log behavior remains unchanged.

Meta-less streams

When a row arrives while result.columns is empty:

  1. Establish columns from that row's keys, preserving Object.keys(row) order.
  2. Represent unavailable ClickHouse types with the existing string field using the explicit sentinel type: ''.
  3. Store the row values in that established column order.
  4. Store all subsequent rows using the same established column order.
  5. Do not wait or buffer rows in the hope that meta will arrive later; the reproduced 24.8 stream reaches EOF without metadata.

Conceptually:

if (json.row) {
  const row = json.row as Record<string, unknown>;

  if (result.columns.length === 0) {
    result.columns = Object.keys(row).map((name) => ({ name, type: '' }));
  }

  // existing row-cap behavior remains in force
  result.rows.push(result.columns.map((column) => row[column.name]));
}

The implementation may be structured differently, but the behavior above is required.

Degraded-functionality contract

type: '' means ClickHouse result type is unknown, not String and not an inferred type.

For a meta-less result:

  • Table: supported. Column names and raw query values must be displayed faithfully.
  • Type display / type-aware cell formatting: may fall back to generic/unknown behavior.
  • Automatic chart role/type detection: not part of the 24.8 support guarantee.
  • KPI type eligibility / tuple parsing: not part of the 24.8 support guarantee.
  • Logs auto-detection: not part of the 24.8 support guarantee.
  • Other consumers that require column.type must fail closed or use their existing unknown-type behavior; they must not throw, silently discard row data, or fabricate a ClickHouse type.

No value-based ClickHouse type inference is required or desired in this issue. In particular, numeric-looking strings, dates, UUIDs, decimals, large integers, enums, etc. must not be assigned synthetic ClickHouse types from their JSON representation.

Non-goals

This issue does not require:

  • reconstructing full ClickHouse types from row values;
  • an auxiliary metadata query;
  • restoring KPI/chart/log feature parity on 24.8;
  • identifying the exact first 25.x release containing the upstream metadata change;
  • changing Column.type to optional.

Those can be considered separately if broader old-server support is later required.

Tests

Add regression coverage for the actual failure mode, not only row-before-meta:

  • a stream containing one row and EOF with no meta ever arriving;
  • multiple meta-less rows, preserving the first row's column order and every row's values;
  • precision-sensitive/string values remain byte-for-byte/value-for-value intact through normalization;
  • row-cap behavior still applies on meta-less streams;
  • normal meta -> row behavior remains unchanged;
  • representative type-dependent consumers tolerate type: '' without throwing or inventing typed behavior.

Re-run the existing live compatibility/spike harness against the pinned 24.8 images and verify ordinary Table query results now match expected values.

Documentation / support matrix

Once the regression is verified, document ClickHouse 24.8 as limited support in the support-matrix work (#71), using language equivalent to:

ClickHouse 24.8: Limited support — query execution and Table results are supported. Typed result features such as automatic charts, KPI interpretation, logs detection, and type-aware formatting may be unavailable because these servers do not provide result metadata in the streaming format used by SQL Browser.

Do not describe 24.8 as full-fidelity support.

Acceptance criteria

  • Meta-less row records populate columns from row keys and preserve all row values.
  • Unknown result types are represented explicitly as type: ''; no ClickHouse type is inferred from values.
  • Multiple rows with no meta through EOF render correctly in Table view.
  • Existing meta-first behavior and typed functionality on newer ClickHouse versions are unchanged.
  • Type-dependent consumers do not crash or silently discard data when type === ''.
  • Existing row-cap/progress/exception behavior is unchanged.
  • Live regression verification passes on 24.8.14.39 and 24.8.14.10547.altinitystable for ordinary Table queries.
  • Document the supported-browser matrix (browsers, ClickHouse versions, IdP requirements) #71/support documentation records 24.8 as limited, not full, support with the scope above.
  • ADR-0005 / ADR-0005: adopt @clickhouse/client-web behind the SQL Browser transport adapter #585 evidence cross-references this issue as the production compatibility fix, independent of the rejected @clickhouse/client-web adoption decision.

Background

This was discovered during the #585 / ADR-0005 @clickhouse/client-web validation spike. The current production transport and the official-client candidate reproduced the same incorrect empty-row behavior on 24.8, so this is a production compatibility defect rather than a client-library migration defect.

ClickHouse added metadata to the progress-bearing JSON row formats after the tested 24.8 line. Newer tested servers (26.3 / 26.6) provide metadata and do not require this fallback.

Relates to

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions