fix: bind scalar Date/Date32 query parameters as date strings - #968
Open
knQzx wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes scalar {name:Date} / {name:Date32} parameter binding by formatting JS Date values as UTC YYYY-MM-DD strings when the declared server-side type is Date/Date32, while preserving the existing Unix-timestamp behavior for DateTime/DateTime64.
Changes:
- Added query placeholder type extraction (
extractQueryParamType) and threaded the inferred type into query-param formatting. - Updated URL and multipart query-param serialization to pass
columnTypeintoformatQueryParams. - Added/updated unit + integration tests and changelog entries for Node and Web clients.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/client-web/src/connection/web_connection.ts | Passes query text into param serialization and forwards param_types_query so scalar Date formatting can be type-directed. |
| packages/client-node/src/connection/node_base_connection.ts | Same as web: passes query text for URL params and type-directed formatting for multipart params. |
| packages/client-common/src/utils/url.ts | Adds param_types_query to allow type extraction without necessarily putting query in the URL. |
| packages/client-common/src/utils/multipart.ts | Enhances URL param serialization to infer {name:Type} and format Date scalars accordingly. |
| packages/client-common/src/index.ts | Re-exports extractQueryParamType. |
| packages/client-common/src/data_formatter/index.ts | Re-exports extractQueryParamType from the formatter module. |
| packages/client-common/src/data_formatter/format_query_params.ts | Adds extractQueryParamType and columnType support; formats scalar Date as YYYY-MM-DD for Date/Date32. |
| packages/client-common/tests/unit/format_query_params.test.ts | Adds scalar Date/Date32 coverage and preserves DateTime behavior assertions. |
| packages/client-common/tests/integration/select_query_binding.test.ts | Adds integration coverage for scalar {d:Date} / {d32:Date32} binding. |
| packages/client-web/CHANGELOG.md | Documents the bug fix for web client. |
| packages/client-node/CHANGELOG.md | Documents the bug fix for node client. |
| - Fixed scalar `Date` / `Date32` query-parameter binding. A JS `Date` bound to a scalar `{name:Date}` / `{name:Date32}` parameter was serialized as a bare Unix timestamp, which the server rejects with `BAD_QUERY_PARAMETER` (only `DateTime` / `DateTime64` accept a numeric timestamp). The bound parameter's type is now read from the query, so a `Date` value is formatted as a UTC date string for `Date` / `Date32` while `DateTime` / `DateTime64` keep the Unix timestamp and preserve the time of day. ([#955]) | ||
|
|
||
| [#947]: https://github.com/ClickHouse/clickhouse-js/pull/947 | ||
| [#955]: https://github.com/ClickHouse/clickhouse-js/issues/955 |
| - Fixed scalar `Date` / `Date32` query-parameter binding. A JS `Date` bound to a scalar `{name:Date}` / `{name:Date32}` parameter was serialized as a bare Unix timestamp, which the server rejects with `BAD_QUERY_PARAMETER` (only `DateTime` / `DateTime64` accept a numeric timestamp). The bound parameter's type is now read from the query, so a `Date` value is formatted as a UTC date string for `Date` / `Date32` while `DateTime` / `DateTime64` keep the Unix timestamp and preserve the time of day. ([#955]) | ||
|
|
||
| [#947]: https://github.com/ClickHouse/clickhouse-js/pull/947 | ||
| [#955]: https://github.com/ClickHouse/clickhouse-js/issues/955 |
Comment on lines
87
to
93
| const searchParams = toSearchParams({ | ||
| database: this.params.database, | ||
| clickhouse_settings, | ||
| query_params: useMultipart ? undefined : params.query_params, | ||
| param_entries: urlParamEntries, | ||
| param_types_query: params.query, | ||
| session_id: params.session_id, |
Comment on lines
216
to
222
| const searchParams = toSearchParams({ | ||
| database: this.params.database, | ||
| // When using multipart, query_params are sent in the multipart body | ||
| query_params: useMultipart ? undefined : params.query_params, | ||
| param_entries: urlParamEntries, | ||
| param_types_query: params.query, | ||
| session_id: params.session_id, |
Comment on lines
114
to
125
| it("formats a date with millis", () => { | ||
| expect( | ||
| formatQueryParams({ | ||
| value: new Date(Date.UTC(2022, 6, 29, 7, 52, 14, 123)), | ||
| }), | ||
| ).toBe("1659081134.123"); | ||
| expect( | ||
| formatQueryParams({ | ||
| value: new Date(Date.UTC(2022, 6, 29, 7, 52, 14, 42)), | ||
| }), | ||
| ).toBe("1659081134.042"); | ||
| expect( | ||
| formatQueryParams({ | ||
| value: new Date(Date.UTC(2022, 6, 29, 7, 52, 14, 5)), | ||
| }), | ||
| ).toBe("1659081134.005"); | ||
| }); |
knQzx
force-pushed
the
fix/scalar-date-param
branch
from
July 28, 2026 11:59
66c46be to
f47d35e
Compare
Author
|
pushed a follow-up addressing the review:
|
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
packages/client-common/src/data_formatter/format_query_params.ts:121
padStart(10, '0')on the Unix-seconds string corrupts negative timestamps (pre-1970 dates). For example,-1becomes"00000000-1", which is not a valid integer and will be rejected by ClickHouse forDateTime/DateTime64params. Handle the sign explicitly (or avoid padding) so pre-epochDatevalues bound toDateTime*work correctly.
const unixTimestamp = Math.floor(value.getTime() / 1000)
.toString()
.padStart(10, "0");
const milliseconds = value.getUTCMilliseconds();
return milliseconds === 0
? unixTimestamp
: `${unixTimestamp}.${milliseconds.toString().padStart(3, "0")}`;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A JS
Datebound to a scalar{name:Date}/{name:Date32}query parameter was serialized as a bare Unix timestamp, which the server rejects withBAD_QUERY_PARAMETER- onlyDateTime/DateTime64accept a numeric timestamp. the bound parameter's type is now read from the query text, so aDateis formatted as a UTCYYYY-MM-DDstring forDate/Date32, whileDateTime/DateTime64keep the Unix timestamp and preserve the time of dayfixes #955
reproduce:
on main this fails with
Code: 457. BAD_QUERY_PARAMETERbecause the client sendsparam_d=1683244800; with this change it sendsparam_d=2023-05-05and the query succeeds. covered by a new unit case informat_query_params.test.tsand an integration case inselect_query_binding.test.ts; the existing scalarDateTime/DateTime64cases still pass unchangedChecklist
CHANGELOG.md(client-node and client-web)