Open bricelam opened 4 years ago
I made some good progress in bricelam:timespan, but I ran into floating-point precision issues and wanted to re-examine how we handle TimeSpan and DateTime literals and parameters on SQLite before moving forward.
Assert.Equal() Failure
Expected: 00:01:00
Actual: 00:00:59.9999964
In order to get this to round to the correct time we need to re-create the TimeSpan (and possibly DateTime) instances in various places using a constructor overload that doesn't take double
.
We could also consider adding a collation.
.NET | SQL |
---|---|
OrderBy(t => t.TimeSpan) | ORDER BY t.TimeSpan COLLATE EF_TIMESPAN |
OrderByDescending(t => t.TimeSpan) | ORDER BY t.TimeSpan COLLATE EF_TIMESPAN DESC |
Note, we can use the mod
function from #18843 (which works with non-integer values) to simplify some translations (including the one for DateTime.Millisecond) which should also avoid overflows.
We can enable these by registering two UDFs on the connection:
The following translations are enabled.
Notes:
datetime()
should actually be translated asrtrim(rtrim(strftime('%Y-%m-%d %H:%M:%f'), '0'), '.')
julianday(datetime(text, modifiers))
can reduce tojulianday(text, modifiers)
julianday(datetime(real))
can reduce toreal
ef_days(ef_timespan(real))
can reduce toreal