feat: add toStartOf* date-time function translations via EF.Functions - #57
Merged
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.
Contributor
Author
|
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.
Collaborator
|
LGTM, thank you for the PR! |
alex-clickhouse
approved these changes
Aug 12, 2026
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.
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: