Skip to content

Conversation

@alex-kulakov
Copy link
Contributor

@alex-kulakov alex-kulakov commented Mar 6, 2023

Adds support for these new types of .NET6 to all supported storages. This PR includes #251 and makes some changes over it.

Main changes:

  • Extraction of column types, assigning with SQL types, reading from and writing to storage.
  • Support for different operations within LINQ.
  • Added new SqlDml methods for operations with these types, such as parts extraction, additions/subtractions, construction from parts, value conversion between DateTime, DateOnly, TimeOnly and DateTimeOffset (when and if possible)
  • Perform data conversion on schema upgrade when ChangeFieldTypeHint is applied.
  • Tests.

Depending on storage, TimeOnly values will have different precision when stored - from 7 for MS SQL Server and Oracle, to six and sometimes 4 fractional digits. MySQL 5.5 (provider still exists thought it was excluded from the supported storages due to age age) has no support for time fractions.

SQL types DATE and TIME are used for DateOnly and TimeOnly respectively, except for Oracle in which there is no TIME type so we used INTERVAL DAY (0) TO SECOND(7). TIME behavior on storage side differentiates between RDBMSs and .NET, for example even so MySQL can store more that 800 hours in TIME operation of adding interval to it will always have not more than 23 in 'hour' part as it is in .NET. Expect .NET-like operations.

On data conversion in case some field (and underlying column) changes type between DateTime/DateOnly/TimeOnly/DateTimeOffset, the conversion happens on storage side. We don't assume and use internal mechanisms whenever it is possible, but sometimes we have to. There is some variation of results of conversion.

DateOnly-to-DateTime conversion is predictable and uses zero-time across the board.

TimeOnly-to-DateTime conversion has a lot of difference:

  • when casting from TIME to DATETIME2, MS SQL Server internal mechanisms use '1900-01-01' as date (under the hood it puts 0000-00-00 as date part but since it is invalid it replaces it with 1900-01-01).
  • MySQL (from 5.6+) uses current server date, for MySQL 5.5 we mimic this behavior but use literal value of current date.
  • PostgreSQL, does not have built-in cast for several data conversions including this, so we had to decide how to convert values. Due to Postgres' connection to UNIX world, UNIX EPOCH is used as default date value thought 0001-01-01 is valid date, it was made so because naturally to_timestamp(0) returns 1970-01-01, not the 0001-01-01. So, for people who work with PostgreSQL this date will be known and expected.
  • Firebird uses current server date, all by itself, as well as MySQL.
  • Oracle just puts minimal date value - 0001-01-01.
  • SQLite uses 1900-01-01 as date.

TimeOnly-to-DateTimeOffset is tricky too. Conversion uses same principals for date part as above but time zone part applied to the value changes depending on RDBMS and even value. For more context take a look at Xtensive.Orm.Tests.Upgrade.DateTimeTypesDataConversionTest

TimeOnly-to-DateOnly causes an exception for all storages except for SQLite (but it's its own thing) for obvious reason.

NOTE There is no support for TimeOnly(long ticks) constructor and TimeOnly.Ticks part yet.

SergeiPavlov and others added 30 commits June 6, 2022 16:29
Fix formatting

Fix tests
…oProvider.cs

Co-authored-by: Oleg Shuruev <shuruev@gmail.com>
…oProvider.cs

Co-authored-by: Oleg Shuruev <shuruev@gmail.com>
Draft implementation of support of DateOnly/TimeOnly types for 
MS SQL Server
temporary keep previous compilation variable as comment
- new SqlDml Methods for Time and Date
- rename DateOnlyXxx and TimeOnlyXxx to DateXxx and TimeXxx to be related to with SQL
- new SqlFunctionTypes & SqlNodeTypes
@alex-kulakov
Copy link
Contributor Author

@SergeiPavlov, Is this a problem that there is no new TimeOnly(ticks) support?

# Conflicts:
#	Orm/Xtensive.Orm.Tests/Upgrade/FullText/DomainUpgradeFullTextTest.cs
#	Orm/Xtensive.Orm/Orm/Providers/Expressions/ExpressionProcessor.cs
#	Orm/Xtensive.Orm/Sql/Info/DataTypeCollection.cs
@SergeiPavlov
Copy link
Contributor

SergeiPavlov commented Mar 7, 2023

@SergeiPavlov, Is this a problem that there is no new TimeOnly(ticks) support?

Why no support?
https://learn.microsoft.com/en-us/dotnet/api/system.timeonly.-ctor?view=net-8.0#system-timeonly-ctor(system-int64)

@alex-kulakov
Copy link
Contributor Author

alex-kulakov commented Mar 7, 2023

The guys in DPA are waiting for at least RC to work with it in development branch so it is mostly because of timings. I'm going to add it later.

@alex-kulakov alex-kulakov merged commit 4e8dfa7 into master Mar 7, 2023
@alex-kulakov alex-kulakov deleted the master-date-and-time-support branch March 9, 2023 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants