-
Notifications
You must be signed in to change notification settings - Fork 934
Fixes with prepare_sql #710
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
Conversation
It seems to demonstrate older issues, mainly with |
Ok, then we need to add these sizings |
Currently testing that, going to add a Jira. Any way good catch. Since this seems a SQL Client specific trouble, do we add this prepare_sql to the 2012 build by example? Testing 2008 without, 2012 with? Or do we duplicate all SQL Server builds, so long for the total build time? |
58e39af
to
7eec6eb
Compare
I have overwritten your merge with a rebase + a quick fix to check if there are other issues than time with SQL Server. |
@@ -144,6 +145,9 @@ protected static void SetDefaultParameterSize(DbParameter dbParam, SqlType sqlTy | |||
case DbType.DateTimeOffset: | |||
dbParam.Size = MaxDateTimeOffset; | |||
break; | |||
case DbType.Time: |
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.
Ideally, this should be in 2008 driver, as 2005 does not support time and reverts it to DateTime. Same for DateTime2.
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.
And same for DateTimeOffset
. Defining defaults for those types supported only for 2008+ in the driver for previous versions is not very sound, excepted that the current pattern of sharing that method with SQL Server Ce, causing it to be static, causes it to be hard to be overridden in 2008 driver.
The reverting for DbType.Time
and DbType.Date
seems to be a specific "feature" of DbParameter
interface implementation for SqlParameter
, when setting types through DbType
property, forcing us to set them through SqlDbType
, and only into 2008 driver.
To clean-up that maybe we should cease sharing with SQL Server CE, switch to instance methods and override them. But it would be a breaking change for those using DateTime2
and DateTimeOffset
with the old SQL Server driver.
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.
Another option could be to check the dialect in SqlClientDriver
for flagging whether we are using 2008+ or not, and if yes port and use corresponding code from SqlClient2008Driver
. That way, no need to override anything anymore in SqlClient2008Driver
, which would be then set as obsolete.
ODBC, Firebird and PostgreSQL are failing due to to four tests, like |
SQL Server CE fails with insufficient memory errors on blob types tests. It seems to be yet another issue. |
This occurs only with 32 bits version. The 64 bits does not have the trouble. The root of the trouble is the default sizing of binary parameters to 2Gb when So we could fix this NH-4091 by ceasing specifying parameter sizes even when |
6a49288
to
3a0a383
Compare
// the test SqlConverter to do its job. | ||
return !(Dialect is MsSqlCeDialect); | ||
var prepareSql = PropertiesHelper.GetBoolean(Environment.PrepareSql, cfg.Properties, false); | ||
return !(prepareSql || Dialect is MsSqlCeDialect); |
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.
Maybe it shall be only for SqlClientDriver?
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.
return !(prepareSql && !(driver is SqlClientDriver) || Dialect is MsSqlCeDialect);
? Or just return driver is SqlClientDriver
?
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.
Second
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.
I do not really get why it should be considered a Sql Server only test. For me it is more like this tests reveal there is some "too wide" catching in place causing the feature to be unavailable for most databases when prepare is enabled. Anyways, that is a quite secondary feature in my mind, and the code lacks indications as to why this "wide" catch is there, so I do not think we should investigate/fix this point, at least not for 5.0.
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.
Ok, leave it as is
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.
Or maybe more accurately, reveals that the test implementation (closing the connection) is not suitable for most databases when prepare is enabled. Maybe should it instead use a trick (like the nullable no null column in some transactions tests for failures) to alter the schema and use that to cause an actual db side failure.
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.
Well, already changed, with comment corresponding to my last comment just above.
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.
Need to regen the async
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.
Done. Thanks for the reminder.
if (prepareSql) | ||
{ | ||
SqlClientDriver.SetVariableLengthParameterSize(dbParam, 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.
What do you think of this removal? It works but is in contradiction with documentation:
Before you call Prepare, specify the data type of each parameter in the statement to be prepared. For each parameter that has a variable-length data type, you must set the Size property to the maximum size needed. Prepare returns an error if these conditions are not met.
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.
It is strange that it works.
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.
I dislike it quite. But that is the simplest change to get it work... Otherwise I could move the code from SqlClientDriver
into Sql CE driver and adjust it to its needs, meaning removing 2008 stuff and not specifying blob sizes, but letting all the other been set, since it will be more compliant with doc and should work too.
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.
I don't think that SqlServer CE requires having all parameter sizes to be set when Prepare
is used.
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.
So we just keep that change as is. This PR could then be merged after dropping the first commit.
|
||
namespace NHibernate.Driver | ||
{ | ||
public class Sql2008ClientDriver : SqlClientDriver | ||
{ | ||
public const byte MaxTime = 5; |
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.
Why is this 5? It shall be either 7 or 8 (same as datetime2). Ok, it is size in bytes, represents the (16,7) precision
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.
Yes, the same for datetime2
and datetimeoffset
, where it wants to knows their size instead of their scale.
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.
About those MaxSizes
, I have put it public for mimicking what was done for others. But well, I do not think there is need for that. Maybe time to clean-up a bit the driver by switching back to protected those parameter sizing members.
d566954
to
224f25f
Compare
Although specifying parameters size is documented as mandatory when preparing statements, it appears it still works without.
The first commit dropped. |
prepare_sql requires all sizes/scales to be specified upfront.
This PR to be dropped if all tests are successful.