-
Notifications
You must be signed in to change notification settings - Fork 934
Add SQL Anywhere 17 support #1854
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
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.
Thanks for your contribution.
I have not yet checked all the tests with my local database instance, but so far this looks overall good. (At least I have used the same driver for my own tests some time ago, see 6aef609.)
/// </item> | ||
/// </list> | ||
/// </remarks> | ||
public class SybaseSQLAnywhere17Dialect : SybaseSQLAnywhere12Dialect |
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 seems to me the name Sybase is phased out. Shouldn't it be named SapSQLAnywhere17Dialect
?
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, that's correct! It should be renamed to Sap instead.
RegisterKeywords(); | ||
} | ||
|
||
new protected void RegisterKeywords() |
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.
SybaseSQLAnywhere12Dialect
implementation is not what we do usually. Maybe that is the right time to fix it: switch these methods (RegisterKeywords
and RegisterDateTimeTypeMappings
) to override
, calling their base implementation, and remove them from constructor call, both in SybaseSQLAnywhere12Dialect
and here. SybaseSQLAnywhere10Dialect
own constructor will call them, once switched to overrides.
@@ -0,0 +1,19 @@ | |||
namespace NHibernate.Driver | |||
{ | |||
public class SybaseSQLAnywhere17Driver : ReflectionBasedDriver |
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.
As for the dialect, it should likely be renamed SapSQLAnywhere17Driver
.
RegisterKeyword("limit"); | ||
RegisterKeyword("offset"); | ||
RegisterKeyword("datetimeoffset"); | ||
base.RegisterKeywords(); |
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, indeed these keywords were already registered in the base dialect. Better remove completely the override then.
{ | ||
RegisterColumnType(DbType.DateTimeOffset, "DATETIMEOFFSET"); | ||
base.RegisterDateTimeTypeMappings(); |
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.
Same here.
Numerous tests are failings, and I may directly push here some commits for fixing these tests failures, but of course feel free to fix some of them 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.
Here is a bunch of fixes. Not everything is fixed yet.
I have notably issues with queries selecting a string concatenation or a case
as a column result. They work fine in Interactive SQL, but for some reasons, the reader (SADataReader) try to convert such column to numeric (string concatenation case) or integer (case when
case), which fails. (Unless the result was by chance convertible to a number.)
I have posted here about this behavior, not finding any information.
@@ -29,7 +29,8 @@ protected override bool AppliesTo(Dialect.Dialect dialect) | |||
return !(dialect is FirebirdDialect) && | |||
!(dialect is Oracle8iDialect) && | |||
!(dialect is MsSqlCeDialect) && | |||
!(dialect is HanaDialectBase); | |||
!(dialect is HanaDialectBase) && | |||
!(dialect is SybaseSQLAnywhere10Dialect); |
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 batcher is not supported by SQL Anywhere. It seems it does not supports to have multiple inserts in the same query, as described here.
comp.Property(p => p.Name); | ||
comp.Property(p => p.Dob); | ||
comp.Property(p => p.Name, m => m.NotNullable(true)); | ||
comp.Property(p => p.Dob, m => m.NotNullable(true)); | ||
comp.Unique(true); // hbm2ddl: Generate a unique constraint in the database |
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 test does not need those columns to be nullable, so for avoiding troubles with database not supporting null in unique constraint, setting the columns as not nullable.
// SQL Anywhere does not respect usual priorities with the bitwise not. Unfortunately the HQL parser | ||
// furthermore remove "undue" parenthesis according to usual rules. As the bitwise not should have maximal | ||
// priority, we can work around this by using a template forcing parenthesis around it. | ||
RegisterFunction("bnot", new VarArgsSQLFunction(NHibernateUtil.Int64, "(~", "", ")")); |
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 is not a breaking change, because the function argument will by default be all that follows the ~
. But thanks to this change, if parenthesis are used to explicit the priority, they will be taken into account for supplying the "function" argument, instead of being silently removed by the parser.
if (limit == null && offset == null) | ||
throw new ArgumentException("Cannot limit with neither a limit nor an offset"); | ||
if (limit == null) | ||
throw new NotSupportedException($"Dialect {this} does not support setting an offset without a limit"); |
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 case was previously blowing with a null reference exception. Overriden in the 17 version since SQL Anywhere 12.0.1 (but not 12.0.0) has a syntax allowing the support of this case.
public SqlStringBuilder Add(SqlString sqlString) | ||
{ | ||
sqlString.Visit(AddingVisitor); | ||
sqlString?.Visit(AddingVisitor); |
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.
Additional change for avoiding blowing with a null reference exception when the sqlString
is null. The usual behavior for string builder being to do nothing on null, doing the same here.
@fredericDelaporte can we setup an automatic build for it? |
On the TeamCity agent, it should be doable. On AppVeyor or Travis, I do no think there is a reasonably lightweight way to set it up on each build. Update: it is maybe not possible for TeamCity too: there is no NuGet package as far as I know for the data provider, and I have not checked yet if its license could allow us to put it in NHibernate lib folder in Git. |
There is a Nuget package, but it is very likely to be unofficial. Looking at the license files available on my local setup, no redistribution is allowed for all components, including client ones. So I do not think we can legally put the data provider in the NHibernate lib folder. (The license allows a single installation for the developer and 25 internal deployments for testing purpose.) |
Have you considered installing provider to GAC? We can put a readme file to /lib/teamcity/sqlAnywhere. Explaining how to install the drivers. If it goes with a |
It does, and it is installed in GAC by the SQL Anywhere installer. Nothing to tell in lib/teamcity indeed. |
Now remain failures due to #1855 and #1859 bugs, and failures due to what seems to be a quite poor type inference done by the data-provider on projected columns, causing it to treat columns resulting from a |
It appears a hack similar to the one done on Firebird parameters in its driver could solve the bad type inference done by the data-provider on projected columns. This trouble seems to occurs only when the projection uses parameter values. And adding a cast around the parameter to explicit its type in the SQL solves the trouble. (At least in the tests here.) But I do not think it is worth it. Such a hack implies parsing with reg-ex each generated query, and tweaking it with "word replacements". It is brittle and may breaks some query cases not covered by NHibernate tests. |
I have setup a SAP SQL Anywhere TeamCity build. Its first almost successful build can be seen in 609f033 checks. 22 tests have failed. With c3597a3, only 14 failing tests should remain. Their fixes are in #1855 and #1859. Either I change them for being ignored, or this PR has to wait for these other PR merges. The Anywhere build is paused, and I am launching it manually. Enabling it would likely cause all other branches builds to fail, unless they get updated with 0545b45 changes. |
6b9b1c3
to
fca0feb
Compare
Rebased for resolving conflicts with latest merges, and test suite fixes squashed together. |
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.
LGTM
683d974
to
3eb4307
Compare
Rebased, Anywhere TeamCity build queued. |
And add the Teamcity build
3eb4307
to
06da1c9
Compare
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.
Now, the SQL Anywhere build succeeds.
About enabling the build on TeamCity, we should likely wait for having active PR updated first. |
@hazzik, do you agree for enabling the SAP SQL Anywhere build for all builds? I think it is time to have all PR targeting master at least up-to-date with 5.2. It will cause a failure for PR targeting older branches though. I do not see how to avoid that. (Excepted back-porting this PR here to the older branches, which I would rather avoid.) |
Added a SQL Anywhere 17 driver and SQL Anywhere 17 dialect.