Uh oh!
There was an error while loading. Please reload this page.
feat: add toStartOf* date-time function translations via EF.Functions - #57
Conversation
Expose the ClickHouse toStartOf* family as EF.Functions extension methods, following the existing EF.Functions.SimpleJson* pattern. This is the provider's first date-time translation surface. Covers the full family: ToStartOfYear/Quarter/Month/Week (with optional week mode), ToStartOfDay/Hour/Minute/Second, the fixed buckets FiveMinutes/TenMinutes/FifteenMinutes, and the general ToStartOfInterval(source, value, unit). Each is generic over the source so DateTime, DateOnly, and DateTime64-mapped columns all work, including in GROUP BY. ToStartOfInterval takes a ClickHouseInterval enum unit and is emitted as toStartOfInterval(source, toInterval<unit>(value)), avoiding raw INTERVAL n UNIT syntax; the unit must be a constant to be translated. The reflection-based translator dictionary leaves room to add the rest of the ClickHouse date family (toYear, date_diff, addX, ...) with no new plumbing. The optional timezone/origin trailing args are deferred to future overloads. Note: default ToStartOfWeek mode 0 is Sunday-based, verified empirically against ClickHouse 25.8 (the upstream docs example is stale). New: - Metadata/ClickHouseInterval.cs - Extensions/ClickHouseDateTimeDbFunctionsExtensions.cs - Query/ExpressionTranslators/Internal/ClickHouseDateTimeMethodTranslator.cs - test/EFCore.ClickHouse.Tests/DateTimeFunctionsTranslationTests.cs (20 tests) Modified: - register translator in ClickHouseMethodCallTranslatorProvider - mark the extensions type non-client-evaluable in ClickHouseEvaluatableExpressionFilter - README.md, CHANGELOG.md, RELEASENOTES.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Adds EF Core translations for ClickHouse toStartOf* date/time functions.
Changes:
- Adds public
EF.Functions.ToStartOf*APIs and interval units. - Registers translation and client-evaluation filtering.
- Adds integration tests and user documentation.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
ClickHouseInterval.cs | Defines supported interval units. |
ClickHouseDateTimeDbFunctionsExtensions.cs | Exposes date/time functions. |
ClickHouseDateTimeMethodTranslator.cs | Generates corresponding ClickHouse SQL. |
ClickHouseMethodCallTranslatorProvider.cs | Registers the translator. |
ClickHouseEvaluatableExpressionFilter.cs | Prevents client evaluation. |
DateTimeFunctionsTranslationTests.cs | Tests translation and execution. |
README.md | Documents usage. |
CHANGELOG.md | Records the feature. |
RELEASENOTES.md | Describes the release behavior. |
Suppressed comments (1)
src/EFCore.ClickHouse/Query/ExpressionTranslators/Internal/ClickHouseDateTimeMethodTranslator.cs:163
toStartOfIntervalhas an additional server-version issue: ClickHouse's release history says source-type-preserving extended results were only fixed in 26.1, while this PR explicitly targets/tests 25.8. Mapping the result as the source type cannot prevent 25.8 from narrowingDate32/DateTime64, so extended-range buckets can be wrong. Either establish ClickHouse 26.1 as the minimum and enforce the extended-results setting, or implement semantics compatible with the supported server range.
returnType: method.ReturnType,
typeMapping: source.TypeMapping);
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
tomh4
commented
Aug 11, 2026
i will revisit this to make the bots happy |
EF.Functions.ToStartOf* with a constant argument is a client-eval candidate; ClickHouseEvaluatableExpressionFilter forces it server-side. No existing test exercised that path (all pass columns), so it showed as uncovered. Add a translation-only test that asserts the constant-argument call is emitted as server-side SQL.
The notes claimed the whole family works over DateOnly. Verified against ClickHouse 23.8, 24.8 and 26.7: the calendar and sub-day truncation functions accept Date32, but toStartOfInterval rejects it on older releases (Illegal type Date32). Also drop the incorrect claim that toStartOfSecond requires DateTime64 (it accepts Date/DateTime and returns DateTime64). Split the statement by function and input type.
The 2026-only test couldn't catch ClickHouse's default narrowing of Date/DateTime results. Add pre-1970 integration cases showing the calendar clamp (1920 -> 1970) and the interval wraparound, plus a case that enables enable_extended_results_for_datetime_functions (via a set_* connection string) and verifies Date32/DateTime64 preserve the full range. Document the range limitation and the opt-in in README/CHANGELOG/RELEASENOTES.
alex-clickhouse
commented
Aug 12, 2026
LGTM, thank you for the PR! |
Addresses issue Feature Request: Add Support for toStartOf* #56 , created in a similar way to exisiting Functions Extensions (e.g. ClickHouseJsonDbFunctionsExtensions)
Once there is support for DateTimeOffset, this might need to be revised adn adjusted (see DateTimeOffset not supported #53)
Expose the ClickHouse toStartOf* family as EF.Functions extension methods, following the existing EF.Functions.SimpleJson* pattern.
Covers the full family: ToStartOfYear/Quarter/Month/Week (with optional week mode), ToStartOfDay/Hour/Minute/Second, the fixed buckets FiveMinutes/TenMinutes/FifteenMinutes, and the general ToStartOfInterval(source, value, unit). Each is generic over the source so DateTime, DateOnly, and DateTime64-mapped columns all work, including in GROUP BY.
ToStartOfInterval takes a ClickHouseInterval enum unit and is emitted as toStartOfInterval(source, toInterval(value)), avoiding raw INTERVAL n UNIT syntax; the unit must be a constant to be translated.
Adding the rest of the ClickHouse date functions later (toYear, date_diff, addX, and so on) can be easily don. I left off the optional timezone/origin arguments for now; we can add overloads for those if anyone needs them.
IMPORTANT: ToStartOfWeek with the default mode (0) starts weeks on Sunday, not Monday. I checked this against ClickHouse 25.8 directly because the example in their docs actually shows the wrong output.. (https://clickhouse.com/docs/reference/functions/regular-functions/date-time-functions#toStartOfWeek)
New:
Modified: