-
Notifications
You must be signed in to change notification settings - Fork 935
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
NH-4087 - Fix decimal parameter with scale above 5 #708
Conversation
namespace NHibernate.Test.DriverTest | ||
{ | ||
[TestFixture] | ||
public class OdbcDriverFixture : TestCase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy paste of SqlClientDriverFixture
which was executed for ODBC too, but with some specific test asserting ignore when it was ODBC. Now separated in its own fixture, with only non-ignored tests.
Assert.That(m.StringProp, Is.EqualTo("a"), "StringProp"); | ||
Assert.That(m.StringClob, Is.EqualTo("a"), "StringClob"); | ||
Assert.That(m.BinaryBlob, Is.EqualTo(new byte[] { 1, 2, 3 }), "BinaryBlob"); | ||
Assert.That(m.Binary, Is.EqualTo(new byte[] { 4, 5, 6 }), "BinaryBlob"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test was previously just saving/updating without checking values.
|
||
t.Rollback(); | ||
} | ||
} | ||
|
||
[Test] | ||
public void DefaultPrecisionScale() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added test for new decimal precision/Scale settings.
src/NHibernate.Test/TestDialect.cs
Outdated
/// <summary> | ||
/// Supports condition not bound to any data, like "where @p1 = @p2". | ||
/// </summary> | ||
public virtual bool SupportsNonDataBoundCondition => true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied from #703, I will have to resolve a conflict on one of those PR depending on merge order. But I was needing this.
} | ||
|
||
[Test] | ||
public void HighScaleParameterSelect() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting with this one, new tests for checking "high" scale decimal are not truncated.
if (Dialect is FirebirdDialect) | ||
{ | ||
configuration.SetProperty(Environment.ParameterDefaultDecimalPrecision, "18"); | ||
configuration.SetProperty(Environment.ParameterDefaultDecimalScale, "9"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to Firebird needing an explicit cast in some queries, injected by its driver, we must set its default scale/precision according to what the application needs. (Applications having varying needs will be stuck by this Firebird limitation, unless they use separated session factories just for those varying needs...)
return _fbDialect.GetTypeName(sqlType); | ||
return _fbDialect.GetTypeName(SqlTypeFactory.GetSqlType(sqlType.DbType, _dbDecimalPrecision, _dbDecimalScale)); | ||
} | ||
return _fbDialect.GetCastTypeName(sqlType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This GetCastTypeName
is quite a terrible method, hopefully having few usages. It disregards the type Length
/Precision
/Scale
and use instead Column.DefaultLength
/Column.DefaultPrecision
/Column.DefaultScale
, which are 255
/19
/2
.
This causes all string types to be cast to a 255
length. Decimal type are trim down to 18
precision by dialect, but anyway, since the type resolution currently compares provided length with the max for the type, which is well below 255
for decimal
, it always uses the default for decimal
type, which for Firebird is decimal(18,5)
. Otherwise we would have got a truncation at 2 digits after dot.
I will fill another Jira for that method.
SqlClientDriver.SetVariableLengthParameterSize(dbParam, sqlType); | ||
} | ||
SqlClientDriver.SetVariableLengthParameterSize(dbParam, sqlType, _dbDecimalPrecision, _dbDecimalScale); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it really make sense to set length for SqlServerCe? I believe its sole purpose it to optimize query plan cache usage, but does SqlServerCe have a query plan cache?
b15723f
to
2874cc9
Compare
2874cc9
to
4a41c89
Compare
Rebased, changed due to |
} | ||
|
||
// Used from SqlServerCeDriver as well | ||
public static void SetVariableLengthParameterSize(DbParameter dbParam, SqlType sqlType) | ||
public static void SetVariableLengthParameterSize( | ||
DbParameter dbParam, SqlType sqlType, byte defaultDecimalPrecision, byte defaultDecimalScale) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If doing that in 5.1, I guess we will have to add back previous method but flagged obsolete, for avoiding a possible breaking change.
4a41c89
to
2f1c4e0
Compare
Rebased and adjusted for having no more breaking changes. |
c4a4e00
to
e12bb7d
Compare
* Use dialect configurable default scale/precision * Fixes nhibernate#1187
e12bb7d
to
02a4f71
Compare
Rebased, reworded. |
Anything against merging this ? |
@fredericDelaporte absolutely nothing apart I don't understand how it works. |
The trouble: currently SqlClientDriver set a hard coded scale (5) and precision (28) on decimal parameters when their parameter definition does not specify it. (They may be deduced and set by the HQL query parsing in some cases, but not in all cases.) This causes issues when the parameter value need a higher scale than 5. With 5.0, a configurable default scale (10) and default precision (28) have been introduced, currently used when a cast is issued in HQL or Linq. This PR uses them instead of the hard coded non configurable ones from SqlClientDriver. So now the user can control the default scale of decimal parameter, and adjust it to its needs, instead of being limited to 5. This PR also adds tests for checking for all dialects we can now use decimal with a scale higher than 5. The Sql client driver test fixture is also split in two, because it was actually also testing the Odbc driver, which was complexifying it and causing issues for the sql client driver changes tests. Now there is an odbc driver fixture on its own, along with the Sql client driver fixture purged from Odbc specific bits. |
NH-4087 (#1196) - Fix decimal parameter with scale above 5
Cease defining default precision/scale in SQL Server driver unless explicitly configuredAllow Firebird to adjust its default parameter type cast