Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SQLite SQL types registrations #2346

Merged
merged 4 commits into from
Apr 14, 2020

Conversation

fredericDelaporte
Copy link
Member

@fredericDelaporte fredericDelaporte commented Apr 13, 2020

Invalid types were declared in SQLite dialect, causing cast errors, and having led to an undue hack disabling casting for some types.

Possible breaking change: in order to avoid a floating point division bug losing the fractional part, decimal are now stored as REAL instead of NUMERIC. Both are binary floating point types, excepted that NUMERIC stores integral values as INTEGER. This change may cause big integral decimal values to lose more precision in SQLite.

Invalid types were declared in SQLite dialect, causing cast errors, and having led to an undue hack disabling casting for some types.

return ((DateTime)value).TimeOfDay;

var dbValue = Convert.ToDateTime(value);
Copy link
Member Author

@fredericDelaporte fredericDelaporte Apr 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The direct cast was not failing thanks to having previously used the "internal use only" DATETIME type, causing the data provider to do the convert itself. But this was also wrecking casting, and as documented in their chm, this type is not meant for being used outside of the provider itself.

So we need now to do the convert, as are already doing other NHibernate types dealing with DateTime, see TimeType by example.

hazzik
hazzik previously approved these changes Apr 13, 2020
@fredericDelaporte fredericDelaporte added this to the 5.3 milestone Apr 14, 2020
@fredericDelaporte fredericDelaporte merged commit 66fa1d4 into nhibernate:master Apr 14, 2020
@fredericDelaporte fredericDelaporte deleted the FixSQLiteTypes branch April 14, 2020 17:27
georgi-yakimov pushed a commit to georgi-yakimov/nhibernate-core that referenced this pull request Apr 16, 2020
@hazzik hazzik changed the title Fix SQLite typing Fix SQLite SQL types registrations May 18, 2020
@mihaicodrean
Copy link
Contributor

Was this really a good call when it comes to Decimal? There's no controlling of the decimals count now, when further casting to string, for example, making reporting a pain, for example. Moreover, the SQLite data types manual specifies the affinity of DECIMAL(10,5) to NUMERIC, not REAL.

@fredericDelaporte
Copy link
Member Author

There was never any actual control of decimal count with SQLite, it has no decimal support. It only has binary floats.

@mihaicodrean
Copy link
Contributor

You're right, I worded it ambiguously. I meant it more like decimals vs. no-decimals, because one now ends up with decimals where there were none previously, due to the replaced NUMERIC:

select sum(cast(FileSize as NUMERIC)) / 1024 / 1024 as MB from Files
=> 14

with REAL:

select sum(cast(FileSize as REAL)) / 1024 / 1024 as MB from Files
=> 14.9871826171875

This is a breaking change, with the workaround to add an extra cast:

select cast(sum(cast(FileSize as REAL)) / 1024 / 1024 as INTEGER) as MB from Files
=> 14

@fredericDelaporte
Copy link
Member Author

This case exploits some very specific behavior of SQLite, where a type that can handle a fractional part behaves as an integer regarding divisions if the provided number is integral. This looks to me as an extreme corner case. Better explicitly use integers where integer behavior is required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants