Skip to content

fix(clickhouse): write number literals that read back exactly - #40

Merged
Makisuo merged 2 commits into
test/fuzz-query-builderfrom
fix/ch-exact-number-literals
Oct 23, 2026
Merged

Makisuo merged 2 commits into
test/fuzz-query-builderfrom
fix/ch-exact-number-literals

Conversation

@Makisuo

@Makisuo Makisuo commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

ClickHouse number literals now read back as exactly the value given.

  • A subnormal float (5e-324) was a SYNTAX_ERROR; text parsing (toFloat64('5e-324')) flushes it to 0. It is written from its bits: reinterpretAsFloat64(toUInt64(1)).
  • A whole double past 2^53 printed as its shortest decimal (44812297868494010) is parsed by ClickHouse as an exact integer the double is not (…008), so WHERE x = value missed the row. It is written as the double's own integer value.

Applies to column literals, lit, and untyped number operands. While here: the fuzzer's earlier "decimal float literals are 1 ULP off" lead was wrong — a bit-exact check shows String(value) round-trips; ClickHouse's text float parser (JSON input, toFloat64('…')) is the imprecise one, so the Float64 reference row is built from bits.

Verification: unit tests in literal.test.ts; Float64/Int64/UInt64 literal fuzz in strict mode at 50× against ClickHouse 25.8 (2000 values per path); full suite.


Stack (merge bottom-up):

  1. test(fuzz): property-based fuzzer for the query builder #39 test(fuzz): property-based fuzzer for the query builder
  2. fix(clickhouse): write number literals that read back exactly #40 fix(clickhouse): write number literals that read back exactly
  3. fix: parenthesise an arithmetic expression passed as an argument #41 fix: parenthesise an arithmetic expression passed as an argument
  4. fix: fail with QueryBuilderError instead of throwing on unusable values #42 fix: fail with QueryBuilderError instead of throwing on unusable values
  5. fix: bare select() over a subquery or union selects every alias #43 fix: bare select() over a subquery or union selects every alias
  6. fix(clickhouse): cast array and map comparison literals to the column type #44 fix(clickhouse): cast array and map comparison literals to the column type
  7. fix(postgres): type the two placeholders Postgres would mistype #45 fix(postgres): type the two placeholders Postgres would mistype

🤖 Generated with Claude Code

Two spellings did not round-trip through ClickHouse's SQL parser:

- a subnormal float (`5e-324`) is a SYNTAX_ERROR, and parsed from text
  (`toFloat64('5e-324')`) it flushes to 0; it is now written from its
  IEEE bits as `reinterpretAsFloat64(toUInt64(<bits>))`.
- a whole double past 2^53 printed as its shortest decimal
  (`44812297868494010`) is parsed as an exact integer the double is not
  (…008), so `WHERE x = value` missed the row; it is now written as the
  double's own integer value.

Both apply to column literals, `lit`, and untyped number operands. Found by
the literal fuzzer; its known-issue entry is removed.

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

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 4 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 07861c4a-e5e8-4e9f-8b4a-bcac3e5b31d0
📥 Commits

Reviewing files that changed from the base of the PR and between 2098470 and a433599.

📒 Files selected for processing: 6
  • .changeset/exact-number-literals.md
  • src/ch/expr.ts
  • src/ch/literal.test.ts
  • src/ch/literal.ts
  • tests/fuzz/known-issues.ts
  • tests/fuzz/regressions.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Makisuo
Makisuo added this pull request to stack #46 October 23, 2026 00:18
@Makisuo Makisuo changed the title fix(clickhouse): write number literals that read back exactly test(fuzz): property-based fuzzer for the query builder Oct 23, 2026
@Makisuo Makisuo changed the title test(fuzz): property-based fuzzer for the query builder fix(clickhouse): write number literals that read back exactly Oct 23, 2026
@Makisuo
Makisuo merged commit 1aee63f into main Oct 23, 2026
3 checks passed
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