Skip to content

Preserve integer precision in ClickHouse query parameters#283

Open
damilolaedwards wants to merge 1 commit into
ethpandaops:masterfrom
damilolaedwards:fix/clickhouse-numeric-param-formatting
Open

Preserve integer precision in ClickHouse query parameters#283
damilolaedwards wants to merge 1 commit into
ethpandaops:masterfrom
damilolaedwards:fix/clickhouse-numeric-param-formatting

Conversation

@damilolaedwards

Copy link
Copy Markdown

Problem

Operation request bodies are decoded with a plain json.Decoder, so every JSON number in a query's parameters map becomes a float64. The ClickHouse parameter formatters (formatClickHouseParamValue, formatClickHouseArrayLiteral) have no numeric case and fall through to fmt.Sprint, which renders a float64 with %g.

The result:

  • Any integer of 1e6 or more is emitted in scientific notation, for example 7500000 becomes 7.5e+06. ClickHouse cannot parse that as a UInt64/Int64, so the query fails.
  • Integers above 2^53 lose precision before they are ever formatted.

This breaks parameterized queries filtering by block number, slot, timestamp, or gas, which are the normal ranges on any real network. Array parameters have the same gap.

Fix

Decode numbers as json.Number (UseNumber) so values keep their exact form, teach optionalIntArg to read json.Number (parseInt64Arg already did), and format json.Number verbatim in both ClickHouse formatters, with a plain-decimal fallback for float64.

Tests

Added tests covering large integers (block/slot/timestamp), array parameters, precision above 2^53, and non-integer values rendering without an exponent. The new tests fail on the old code and pass on the new code, and the full pkg/server suite passes (the UseNumber change does not affect other operations).

Operation request bodies were decoded without UseNumber, so JSON numbers
became float64. The ClickHouse parameter formatters then fell through to
fmt.Sprint, which renders float64 with %g: any integer of 1e6 or more
came out in scientific notation (7.5e+06), which ClickHouse cannot parse
as an integer type, and integers above 2^53 lost precision before they
were ever formatted. This broke parameterized queries filtering by block,
slot, timestamp, or gas.

Decode numbers as json.Number so values keep their exact form, teach
optionalIntArg to read json.Number, and format json.Number verbatim
(with a plain-decimal fallback for float64). Add tests covering large
integers, arrays, precision above 2^53, and non-integer values.
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