Fix setting ignored for numeric-to-DateTime64/Time64 casts by RenzoMXD · Pull Request #100535 · ClickHouse/ClickHouse · GitHub
Skip to content

Fix setting ignored for numeric-to-DateTime64/Time64 casts#100535

Open
RenzoMXD wants to merge 23 commits into
ClickHouse:masterfrom
RenzoMXD:fix-datetime-overflow-behavior
Open

Fix setting ignored for numeric-to-DateTime64/Time64 casts#100535
RenzoMXD wants to merge 23 commits into
ClickHouse:masterfrom
RenzoMXD:fix-datetime-overflow-behavior

Conversation

@RenzoMXD

Copy link
Copy Markdown
Contributor

Fix date_time_overflow_behavior setting being ignored when casting numeric types (Int64, UInt64, Float64) to DateTime64 / Time64. The setting was silently clamping values instead of throwing VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE when set to throw.

Two root causes:

  1. In ConvertImpl::execute (FunctionsConversion.h), 15 conversion branches passed the hardcoded default_date_time_overflow_behavior (Ignore) instead of the template parameter date_time_overflow_behavior to the transform structs. This broke the toDateTime64 / toTime64 runtime path.

  2. In FunctionCast::createDecimalWrapper (FunctionsConversion.cpp), ConvertImpl was called without specifying the overflow behavior template parameter, always defaulting to Ignore. This broke the CAST(... AS DateTime64) path, including constant-folded expressions.

Fixes #100471

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):

Fix date_time_overflow_behavior setting being ignored for numeric-to-DateTime64/Time64 conversions via CAST, toDateTime64, and toTime64.

Documentation entry for user-facing changes

  • Documentation is written (mandatory for new features)

No documentation changes needed — this is a bug fix for existing documented behavior.

@yariks5s yariks5s self-assigned this Mar 24, 2026
@yariks5s yariks5s added the can be tested Allows running workflows for external contributors label Mar 24, 2026
@clickhouse-gh

clickhouse-gh Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

@clickhouse-gh clickhouse-gh Bot added the pr-bugfix Pull request with bugfix, not backported by default label Mar 24, 2026
@RenzoMXD RenzoMXD force-pushed the fix-datetime-overflow-behavior branch from 0c9fc33 to 1d4b032 Compare March 25, 2026 02:23
Comment thread src/Functions/FunctionsConversion.h Outdated
@RenzoMXD RenzoMXD force-pushed the fix-datetime-overflow-behavior branch from 1d4b032 to afa6e33 Compare March 25, 2026 04:06
@RenzoMXD

Copy link
Copy Markdown
Contributor Author

@yariks5s
I updated code. Please review again. Thanks.

@RenzoMXD

Copy link
Copy Markdown
Contributor Author

@rschu1ze @alexey-milovidov @yariks5s
Can you review my PR please? Thanks.

@yariks5s

Copy link
Copy Markdown
Member

@RenzoMXD I will check your PR soon, there are a lot of PRs to check, so it can sometimes take some time to review pull requests. Anyway, I remember about your pr and will check it.🙂

@rschu1ze

Copy link
Copy Markdown
Member

@RenzoMXD Thanks for the contribution(s). There is generally no need to ping random people, all PRs get eventually reviewed (it may just take a while).

@RenzoMXD

RenzoMXD commented Mar 31, 2026

Copy link
Copy Markdown
Contributor Author

@yariks5s @rschu1ze Thanks. Sorry for many pings.

@RenzoMXD

RenzoMXD commented Apr 2, 2026

Copy link
Copy Markdown
Contributor Author

Hi, @yariks5s. Sorry for interrupting you.
Is there any feedback for me?
I merged main branch and I think this failure is not from my change.
Please review. Thanks.

@rschu1ze

rschu1ze commented Apr 2, 2026

Copy link
Copy Markdown
Member

@RenzoMXD In general, it is really not needed to ask for new reviews once a day. This creates a false sense of urgency and priority on our end.

@RenzoMXD

RenzoMXD commented Apr 6, 2026

Copy link
Copy Markdown
Contributor Author

Hi, @yariks5s @alexey-milovidov @rschu1ze
Please review my PR and let me know if anything else is needed to update.
Thanks.

@alexey-milovidov

Copy link
Copy Markdown
Member

The Stress test (arm_msan) failure is fixed by #101239, which should be merged first. After it is merged, please update the branch to include the fix.

@RenzoMXD

RenzoMXD commented Apr 7, 2026

Copy link
Copy Markdown
Contributor Author

@alexey-milovidov Please give me any advice for this failure.
I don't think it's from my change. Thanks.

Comment thread src/Functions/FunctionsConversion.cpp Outdated
@alexey-milovidov

Copy link
Copy Markdown
Member

The failures of "Flaky check" in "functions_bad_arguments" will be fixed by #101994.

Comment thread src/Functions/FunctionsConversion.h Outdated
@RenzoMXD RenzoMXD closed this Apr 10, 2026
@RenzoMXD RenzoMXD reopened this Apr 10, 2026
@RenzoMXD

Copy link
Copy Markdown
Contributor Author

Hi, @yariks5s @rschu1ze
Can you review my PR please? I tried many times but still don't pass CI tests. I think test failures are not from my change.
I appreciate any advice from you. Thanks.

Comment thread src/Functions/FunctionsConversion.h
Comment thread src/Functions/FunctionsConversion.h
RenzoMXD and others added 4 commits May 1, 2026 06:23
…onversions

When a UInt64 above INT64_MAX is converted to DateTime64 / Time with
date_time_overflow_behavior = saturate or ignore, the previous code
clamped via std::min(time_t(from), MAX_*). Casting such a value to
signed time_t is implementation-defined and typically wraps to a
negative number, so the clamp returned the negative value instead
of saturating to the upper bound.

Clamp in the unsigned domain first (std::min<UInt64>), then cast,
mirroring the pattern already used by ToTime64TransformUnsigned.

Also rename the test added in this PR to 04141_* to avoid the
04056_* prefix collision with nine unrelated tests, and add
boundary regressions exercising 18446744073709551615::UInt64.

Refs ClickHouse#100535

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit's test added two queries:
    SELECT toTime(18446744073709551615::UInt64) SETTINGS date_time_overflow_behavior = ...
which fail with `Illegal type UInt64 of argument of function toTimeWithFixedDate`.
The `toTime` function does not accept a numeric input, so these queries are
invalid. Drop them; the matching `toDateTime64(...)` and `CAST(..., 'DateTime64(3)')`
boundary queries still exercise the fix in `ToDateTime64TransformUnsigned`.

Also rename the test from 04141 to 04145: 04141 has been claimed by five
unrelated tests on master since the previous rename.

CI report: https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=100535&sha=7f0d78ba58a7e0d1ea30f709451ae6f8b8ca6ca5&name_0=PR&name_1=Fast%20test
PR: ClickHouse#100535

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@PedroTadim

Copy link
Copy Markdown
Member

Hello! Why this PR was closed?

@RenzoMXD RenzoMXD reopened this Jul 3, 2026
{
if constexpr (std::is_same_v<ToDataType, DataTypeDateTime>)
return DateTimeTransformImpl<FromDataType, ToDataType, ToDateTimeTransform64<typename FromDataType::FieldType, UInt32, default_date_time_overflow_behavior>, false>::template execute<Additions>(
return DateTimeTransformImpl<FromDataType, ToDataType, ToDateTimeTransform64<typename FromDataType::FieldType, UInt32, date_time_overflow_behavior>, false>::template execute<Additions>(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Routing UInt64 -> DateTime through date_time_overflow_behavior here exposes the same signed-intermediate bug that this PR already had to fix for Time and DateTime64.

ToDateTimeTransform64::execute still clamps with std::min(time_t(from), time_t(MAX_DATETIME_TIMESTAMP)), so values above INT64_MAX wrap before the clamp. On a typical 64-bit signed time_t, CAST(9223372036854775808::UInt64, 'DateTime') SETTINGS date_time_overflow_behavior = 'saturate' goes through INT64_MIN, then casts back to UInt32 as 0, i.e. 1970-01-01 00:00:00 instead of saturating to 2106-02-07 06:28:15.

The same pattern is still present in the UInt64 -> Date / Date32 branches that were switched above: both helpers convert the huge unsigned value to a signed time_t / Int64 before applying std::min, so saturate / ignore can wrap toward the low end instead of the maximum representable date.

Please clamp in the unsigned domain first (same pattern as ToTimeTransform64 / ToDateTime64TransformUnsigned) and add regressions for at least CAST(9223372036854775808::UInt64, 'DateTime') and CAST(9223372036854775808::UInt64, 'Date') with date_time_overflow_behavior = 'saturate'.

@clickhouse-gh

clickhouse-gh Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

LLVM Coverage Report

Metric Baseline Current Δ
Lines 85.50% 85.60% +0.10%
Functions 92.70% 92.70% +0.00%
Branches 77.70% 77.70% +0.00%

Changed lines: Changed C/C++ lines covered: 49/62 (79.03%) · Uncovered code

Full report · Diff report

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.

date_time_overflow_behavior='throw' silently ignored for Int/UInt/Float -> DateTime64 and Time64 casts

5 participants