Skip to content

Commit 9527cb0

Browse files
fredericDelaportehazzik
authored andcommitted
NH-4063 - Fix ODBC failing tests.
1 parent ea51355 commit 9527cb0

File tree

24 files changed

+186
-18707
lines changed

24 files changed

+186
-18707
lines changed

lib/teamcity/sqlServerOdbc/NHibernate.Test.last-results.xml

Lines changed: 0 additions & 18677 deletions
This file was deleted.

src/NHibernate.Test/Hql/HQLFunctions.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ public void Cast()
625625
// 1) Has more then 1 argument
626626
// 2) The argument separator is "as" (for the other function is ',' or ' ')
627627
// 3) The ReturnType is not fixed (depend on a column type)
628-
// 4) The 2th argument is parsed by NH and traslated for a specific Dialect (can't be interpreted directly by RDBMS)
628+
// 4) The 2th argument is parsed by NH and translated for a specific Dialect (can't be interpreted directly by RDBMS)
629629
using (ISession s = OpenSession())
630630
{
631631
Animal a1 = new Animal("abcdef", 1.3f);
@@ -643,7 +643,7 @@ public void Cast()
643643
Assert.AreEqual(1, l.Count);
644644
Assert.That(l[0], Is.TypeOf(typeof (double)));
645645

646-
// Rendered in SELECT using a property in an operation with costant
646+
// Rendered in SELECT using a property in an operation with constants
647647
hql = "select cast(7+123-5*a.BodyWeight as Double) from Animal a";
648648
l = s.CreateQuery(hql).List();
649649
Assert.AreEqual(1, l.Count);
@@ -658,7 +658,7 @@ public void Cast()
658658
Assert.That(l[0], Is.TypeOf(typeof(double)));
659659
}
660660

661-
// TODO: Rendered in SELECT using string costant assigned with critic chars (separators)
661+
// TODO: Rendered in SELECT using string constant assigned with critic chars (separators)
662662

663663
// Rendered in WHERE using a property
664664
if (!(Dialect is Oracle8iDialect))
@@ -668,7 +668,7 @@ public void Cast()
668668
Assert.AreEqual("abcdef", result.Description);
669669
}
670670

671-
// Rendered in WHERE using a property in an operation with costants
671+
// Rendered in WHERE using a property in an operation with constants
672672
hql = "from Animal a where cast(7+123-2*a.BodyWeight as Double)>0";
673673
result = (Animal)s.CreateQuery(hql).UniqueResult();
674674
Assert.AreEqual("abcdef", result.Description);
@@ -694,7 +694,7 @@ public void Cast()
694694
Assert.AreEqual(1, l.Count);
695695
Assert.That(l[0], Is.TypeOf(typeof(double)));
696696

697-
// Rendered in GROUP BY using a property in an operation with costant
697+
// Rendered in GROUP BY using a property in an operation with constants
698698
hql = "select cast(7+123-5*a.BodyWeight as Double) from Animal a group by cast(7+123-5*a.BodyWeight as Double)";
699699
l = s.CreateQuery(hql).List();
700700
Assert.AreEqual(1, l.Count);
@@ -719,7 +719,7 @@ public void Cast()
719719
Assert.AreEqual(1, l.Count);
720720
Assert.That(l[0], Is.TypeOf(typeof(double)));
721721

722-
// Rendered in HAVING using a property in an operation with costants
722+
// Rendered in HAVING using a property in an operation with constants
723723
hql =
724724
"select cast(7+123.3-1*a.BodyWeight as int) from Animal a group by cast(7+123.3-1*a.BodyWeight as int) having cast(7+123.3-1*a.BodyWeight as int)>0";
725725
l = s.CreateQuery(hql).List();
@@ -742,6 +742,9 @@ public void Cast()
742742
}
743743
catch (ADOException ex)
744744
{
745+
if (ex.InnerException == null)
746+
throw;
747+
745748
if (Dialect is Oracle8iDialect)
746749
{
747750
if (!ex.InnerException.Message.StartsWith("ORA-00979"))
@@ -762,7 +765,7 @@ public void Cast()
762765
// This test raises an exception in SQL Server because named
763766
// parameters internally are always positional (@p0, @p1, etc.)
764767
// and named differently hence they mismatch between GROUP BY and HAVING clauses.
765-
if (!ex.InnerException.Message.Equals(msgToCheck))
768+
if (!ex.InnerException.Message.Contains(msgToCheck))
766769
throw;
767770
}
768771
}

src/NHibernate.Test/Insertordering/InsertOrderingFixture.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Linq;
77
using NHibernate.AdoNet;
88
using NHibernate.Cfg;
9+
using NHibernate.Dialect;
910
using NHibernate.Driver;
1011
using NHibernate.Engine;
1112
using NHibernate.SqlCommand;
@@ -33,7 +34,7 @@ protected override string MappingsAssembly
3334
protected override bool AppliesTo(Dialect.Dialect dialect)
3435
{
3536
// Custom batcher enforces sql server.
36-
return dialect.SupportsSqlBatches;
37+
return dialect is MsSql2000Dialect;
3738
}
3839

3940
protected override bool AppliesTo(ISessionFactoryImplementor factory)

src/NHibernate.Test/NHSpecificTest/NH1444/Fixture.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ protected override void Configure(Configuration configuration)
1111
{
1212
configuration.SetProperty(Environment.FormatSql, "false");
1313
}
14+
1415
[Test]
1516
public void Bug()
1617
{
@@ -23,8 +24,11 @@ public void Bug()
2324
.SetParameter("filternull", !filter.HasValue)
2425
.SetParameter("filterval", filter.HasValue ? filter.Value : 0).List<xchild>();
2526
var message = ls.GetWholeLog();
26-
string paramPrefix = ((DriverBase) Sfi.ConnectionProvider.Driver).NamedPrefix;
27-
Assert.That(message, Does.Contain("xchild0_.ParentId=xparent1_.Id and (" + paramPrefix + "p0=" + Dialect.ToBooleanValueString(true) + " or xparent1_.A<" + paramPrefix + "p1)"));
27+
var paramFormatter = (ISqlParameterFormatter)Sfi.ConnectionProvider.Driver;
28+
Assert.That(message, Does.Contain(
29+
"xchild0_.ParentId=xparent1_.Id and (" +
30+
$"{paramFormatter.GetParameterName(0)}={Dialect.ToBooleanValueString(true)} or " +
31+
$"xparent1_.A<{paramFormatter.GetParameterName(1)})"));
2832
}
2933
}
3034
}

src/NHibernate.Test/NHSpecificTest/NH1553/MsSQL/SnapshotIsolationUpdateConflictTest.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System.Data;
22
using NHibernate.Cfg;
33
using NHibernate.Dialect;
4+
using NHibernate.Driver;
5+
using NHibernate.Engine;
46
using NUnit.Framework;
57
using NUnit.Framework.Constraints;
68

@@ -125,6 +127,13 @@ protected override bool AppliesTo(Dialect.Dialect dialect)
125127
return dialect is MsSql2005Dialect;
126128
}
127129

130+
protected override bool AppliesTo(ISessionFactoryImplementor factory)
131+
{
132+
// SQLUpdateConflictToStaleStateExceptionConverter is specific to Sql client driver, and does not work
133+
// with Odbc (and likeley Oledb).
134+
return factory.ConnectionProvider.Driver is SqlClientDriver;
135+
}
136+
128137
private void SetAllowSnapshotIsolation(bool on)
129138
{
130139
using (ISession session = OpenSession())

src/NHibernate.Test/NHSpecificTest/NH1756/Fixture.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System.Collections.Generic;
22
using NHibernate.Dialect;
3+
using NHibernate.Driver;
4+
using NHibernate.Engine;
35
using NUnit.Framework;
46

57
namespace NHibernate.Test.NHSpecificTest.NH1756
@@ -12,6 +14,25 @@ protected override bool AppliesTo(Dialect.Dialect dialect)
1214
return dialect is MsSql2000Dialect;
1315
}
1416

17+
protected override bool AppliesTo(ISessionFactoryImplementor factory)
18+
{
19+
// ODBC driver DateTime handling with SQL Server 2008+ Client is broken and forbids using it as a time stamp
20+
// generated on db-side.
21+
// Due to NH-3895, we have to force the scale on date-time parameters to 3 (3 significant fractional seconds digits)
22+
// when using ODBC + SQL Server 2008+, otherwise DateTime values having milliseconds will be rejected. But the SQL
23+
// Server DateTime does not have actually a one millisecond resolution (it has 3.333), causing ODBC to convert the
24+
// parameter to DateTime2. A DateTime value ending by 3ms (indeed 3.333) or 7ms (indeed 6.666) is
25+
// to be transmitted as having 3ms or 7ms and will match if transmitted as a DateTime. But when transmitted as
26+
// DateTime2, it will no more be considered equal, causing the test to be flaky and failing two thirds of tries.
27+
// Example failing update captured with profiler:
28+
// exec sp_executesql N'UPDATE book SET name_column = @P1 WHERE id = @P2 AND version_column = @P3',
29+
// N'@P1 nvarchar(18),@P2 int,@P3 datetime2',N'modified test book',1,'2017-08-02 16:37:16.0630000'
30+
// Setting the scale to 2 still causes failure for two thirds of tries, due to 3ms/7ms being truncated in such case
31+
// with ODBC and SQL Server 2008+ Client, which is rejected bu ODBC.
32+
// (Affects DbVersionFixture too.)
33+
return !(factory.ConnectionProvider.Driver is OdbcDriver);
34+
}
35+
1536
[Test]
1637
public void SaveTransient_Then_Update_Ok()
1738
{

src/NHibernate.Test/NHSpecificTest/NH1850/Fixture.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ namespace NHibernate.Test.NHSpecificTest.NH1850
44
{
55
using System;
66
using AdoNet;
7-
using Environment=NHibernate.Cfg.Environment;
7+
using NHibernate.Engine;
8+
using Environment = NHibernate.Cfg.Environment;
89

910
[TestFixture]
1011
public class Fixture:BugTestCase
@@ -14,9 +15,18 @@ protected override void Configure(NHibernate.Cfg.Configuration configuration)
1415
configuration.SetProperty(Environment.BatchSize, "1");
1516
}
1617

17-
protected override bool AppliesTo(Dialect.Dialect dialect)
18+
protected override bool AppliesTo(ISessionFactoryImplementor factory)
1819
{
19-
return dialect.SupportsSqlBatches;
20+
// This test heavily depends on the batcher implementation.
21+
// The MySql one likely does not issue the expected logs, but is in fact unused
22+
// (driver does not supply it, it needs to be explicitly configured).
23+
// The Oracle one logs twice, causing the expected count to not match.
24+
// The non batching one just does one single log instead of many.
25+
// (This test has never test anything else than SQL Server because it was previously
26+
// applied according to dialect.SupportsSqlBatches which is utterly unrelated to
27+
// the batcher and just tell about "GO" SQL Server Client tools convention. This was
28+
// causing it to fail with ODBC + SQL Server, since ODBC uses the non batching batcher.)
29+
return factory.Settings.BatcherFactory is SqlClientBatchingBatcherFactory;
2030
}
2131

2232
[Test]

src/NHibernate.Test/NHSpecificTest/NH1981/Fixture.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using NHibernate.Driver;
2+
using NHibernate.Engine;
13
using NUnit.Framework;
24

35
namespace NHibernate.Test.NHSpecificTest.NH1981
@@ -11,6 +13,13 @@ protected override bool AppliesTo(Dialect.Dialect dialect)
1113
return !(dialect is Dialect.FirebirdDialect);
1214
}
1315

16+
protected override bool AppliesTo(ISessionFactoryImplementor factory)
17+
{
18+
// When not using a named prefix, the driver use positional parameters, causing parameterized
19+
// expression used in group by and select to be not be considered as the same expression.
20+
return ((DriverBase)factory.ConnectionProvider.Driver).UseNamedPrefixInParameter;
21+
}
22+
1423
protected override void OnSetUp()
1524
{
1625
using (var s = OpenSession())

src/NHibernate.Test/NHSpecificTest/NH2020/Fixture.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using NUnit.Framework;
22
using NHibernate.Dialect;
3+
using NHibernate.Driver;
34
using NHibernate.Exceptions;
45
using NHibernate.Test.ExceptionsTest;
6+
using NHibernate.Engine;
57

68
namespace NHibernate.Test.NHSpecificTest.NH2020
79
{
@@ -21,6 +23,12 @@ protected override bool AppliesTo(NHibernate.Dialect.Dialect dialect)
2123
return dialect is MsSql2000Dialect;
2224
}
2325

26+
protected override bool AppliesTo(ISessionFactoryImplementor factory)
27+
{
28+
// Use a SQL Server Client exception converter, cannot work for ODBC or OleDb
29+
return factory.ConnectionProvider.Driver is SqlClientDriver;
30+
}
31+
2432
protected override void OnTearDown()
2533
{
2634
using (ISession s = OpenSession())
Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Threading;
32
using System.Transactions;
4-
using NHibernate.Impl;
53
using NUnit.Framework;
6-
using NHibernate.Criterion;
74

85
namespace NHibernate.Test.NHSpecificTest.NH2057
96
{
107
[TestFixture]
118
public class Fixture : BugTestCase
129
{
1310
[Test]
14-
[Description("This test fails intermittently on SQL Server ODBC. Not sure why.")]
1511
public void WillCloseWhenUsingDTC()
1612
{
17-
SessionImpl s;
13+
ISession s;
1814
using (var tx = new TransactionScope())
1915
{
20-
using (s = (SessionImpl)OpenSession())
16+
using (s = OpenSession())
2117
{
2218
s.Get<Person>(1);
2319
}
2420
//not closed because the tx is opened yet
25-
Assert.False(s.IsClosed);
21+
Assert.That(s.IsOpen, Is.True);
2622
tx.Complete();
2723
}
28-
Assert.That(s.IsClosed, Is.True);
24+
// ODBC does promote to distributed, causing the completion to happen concurrently to code
25+
// following scope disposal. Sleep a bit for accounting for this.
26+
Assert.That(() => s.IsOpen, Is.False.After(500, 100));
2927
}
3028
}
3129
}

src/NHibernate.Test/NHSpecificTest/NH2167/Fixture.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using NHibernate.Cfg.MappingSchema;
22
using NHibernate.Criterion;
33
using NHibernate.Dialect;
4+
using NHibernate.Driver;
5+
using NHibernate.Engine;
46
using NHibernate.Mapping.ByCode;
57
using NUnit.Framework;
68

@@ -13,6 +15,13 @@ protected override bool AppliesTo(Dialect.Dialect dialect)
1315
return !(dialect is FirebirdDialect);
1416
}
1517

18+
protected override bool AppliesTo(ISessionFactoryImplementor factory)
19+
{
20+
// When not using a named prefix, the driver use positional parameters, causing parameterized
21+
// expression used in group by and select to be not be considered as the same expression.
22+
return ((DriverBase)factory.ConnectionProvider.Driver).UseNamedPrefixInParameter;
23+
}
24+
1625
protected override HbmMapping GetMappings()
1726
{
1827
var mapper = new ModelMapper();

src/NHibernate.Test/NHSpecificTest/NH2302/Fixture.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Data;
22
using NHibernate.Dialect;
3+
using NHibernate.Driver;
34
using NHibernate.Mapping;
45
using NUnit.Framework;
56

@@ -37,6 +38,9 @@ protected override void OnTearDown()
3738
[Test]
3839
public void StringHugeLength()
3940
{
41+
if (Sfi.ConnectionProvider.Driver is OdbcDriver)
42+
Assert.Ignore("NH-4065, not fixed for Odbc");
43+
4044
int id;
4145
// buildup a string the exceed the mapping
4246
string str = GetFixedLengthString12000();

src/NHibernate.Test/NHSpecificTest/NH3405/Fixture.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using NHibernate.Cfg;
55
using NHibernate.Cfg.MappingSchema;
66
using NHibernate.Dialect;
7+
using NHibernate.Driver;
8+
using NHibernate.Engine;
79
using NHibernate.Linq;
810
using NHibernate.Mapping.ByCode;
911
using NHibernate.Type;
@@ -29,6 +31,12 @@ protected override bool AppliesTo(Dialect.Dialect dialect)
2931
return dialect is MsSql2005Dialect;
3032
}
3133

34+
protected override bool AppliesTo(ISessionFactoryImplementor factory)
35+
{
36+
// No Xml support with Odbc (and likely OleDb too).
37+
return factory.ConnectionProvider.Driver is SqlClientDriver;
38+
}
39+
3240
protected override HbmMapping GetMappings()
3341
{
3442
var mapper = new ModelMapper();

src/NHibernate.Test/NHSpecificTest/NH3609/Fixture.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using NHibernate.Criterion;
22
using NHibernate.Dialect;
3+
using NHibernate.Driver;
34
using NHibernate.Transform;
45
using NUnit.Framework;
56

@@ -85,6 +86,10 @@ public void GroupByClauseHasParameterSet()
8586
{
8687
if (Dialect is FirebirdDialect)
8788
Assert.Ignore("Firebird does not support complex group by expressions");
89+
// When not using a named prefix, the driver use positional parameters, causing parameterized
90+
// expression used in group by and select to be not be considered as the same expression.
91+
if (!((DriverBase)Sfi.ConnectionProvider.Driver).UseNamedPrefixInParameter)
92+
Assert.Ignore("Cannot group by and select a parameterized expression with positional parameters");
8893

8994
using (var session = OpenSession())
9095
using (session.BeginTransaction())

src/NHibernate.Test/NHSpecificTest/NH392/Fixture.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ protected override void OnTearDown()
3939
{
4040
using (ISession s = Sfi.OpenSession())
4141
{
42-
s.Delete("from UnsavedValueMinusOne");
43-
s.Flush();
42+
// s.Delete("from UnsavedValueMinusOne") loads then delete entities one by one, checking the version.
43+
// This fails with ODBC & Sql Server 2008+, see NH-1756 test case or DbVersionFixture for more details.
44+
// Use an in-db query instead.
45+
s.CreateQuery("delete from UnsavedValueMinusOne").ExecuteUpdate();
4446
}
4547
}
4648
}

src/NHibernate.Test/Pagination/CustomDialectFixture.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
using System.Collections.Generic;
33
using NHibernate.Cfg;
44
using NHibernate.Criterion;
5+
using NHibernate.Dialect;
6+
using NHibernate.Driver;
7+
using NHibernate.Util;
58
using NUnit.Framework;
69
using Environment = NHibernate.Cfg.Environment;
710

@@ -22,8 +25,12 @@ protected override IList Mappings
2225

2326
protected override void Configure(Configuration configuration)
2427
{
25-
if (!(Dialect is Dialect.MsSql2005Dialect))
28+
// Configure is called before Applies, must check here.
29+
if (!(Dialect is MsSql2005Dialect))
2630
Assert.Ignore("Test is for SQL dialect only");
31+
var driverClass = ReflectHelper.ClassForName(cfg.GetProperty(Environment.ConnectionDriver));
32+
if (!typeof(SqlClientDriver).IsAssignableFrom(driverClass))
33+
Assert.Ignore("Test is compatible only with Sql Server Client driver connection strings");
2734

2835
cfg.SetProperty(Environment.Dialect, typeof(CustomMsSqlDialect).AssemblyQualifiedName);
2936
cfg.SetProperty(Environment.ConnectionDriver, typeof(CustomMsSqlDriver).AssemblyQualifiedName);

0 commit comments

Comments
 (0)