Problem
The provider translates no DateTime members and no DateTime methods. Only a direct comparison works.
EF Core's base RelationalMemberTranslatorProvider registers no built-in translators. It adds plugins only (RelationalMemberTranslatorProvider.cs:22). ClickHouseMemberTranslatorProvider adds ClickHouseArrayMethodTranslator and ClickHouseStringMethodTranslator only. No date/time translator exists.
Measured behaviour
Tested against a real ClickHouse server, on a DateTime property with column type DateTime64(6, 'UTC'):
| Expression | Result |
|---|
.Year.Month.Day.Hour.Minute | InvalidOperationException: The LINQ expression ... could not be translated |
.Date.DayOfWeek.DayOfYear.TimeOfDay | same |
.AddDays(1).AddMonths(1) | same |
DateTime.UtcNow / DateTime.Now / DateTime.Today | same |
dt - dt (result is TimeSpan) | InvalidCastException: Unable to cast object of type 'System.TimeSpan' to type 'System.DateTime' |
ts > new DateTime(2020, 1, 1) | works: WHERE `d`.`ts` > '2020-01-01 00:00:00.000000' |
The dt - dt result is different from the others. It gives an InvalidCastException instead of a clear "could not be translated" message. This looks like a defect, not only a missing feature.
Suggested work
Add one shared date/time member translator. Give it the CLR type as a parameter so that it serves DateTime, DateOnly, and DateTimeOffset from the same class. Npgsql uses this shape (NpgsqlDateTimeMemberTranslator).
ClickHouse functions to map:
| Member | ClickHouse function |
|---|
.Year | toYear |
.Month | toMonth |
.Day | toDayOfMonth |
.Hour | toHour |
.Minute | toMinute |
.Second | toSecond |
.DayOfYear | toDayOfYear |
.DayOfWeek | toDayOfWeek (note: ClickHouse counts Monday as 1, .NET counts Sunday as 0) |
.Date | toStartOfDay |
.AddDays / .AddMonths / .AddYears | date_add |
DateTime.UtcNow | now64 |
Also translate the DateTime difference to date_diff, or give a clear "not supported" message.
Take care with two ClickHouse behaviours:
toDayOfWeek starts at Monday = 1. .NET DayOfWeek starts at Sunday = 0. The translation must adjust the value, in the same way the string translators adjust the 0-based to 1-based index.- These functions read the column timezone. For a
DateTimeOffset property the result must stay consistent with the UTC instant that the column holds.
Notes
Found while I investigated #53. DateTimeOffset needs the same translators, so one shared class is better than a DateTimeOffset-only class. #53 itself needs comparison support only, which already works.
Problem
The provider translates no
DateTimemembers and noDateTimemethods. Only a direct comparison works.EF Core's base
RelationalMemberTranslatorProviderregisters no built-in translators. It adds plugins only (RelationalMemberTranslatorProvider.cs:22).ClickHouseMemberTranslatorProvideraddsClickHouseArrayMethodTranslatorandClickHouseStringMethodTranslatoronly. No date/time translator exists.Measured behaviour
Tested against a real ClickHouse server, on a
DateTimeproperty with column typeDateTime64(6, 'UTC'):.Year.Month.Day.Hour.MinuteInvalidOperationException: The LINQ expression ... could not be translated.Date.DayOfWeek.DayOfYear.TimeOfDay.AddDays(1).AddMonths(1)DateTime.UtcNow/DateTime.Now/DateTime.Todaydt - dt(result isTimeSpan)InvalidCastException: Unable to cast object of type 'System.TimeSpan' to type 'System.DateTime'ts > new DateTime(2020, 1, 1)WHERE `d`.`ts` > '2020-01-01 00:00:00.000000'The
dt - dtresult is different from the others. It gives anInvalidCastExceptioninstead of a clear "could not be translated" message. This looks like a defect, not only a missing feature.Suggested work
Add one shared date/time member translator. Give it the CLR type as a parameter so that it serves
DateTime,DateOnly, andDateTimeOffsetfrom the same class. Npgsql uses this shape (NpgsqlDateTimeMemberTranslator).ClickHouse functions to map:
.YeartoYear.MonthtoMonth.DaytoDayOfMonth.HourtoHour.MinutetoMinute.SecondtoSecond.DayOfYeartoDayOfYear.DayOfWeektoDayOfWeek(note: ClickHouse counts Monday as 1, .NET counts Sunday as 0).DatetoStartOfDay.AddDays/.AddMonths/.AddYearsdate_addDateTime.UtcNownow64Also translate the
DateTimedifference todate_diff, or give a clear "not supported" message.Take care with two ClickHouse behaviours:
toDayOfWeekstarts at Monday = 1. .NETDayOfWeekstarts at Sunday = 0. The translation must adjust the value, in the same way the string translators adjust the 0-based to 1-based index.DateTimeOffsetproperty the result must stay consistent with the UTC instant that the column holds.Notes
Found while I investigated #53.
DateTimeOffsetneeds the same translators, so one shared class is better than aDateTimeOffset-only class. #53 itself needs comparison support only, which already works.