Skip to content

Accept fractional unix timestamp for DateTime64 in containers and JSON - #109978

Open
groeneai wants to merge 19 commits into
ClickHouse:masterfrom
groeneai:groeneai-fix-array-datetime64-fractional-csv
Open

Accept fractional unix timestamp for DateTime64 in containers and JSON#109978
groeneai wants to merge 19 commits into
ClickHouse:masterfrom
groeneai:groeneai-fix-array-datetime64-fractional-csv

Conversation

@groeneai

@groeneai groeneai commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Closes: #109884

Changelog category (leave one):

  • Bug Fix (user-visible misbehavior in an official stable release)

Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):

Fixed parsing of DateTime64 values written as an unquoted fractional unix timestamp (e.g. 1783585473.954) when they appear as elements of Array, Tuple, Map, or in JSON. Previously only scalar DateTime64 columns accepted this form; inside containers the value failed with CANNOT_READ_ARRAY_FROM_TEXT. A bare integer is still interpreted as a scaled tick count, unchanged.

Description

Closes #109884.

Parsing CSV/TSV/JSON/Values into a container of DateTime64(N) (e.g. Array(DateTime64(3))) rejected an element written as an unquoted fractional unix timestamp such as 1783585473.954, failing with Cannot read array from text, expected comma or end of array, found '.' (CANNOT_READ_ARRAY_FROM_TEXT). The same instant written as integer ticks (1783585473954) worked, and a scalar DateTime64 column accepted both forms.

Root cause: container/JSON elements go through SerializationDateTime64::deserializeTextQuoted / deserializeTextJSON, whose unquoted branch used readIntText, which stops at the .. The leftover . then broke the array reader. Scalar CSV/Escaped columns use readText (readDateTime64Text), which already handles the fractional form.

Fix: the unquoted numeric branch now reads the integer and, if a . follows, treats the integer part as whole seconds and the fraction as subseconds (mirroring the scalar readDateTimeTextImpl logic, including negative-timestamp handling and scale truncation/padding). A bare integer with no . keeps its existing raw-tick interpretation, so behavior is unchanged for every previously-accepted input (no backward-incompatible change).

Container (Array/Tuple/Map) and JSON DateTime64 elements went through
deserializeTextQuoted/deserializeTextJSON, whose unquoted branch used
readIntText and stopped at the decimal point, so an element written as
an unquoted fractional unix timestamp (e.g. 1783585473.954) failed with
CANNOT_READ_ARRAY_FROM_TEXT while a scalar DateTime64 column accepted it.

Read the fractional part when a decimal point follows the integer,
mirroring the scalar readDateTimeTextImpl logic. A bare integer stays a
scaled tick count, so previously-accepted inputs are unchanged.

Closes ClickHouse#109884

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@groeneai

Copy link
Copy Markdown
Contributor Author
Pre-PR validation gate (click to expand)
# Question Answer
a Deterministic repro? Yes. printf '"[1783585473.954,1783585473.954]"\n' | clickhouse-local --input-format CSV --structure "x Array(DateTime64(3))" -q "SELECT * FROM table" fails on master with CANNOT_READ_ARRAY_FROM_TEXT every time.
b Root cause explained? Container/JSON DateTime64 elements deserialize via SerializationDateTime64::deserializeTextQuoted/deserializeTextJSON; the unquoted branch used readIntText, which stops at the .. The leftover . then makes SerializationArray::deserializeTextImpl throw "expected comma or end of array". Scalar CSV/Escaped use readTextreadDateTime64Text, which already parses the fractional form.
c Fix matches root cause? Yes. The unquoted numeric branch now reads the fraction when a . follows, mirroring the scalar readDateTimeTextImpl logic (subsecond scale truncation/padding + negative-timestamp handling). No band-aid guard.
d Test intent preserved / new tests added? New stateless test 04401_array_datetime64_fractional_unix_timestamp.sql added, covering CSV/TSV/JSON/Values/Map, Nullable, negative, scale variants, and the backward-compat bare-int-ticks cases.
e Both directions demonstrated? Yes. Test fails on the pristine binary (CANNOT_READ_ARRAY_FROM_TEXT), passes with the fix. Verified on an up-to-date master build.
f Fix is general across code paths? Yes. All numeric container/JSON entry points fixed: deserializeTextQuoted, tryDeserializeTextQuoted, deserializeTextJSON, tryDeserializeTextJSON (shared helper). These are the only DateTime64 paths that used readIntText. Time64's scalar path does not accept the fractional unix-ts form at all, so there is no scalar/array divergence to fix there.
g Fix generalizes across inputs? Verified across scales 0/3/6/9 (truncate/pad), negative timestamps, Nullable elements, and integer vs fractional forms producing identical values. LowCardinality(DateTime64) is rejected by the type system independently.
h Backward compatible? Yes — no behavior change for any previously-accepted input. A bare integer with no . keeps its raw-tick interpretation ([1504193808] still parses to 1970, not 2017). Only the previously-failing .-form is newly accepted. No setting/format/metadata change.
i Invariants and contracts preserved? Yes. The helper only advances the buffer over the digits it consumes (same contract as readIntText) and builds the value via DecimalUtils::decimalFromComponents, identical to the scalar reader. Array/container element-reader contract (leave buffer at , or ]) is now honored.

Session id: cron:clickhouse-worker-slot-1:20260710-100400

@groeneai

Copy link
Copy Markdown
Contributor Author

cc @Avogar @yariks5s — could you review this? It makes DateTime64 elements inside Array/Tuple/Map and JSON accept the unquoted fractional unix timestamp form (1783585473.954), which scalar columns already accept; the container/JSON path used readIntText and stopped at the .. A bare integer stays a scaled tick count, so no behavior changes for existing inputs.

SELECT 'csv_array_frac', * FROM format(CSV, 'x Array(DateTime64(3))', '"[1783585473.954,1783585473.954]"');

-- Fractional form parses to the same value as the equivalent integer-ticks form.
SELECT 'csv_array_frac_eq_ticks',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@groeneai what about the DateTime type?

@clickhouse-gh

clickhouse-gh Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Workflow [PR], commit [d96914e]

Summary:

job_name test_name status info comment
Integration tests (amd_tsan, 3/6) FAIL
test_replicated_database/test.py::test_replicated_table_structure_alter FAIL cidb, issue

AI Review

Summary

This PR extends unquoted fractional unix-timestamp parsing for nested and JSON DateTime64 values, then folds the follow-up sign, overflow, and parser-consistency fixes back into the shared readers in ReadHelpers.h. I re-checked the final head against the current diff and the earlier review threads, and I did not find any remaining correctness, compatibility, or test-coverage issues in the current version.

Final Verdict
  • Status: ✅ Approve

@clickhouse-gh clickhouse-gh Bot added the pr-bugfix Pull request with bugfix, not backported by default label Jul 10, 2026
Comment thread src/DataTypes/Serializations/SerializationDateTime64.cpp Outdated
readIntText normalises -0 to 0, so the sign was lost for pre-epoch
sub-second values with a zero whole part parsed inside containers
(arrays/tuples/maps) and JSON: -0.123 was stored as 1970-01-01 00:00:00.123
instead of 1969-12-31 23:59:59.877. Restore the sign explicitly when the
whole part is zero and a negative sign was present. Non-zero whole parts
already carry the sign through decimalFromComponents.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@groeneai

Copy link
Copy Markdown
Contributor Author

Re: DateTime.

Checked scalar vs container for plain DateTime, there is no divergence there, so no change is needed:

  • Scalar DateTime rejects the unquoted fractional form on every text path. printf '1783585473.9\n' | clickhouse-local --input-format CSV --structure "x DateTime" gives UNEXPECTED_DATA_AFTER_PARSED_VALUE (and TSV/JSON likewise). SerializationDateTime::deserializeText* route through readDateTimeTextImpl(time_t&, ...), which reads the integer unix timestamp and stops at ., so the leftover .9 is a parse error.
  • Array(DateTime)/JSON containers reject it identically: [1783585473.9] -> CANNOT_READ_ARRAY_FROM_TEXT on the same leftover ..

So plain DateTime behaves consistently across scalar and container (fractional simply not accepted, it is a 1-second-resolution type). The bug was specific to DateTime64, where the scalar path (readDateTime64Text) accepted the fractional unix-timestamp form but the container/JSON path used readIntText and did not. That asymmetry is what this PR removes. Extending the fractional form to DateTime would instead create a new divergence (containers more permissive than scalar), so I left DateTime untouched.

@groeneai

Copy link
Copy Markdown
Contributor Author

Fixed the negative sub-second edge case (0bb3a36).

readIntText normalises -0 to 0, so the sign was lost when the whole part is zero: [-0.123]::Array(DateTime64(3)) used to store 1970-01-01 00:00:00.123 instead of the correct pre-epoch 1969-12-31 23:59:59.877. The old !is_negative && whole < 0 guard I had copied from readDateTimeTextImpl was dead code here, since an integer-only reader never yields a negative whole without a leading -.

New handling: restore the sign explicitly only when a - was present and the whole part is zero. Non-zero negative wholes already carry the sign through decimalFromComponents (whole = -1, frac = 123 -> -1123 ticks), so they are left as is.

Verified against ticks (scale 3): -0.123 -> -123, -1.123 -> -1123, -0.877 -> -877, positive forms unchanged, bare-integer ticks unchanged. Added CSV/JSON regression cases csv_neg_zero_frac, json_neg_zero_frac, csv_neg_one_frac.

@yariks5s yariks5s self-assigned this Jul 10, 2026
Comment thread src/DataTypes/Serializations/SerializationDateTime64.cpp Outdated
The scalar readDateTime64Text path normalised the whole part of -0.xxx to 0
(readIntText drops the sign) and never restored it, so a scalar DateTime64
parsed '-0.123' as 1970-01-01 00:00:00.123 while the container/JSON helper
(fixed earlier in this PR) parsed it as 1969-12-31 23:59:59.877. Factor the
fractional sign finalisation into a shared adjustFractionalDateTimeSign()
used by the scalar DateTime64, Time64, and container paths so all agree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@groeneai

Copy link
Copy Markdown
Contributor Author

Fixed in 237f5a9. Moved the sign restoration into a shared `adjustFractionalDateTimeSign()` helper (src/IO/ReadHelpers.h) now used by the scalar `readDateTimeTextImpl(DateTime64&)`, the `Time64` reader (which already had the same logic inline), and the container/JSON helper. Both cases live in one place:

  • pre-epoch negative whole (ISO form, no leading -): fold fraction into <whole+1>.<scale-fraction>;
  • explicit - with zero whole (readIntText normalises -00): restore sign via the multiplier.

Scalar and container now agree (Basic input format, verified locally):

input scalar DateTime64(3) Array(DateTime64(3)) element
-0.123 1969-12-31 23:59:59.877 1969-12-31 23:59:59.877
-0.877 1969-12-31 23:59:59.123 1969-12-31 23:59:59.123
-1.123 1969-12-31 23:59:58.877 1969-12-31 23:59:58.877

Added scalar regressions to 04401_array_datetime64_fractional_unix_timestamp.sql: scalar_neg_zero_frac and two scalar_eq_container_* equality checks that assert the scalar and container paths produce identical values for -0.xxx and -1.xxx.

CI randomizes date_time_input_format. The fractional unix-timestamp form
this fix adds is a feature of the basic DateTime64 reader
(readDateTime64Text / readNumericText). The best_effort reader is a
separate parser that rejects the '.'-containing form even for scalar
columns, so under a randomized date_time_input_format=best_effort the
test failed with CANNOT_PARSE_DATETIME / UNEXPECTED_DATA_AFTER_PARSED_VALUE.
Pin basic so the test exercises the reader the bug and fix concern.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/DataTypes/Serializations/SerializationDateTime64.cpp Outdated
The scalar readDateTime64Text path already accepts the shorthand -.123
(sign directly followed by the decimal point, implied zero whole part),
but the container/JSON numeric helper went straight through readIntText,
which rejects a lone sign with no digits. That left a scalar/nested
asymmetry for the negative shorthand form.

Special-case -.<digits> in the container helper: consume the sign, leave
whole == 0, and let the shared adjustFractionalDateTimeSign restore the
sign. Now scalar and container agree for -.123.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@groeneai

Copy link
Copy Markdown
Contributor Author

Fixed in e0d333f. The container/JSON numeric helper now special-cases the bare -.<digits> shorthand: it consumes the leading sign (leaving whole == 0) instead of feeding it to readIntText, which rejects a lone sign with no digits. The shared adjustFractionalDateTimeSign then restores the sign, so scalar and container agree:

  • format(CSV, 'x DateTime64(3)', '-.123')1969-12-31 23:59:59.877
  • format(CSV, 'x Array(DateTime64(3))', '"[-.123]"')1969-12-31 23:59:59.877

The .123 form (no sign) already worked because readIntText tolerates zero leading digits. A lone - with no following ./digit still falls through to the existing reject path (CANNOT_PARSE_NUMBER).

Regression coverage added in 04401: csv_neg_shorthand, json_neg_shorthand, pos_shorthand, and scalar_eq_container_neg_shorthand (asserts scalar == container for -.123).

Comment thread src/DataTypes/Serializations/SerializationDateTime64.cpp Outdated
groeneai and others added 2 commits July 10, 2026 19:13
The container/JSON helper detected the bare -.123 shorthand with a
lookahead into the current buffer chunk (istr.available()/position()[1]).
When - was the last byte of a refill and . started the next, the branch
was skipped, readIntText consumed the sign and threw CANNOT_PARSE_NUMBER.
Consume the sign first, then inspect the next byte after an istr.eof()
refill so the decision is independent of chunk boundaries. A lone - with
no fraction or magnitude is still rejected. Adds a streamed regression.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The test declared the array elements as bare Array(DateTime64(3)), whose
rendering via toString() falls back to the host timezone. On a non-UTC CI
runner the pre-epoch values rendered one hour off (e.g. 1970-01-01 00:59:59.877
instead of 1969-12-31 23:59:59.877), failing the reference diff. Pin the
element timezone to 'UTC' in the --structure so rendering is host-TZ-independent.
Parse-correctness assertions are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@groeneai

Copy link
Copy Markdown
Contributor Author

Fixed a test-determinism issue in the new 04409_datetime64_neg_shorthand_chunk_boundary test (fc5e35f). The elements were declared Array(DateTime64(3)) with no timezone, so toString() fell back to the host TZ and a non-UTC runner rendered the pre-epoch values one hour off (1970-01-01 00:59:59.877 vs 1969-12-31 23:59:59.877). Pinned the element timezone to 'UTC' in --structure so rendering is host-TZ-independent; verified identical output under UTC, Europe/Berlin, America/New_York. Parse-correctness assertions unchanged.

Bake 'UTC' into the Array(DateTime64(3, 'UTC')) column type so toString()
rendering is independent of the CI runner's process timezone. The parsed
instants were already correct; only the rendered strings differed under a
non-UTC runner because session_timezone does not propagate into the
arrayMap(toString) element type.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/DataTypes/Serializations/SerializationDateTime64.cpp Outdated
groeneai and others added 2 commits July 10, 2026 22:19
The container/JSON numeric helper read the whole part through readIntText,
which silently accepts a leading '+'. Scalar DateTime64 basic parsing rejects
it (readDateTimeTextFallback only special-cases '-'), and the pre-PR container
path went through readDateTime64Text and also rejected it. Filter '+' up front
so the container/JSON path stays in parity with scalar and pre-PR behavior.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nal test

CI randomizes date_time_input_format. A per-query SETTINGS clause on
format() inside a scalar subquery does not reach the parallel parsing
reader, so under best_effort the scalar -0.xxx rows hit
parseDateTimeBestEffort (which rejects the '.') and fail with
CANNOT_PARSE_DATETIME. Use a top-level SET, which reliably overrides the
runner randomization.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/DataTypes/Serializations/SerializationDateTime64.cpp Outdated
The unquoted container/JSON DateTime64 helper hard-coded the basic-parser
dotted rules regardless of date_time_input_format. Under best_effort the
scalar and quoted-nested paths route through parseDateTime64BestEffort and
reject the dotted fractional/sign/shorthand forms, but the unquoted nested
path still accepted them, so the effective parser depended on quoting/nesting
instead of the setting.

Thread date_time_input_format into the helper and fall back to the pre-PR
bare-integer tick-count path under best_effort/best_effort_us, so the dotted
forms are rejected there exactly as the scalar and quoted paths reject them.
The bare integer tick count still parses under every setting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/DataTypes/Serializations/SerializationDateTime64.cpp Outdated
…ners

The container/JSON DateTime64 helper consumed the leading '-' up front (for
chunk-boundary safety) then read the magnitude into a signed time_t and did
`whole = -whole`. For the minimum tick value -9223372036854775808 the magnitude
2^63 does not fit a signed Int64, so this was signed-overflow UB, and it also
diverged between the throw path (readIntText, no overflow check) and the try
path (tryReadIntText, CHECK_OVERFLOW rejects 2^63). Read the magnitude as
UInt64 and negate via well-defined two's-complement arithmetic, rejecting
magnitudes past 2^63. This preserves INT64_MIN/INT64_MAX exactly, keeps both
paths in agreement, and matches the pre-PR readIntText(x) container behavior.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/DataTypes/Serializations/SerializationDateTime64.cpp Outdated
The unquoted container/JSON helper readNumericTextImpl read the positive
whole part via bare readIntText (DO_NOT_CHECK_OVERFLOW), so the throw path
could consume an out-of-range whole seconds value and wrap a signed time_t
before the fractional logic ran, while the try path (tryReadIntText,
CHECK_OVERFLOW) and the scalar readDateTime64Text path both reject it.

Use ReadIntTextCheckOverflow::CHECK_OVERFLOW for the positive whole part in
both the throw and try helpers, and for the best_effort bare-integer
fallback, so an out-of-range whole is rejected consistently and container
parsing matches scalar. Add regressions for the positive out-of-range whole
(container throw/try + scalar) and an in-range scalar==container check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/DataTypes/Serializations/SerializationDateTime64.cpp
…ime64 containers

The unquoted container/JSON DateTime64 helper rejected a leading '+' only for the
basic dotted path; under best_effort/best_effort_us it took the bare-integer
readIntText fallback first, which accepts '+', so [+1783585473954] parsed while
scalar DateTime64 (parseDateTime64BestEffort) rejects the same token. Move the '+'
guard before the input_format branch so it applies to every date_time_input_format,
restoring scalar/container parity. Also chunk-boundary safe: the '+' byte is
inspected before any refill decision.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/DataTypes/Serializations/SerializationDateTime64.cpp
groeneai and others added 2 commits July 11, 2026 10:31
A token with no digit on either side of the decimal point ('.' or '-.')
was silently coerced to the epoch: readIntText leaves whole == 0, then the
fractional branch consumed '.' and padded an empty mantissa with zeroes.
Both forms were rejected before this PR. Add a digit-presence check in the
shared scalar/container path (readFractionalDateTimePart reports the number
of fractional digits; the whole-part advance is measured via buf.count(),
which is chunk-boundary safe) so scalar DateTime64, Time64, and the
container/JSON helper all reject the empty-mantissa forms and agree.

'.5', '5.', '-.5', '0.' all carry a digit and remain valid.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rence

The non-throwing (try) DateTime64/Time64 text readers recovered on a trailing
'.' whenever the whole reader failed, even after it had consumed date/time bytes
(e.g. `5981 10:01` before `.000`). That fed a bogus whole part into the fractional
branch, which overflowed Decimal64 at large scale during schema inference, so
`5981 10:01.000` inferred as DateTime64(9) and then threw DECIMAL_OVERFLOW instead
of falling back to String. Restrict recovery to the leading-dot shorthand (`.5`,
`-.5`), where the reader consumed nothing but the optional sign. The throwing path
is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@groeneai

Copy link
Copy Markdown
Contributor Author

Fixed the `03720_datetime64_bad_inference` Fast test regression in bf77586.

The round-10 helper change relaxed the non-throwing (try) DateTime64/Time64 readers to recover on a trailing `.` whenever the whole reader failed. That was too broad: for a date-like token such as `5981 10:01.000` the whole reader consumes the date/time bytes, fails (year out of range), and left position at `.`; recovery then fed a bogus whole part into the fractional branch, so schema inference picked `DateTime64(9)` and reading overflowed Decimal64 (`DECIMAL_OVERFLOW`) instead of falling back to `String`.

The fix restricts try-path recovery to the leading-dot shorthand (`.5`, `-.5`), where the reader consumed nothing but the optional sign (`buf.count() == count_before_whole + sign`, chunk-boundary safe). The throwing path is unchanged, so scalar `5.`/`5.5`/`.5` still parse. `03720` now infers `Nullable(String)` again; `03720`, `04401`, and `04409` all pass (x3 with randomized settings).

At scale 3 a 13-digit best_effort millisecond timestamp and a scale-3 raw
tick count render identically, so the existing be_unquoted_bare_int case
cannot distinguish the scalar/quoted (parseDateTime64BestEffort) path from
the unquoted-container raw-tick path. Add a scale-6 case where they differ
(2026-07-09 08:24:33.954000 vs 1970-01-21 15:26:25.473954) and pin all
three paths. The unquoted-vs-scalar/quoted difference is intentional and
pre-existing: before this PR the unquoted numeric container path read a bare
integer with readIntText (raw ticks) under every date_time_input_format, and
preserving bare-integer = raw ticks is a backward-compatibility requirement.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/IO/ReadHelpers.h
groeneai and others added 2 commits July 11, 2026 14:24
The out-of-range-year saturation of a date-like token such as 5981 10:01.000
comes from readDateTimeTextFallback, which this PR does not touch and which
fires identically without a fraction. Add a direct scalar throwing-path case
and assert scalar == toDateTime64OrNull (no throw-vs-try divergence).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The old analyzer drops subquery-level SETTINGS clauses, so the two
best_effort comparison lines had their per-subquery settings ignored and
both sides fell back to the session-level basic reader. With CI randomizing
date_time_input_format the quoted side then read raw ticks and the equality
returned 0 (deterministic FAIL under the old-analyzer coverage config).

Hoist the best_effort settings to the outer query, which both analyzers
honor and which overrides the session SET and CI randomization.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@groeneai

Copy link
Copy Markdown
Contributor Author

Fixed the deterministic `04401` failure under `Stateless tests (amd_llvm_coverage, old analyzer, ...)` (head f51fa36).

Root cause: the two `be_*_bare_s6` best_effort comparison lines put `SETTINGS ... = 'best_effort'` inside the subqueries. The old analyzer drops subquery-level SETTINGS, so both sides fell back to the session-level `basic` reader; with CI randomizing `date_time_input_format` the quoted side read raw ticks and `be_scalar_eq_quoted_bare_s6` returned 0 instead of 1. The standalone `be_scalar_bare_s6`/`be_quoted_bare_s6` lines passed because their SETTINGS live on the top-level SELECT, which the old analyzer honors.

Fix (d96914e, test-only): hoist the best_effort settings to the outer query, which both analyzers honor and which overrides the session SET and CI randomization. Verified all 42 output lines match the reference under both analyzers (0 mismatches), including with a hostile top-level `date_time_input_format=best_effort`; serverError-expecting lines still reject.

@groeneai

Copy link
Copy Markdown
Contributor Author

CI finish ledger — d96914e

CI is fully finished (Finish Workflow + Mergeable Check complete, no checks pending). The PR-caused failures on earlier heads (Fast test 03720/04409, old-analyzer 04401) were fixed and are green on this head. Every remaining failure has an owner; none is caused by this PR's DateTime64 CSV-parse change.

Check / test Reason Owner / fixing PR
Integration tests (amd_asan_ubsan, db disk, old analyzer, 3/6) / test_replicated_database::test_replicated_table_structure_alter flaky (chronic, 81 PRs / 124 hits / 14 master in 30d; unrelated to DateTime64 parsing) #110030 (ours, open)

Report: https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=109978&sha=d96914e26eecd8c6cb51489b8a3de1dd68f1368e&name_0=PR&name_1=Integration%20tests%20%28amd_asan_ubsan%2C%20db%20disk%2C%20old%20analyzer%2C%203%2F6%29

Session id: cron:our-pr-ci-monitor:20260712-023000

@clickhouse-gh

clickhouse-gh Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

LLVM Coverage Report

Metric Baseline Current Δ
Lines 85.80% 85.80% +0.00%
Functions 92.70% 92.70% +0.00%
Branches 77.90% 78.00% +0.10%

Changed lines: Changed C/C++ lines covered: 108/130 (83.08%) · Uncovered code

Full report · Diff report

@clickhouse-gh

clickhouse-gh Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Dear @yariks5s, you haven't been active on this PR for 30 days. You will be unassigned. Will you continue working on it? If so, please feel free to reassign yourself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

can be tested Allows running workflows for external contributors pr-bugfix Pull request with bugfix, not backported by default

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Array(DateTime64(N)) CSV parsing fails for unquoted fractional unix timestamp (e.g. "1783585473.954")

3 participants