Skip to content

bug(streaming): SSE /v1/stream emits row DateTime columns zone-less while /v1/query uses RFC3339 Z #372

Description

@EricAndrechek

Area: streaming · query · sdk — bug (timestamp serialization inconsistency) · found via WaveHouse-Stats dogfooding

Expected: a DateTime column serializes identically on every read path — one unambiguous zoned RFC3339 form (…Z) — so a client stitching backfill (/v1/query) + live (/v1/stream) parses both on the same clock, and it matches the SSE frame's own received_timestamp.

Actual: the same event_ts (DateTime64(3,'UTC')) comes back two ways:

  • POST /v1/query"event_ts":"2026-07-06T14:42:36Z" — RFC3339 Z.
  • GET /v1/stream frame → envelope "received_timestamp":"…Z" (zoned) but the wrapped row column "data":{…,"event_ts":"2026-07-06 14:42:36.000"} — ClickHouse-native (space separator, no zone). Same frame, envelope zoned / row column not.

The stream marshals the row data verbatim (internal/stream/hub.go project()json.Marshal({… "data": evt.Data})), so a row DateTime keeps its native form, while /v1/query formats through the CH driver to RFC3339. The SDK SSETransport (clients/ts/src/stream/sse.js) passes data through untouched, and JS Date.parse reads a zone-less string as local time.

Impact: any SDK liveQuery consumer (backfill .fetch() + SSE live in one list) lands the two paths on different clocks — in America/New_York a live row's event_ts resolves +4h vs the same instant from /v1/query, sign-flipping by the viewer's UTC offset. Broke both ordering and the "N min ago" label in the Stats live feed (a 2-min-old event rendered "just now"). Every consumer must normalize today. Envelope-keyed logic (e.g. ingest latency off received_timestamp) is unaffected — the bug is row DateTime columns inside data.

Scope: render row DateTime/DateTime64 columns in the SSE data payload with the same formatter /v1/query uses (RFC3339 Z) rather than the driver-default YYYY-MM-DD HH:MM:SS.fff.

Related: #294 (SSE delivery path), #319 (stream-vs-query policy drift — same query/stream-parity theme), WaveHouse-Stats#55 (client-side workaround shipped there)


From WaveHouse-Stats WAVEHOUSE-FEEDBACK.md dogfooding (live curl capture + SDK-path analysis, dev 08c6f19); validated by code-read against ccd7549 (main) on 2026-07-06.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/apiHTTP handlers, routing, middlewarearea/queryStructured query AST, SQL builderarea/sdkTypeScript SDK (clients/ts/)bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions