Skip to content

sdk(ts): codegen types Decimal columns as number, but /v1/query returns quoted strings #453

Description

@jfwoods

The TypeScript codegen maps every ClickHouse Decimal* column to number, but /v1/query returns Decimals as quoted strings. A generated interface therefore types a field as number while it holds "12.34" at runtime — arithmetic on it silently produces string concatenation or NaN, with no type error.

Evidence

  • clients/ts/src/cli/codegen.ts puts "Decimal" in the numeric bucket, emitting number.
  • The server does not convert Decimals on the way out: internal/api/clickhouse_exec.go's transformRow special-cases only uuid.UUID, [16]byte, and time.Time. A Decimal column arrives from clickhouse-go as a shopspring/decimal.Decimal, which marshals to a quoted JSON string (there is no MarshalJSONWithoutQuotes override in the repo).
  • The Go SDK documents the actual behavior: docs/src/content/docs/sdk/go/reference.md maps Decimal*string ("marshaled as a quoted string on the structured-query path").

So the two SDKs' generated types disagree about the same endpoint, and the TypeScript one is wrong.

Options

  1. Fix the codegen — emit string for Decimal* in the TS CLI, matching the Go generator and the wire. Breaking for anyone who has generated types and is (incorrectly) doing arithmetic, but the arithmetic was already broken.
  2. Fix the server — normalize Decimals to unquoted JSON numbers in transformRow. Loses precision above float64 for high-scale Decimals, which is usually the reason a schema uses Decimal in the first place. Not recommended.
  3. Emit a branded type (type Decimal = string) so the generated field is self-documenting and arithmetic is a type error.

Option 1 or 3. This is the same family as #436 (Array(UInt8) base64), which is already tracked against the server side.

Interim

docs/src/content/docs/sdk/reference.md now footnotes the Decimal* row with the real wire shape and links here.

Found during PR #434 review, where the Go SDK's type table made the discrepancy visible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions