Skip to content

Commit 978e492

Browse files
fixup !NH-4088 - Fix GetCastTypeName
* Oracle double special case * More tests * Tests fixes
1 parent bbd7772 commit 978e492

File tree

5 files changed

+125
-110
lines changed

5 files changed

+125
-110
lines changed

src/NHibernate.Test/Criteria/ProjectionsTest.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using NHibernate.Criterion;
55
using NHibernate.Dialect;
6+
using NHibernate.SqlTypes;
67
using NHibernate.Type;
78
using NUnit.Framework;
89

@@ -94,6 +95,11 @@ public void UsingSqlFunctions_Concat_WithCast()
9495
[Test]
9596
public void CastWithLength()
9697
{
98+
if (!Dialect.GetCastTypeName(SqlTypeFactory.GetString(3)).Contains("3"))
99+
{
100+
Assert.Ignore($"Dialect {Dialect} does not seem to handle string length in cast");
101+
}
102+
97103
using (var s = OpenSession())
98104
{
99105
try
@@ -109,8 +115,7 @@ public void CastWithLength()
109115
}
110116
catch (Exception e)
111117
{
112-
if (!e.Message.Contains("truncation") &&
113-
(e.InnerException == null || !e.InnerException.Message.Contains("truncation")))
118+
if (e.InnerException == null || !e.InnerException.Message.Contains("truncation"))
114119
throw;
115120
}
116121
}

src/NHibernate.Test/DialectTest/DialectFixture.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ public void GetDecimalTypeName()
178178
var dialect = Dialect.Dialect.GetDialect(cfg.Properties);
179179

180180
Assert.That(dialect.GetTypeName(SqlTypeFactory.GetSqlType(DbType.Decimal, 40, 40)), Does.Not.Contain("40"), "oversized decimal");
181+
// This regex test wether the type is qualified with expected length/precision/scale or not qualified at all.
181182
Assert.That(dialect.GetTypeName(SqlTypeFactory.GetSqlType(DbType.Decimal, 3, 2)), Does.Match(@"^[^(]*(\(\s*3\s*,\s*2\s*\))?\s*$"), "small decimal");
182183
}
183184

@@ -190,8 +191,11 @@ public void GetTypeCastName()
190191
cfg.SetProperty(Environment.QueryDefaultCastScale, "3");
191192
var dialect = Dialect.Dialect.GetDialect(cfg.Properties);
192193

194+
// Those regex test wether the type is qualified with expected length/precision/scale or not qualified at all.
193195
Assert.That(dialect.GetCastTypeName(SqlTypeFactory.Decimal), Does.Match(@"^[^(]*(\(\s*10\s*,\s*3\s*\))?\s*$"), "decimal");
196+
Assert.That(dialect.GetCastTypeName(SqlTypeFactory.GetSqlType(DbType.Decimal, 12, 4)), Does.Match(@"^[^(]*(\(\s*12\s*,\s*4\s*\))?\s*$"), "decimal(12,4)");
194197
Assert.That(dialect.GetCastTypeName(new SqlType(DbType.String)), Does.Match(@"^[^(]*(\(\s*20\s*\))?\s*$"), "string");
198+
Assert.That(dialect.GetCastTypeName(SqlTypeFactory.GetString(25)), Does.Match(@"^[^(]*(\(\s*25\s*\))?\s*$"), "string(25)");
195199
}
196200
}
197201
}

src/NHibernate.Test/DriverTest/FirebirdClientDriverFixture.cs

Lines changed: 110 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -14,157 +14,160 @@ public class FirebirdClientDriverFixture
1414
private string _connectionString;
1515
private FirebirdClientDriver _driver;
1616

17+
[OneTimeSetUp]
18+
public void OneTimeSetup()
19+
{
20+
var cfg = TestConfigurationHelper.GetDefaultConfiguration();
21+
22+
var dlct = cfg.GetProperty("dialect");
23+
if (!dlct.Contains("Firebird"))
24+
Assert.Ignore("Applies only to Firebird");
25+
26+
_driver = new FirebirdClientDriver();
27+
_driver.Configure(cfg.Properties);
28+
_connectionString = cfg.GetProperty("connection.connection_string");
29+
}
30+
1731
[Test]
1832
public void ConnectionPooling_OpenThenCloseThenOpenAnotherOne_OnlyOneConnectionIsPooled()
1933
{
20-
MakeDriver();
21-
2234
_driver.ClearPool(_connectionString);
2335

2436
var allreadyEstablished = GetEstablishedConnections();
2537

26-
var connection1 = MakeConnection();
27-
var connection2 = MakeConnection();
28-
29-
//open first connection
30-
connection1.Open();
31-
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After first open");
38+
using (var connection1 = MakeConnection())
39+
using (var connection2 = MakeConnection())
40+
{
41+
//open first connection
42+
connection1.Open();
43+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After first open");
3244

33-
//return it to the pool
34-
connection1.Close();
35-
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After first close");
45+
//return it to the pool
46+
connection1.Close();
47+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After first close");
3648

37-
//open the second connection
38-
connection2.Open();
39-
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After second open");
49+
//open the second connection
50+
connection2.Open();
51+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After second open");
4052

41-
//return it to the pool
42-
connection2.Close();
43-
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After second close");
53+
//return it to the pool
54+
connection2.Close();
55+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After second close");
56+
}
4457
}
4558

4659
[Test]
4760
public void ConnectionPooling_OpenThenCloseTwoAtTheSameTime_TowConnectionsArePooled()
4861
{
49-
MakeDriver();
50-
5162
_driver.ClearPool(_connectionString);
5263

5364
var allreadyEstablished = GetEstablishedConnections();
5465

55-
var connection1 = MakeConnection();
56-
var connection2 = MakeConnection();
57-
58-
//open first connection
59-
connection1.Open();
60-
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After first open");
66+
using (var connection1 = MakeConnection())
67+
using (var connection2 = MakeConnection())
68+
{
69+
//open first connection
70+
connection1.Open();
71+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 1, "After first open");
6172

62-
//open second one
63-
connection2.Open();
64-
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 2, "After second open");
73+
//open second one
74+
connection2.Open();
75+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 2, "After second open");
6576

66-
//return connection1 to the pool
67-
connection1.Close();
68-
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 2, "After first close");
77+
//return connection1 to the pool
78+
connection1.Close();
79+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 2, "After first close");
6980

70-
//return connection2 to the pool
71-
connection2.Close();
72-
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 2, "After second close");
81+
//return connection2 to the pool
82+
connection2.Close();
83+
VerifyCountOfEstablishedConnectionsIs(allreadyEstablished + 2, "After second close");
84+
}
7385
}
7486

7587
[Test]
7688
public void AdjustCommand_StringParametersWithinConditionalSelect_ThenParameterIsWrappedByAVarcharCastStatement()
7789
{
78-
MakeDriver();
79-
var cmd = BuildSelectCaseCommand(SqlTypeFactory.GetString(255));
80-
81-
_driver.AdjustCommand(cmd);
90+
using (var cmd = BuildSelectCaseCommand(SqlTypeFactory.GetString(255)))
91+
{
92+
_driver.AdjustCommand(cmd);
8293

83-
var expectedCommandTxt = "select (case when col = @p0 then cast(@p1 as VARCHAR(255)) else cast(@p2 as VARCHAR(255)) end) from table";
84-
Assert.That(cmd.CommandText, Is.EqualTo(expectedCommandTxt));
94+
var expectedCommandTxt =
95+
"select (case when col = @p0 then cast(@p1 as VARCHAR(4000)) else cast(@p2 as VARCHAR(4000)) end) from table";
96+
Assert.That(cmd.CommandText, Is.EqualTo(expectedCommandTxt));
97+
}
8598
}
8699

87100
[Test]
88101
public void AdjustCommand_IntParametersWithinConditionalSelect_ThenParameterIsWrappedByAnIntCastStatement()
89102
{
90-
MakeDriver();
91-
var cmd = BuildSelectCaseCommand(SqlTypeFactory.Int32);
92-
93-
_driver.AdjustCommand(cmd);
103+
using (var cmd = BuildSelectCaseCommand(SqlTypeFactory.Int32))
104+
{
105+
_driver.AdjustCommand(cmd);
94106

95-
var expectedCommandTxt = "select (case when col = @p0 then cast(@p1 as INTEGER) else cast(@p2 as INTEGER) end) from table";
96-
Assert.That(cmd.CommandText, Is.EqualTo(expectedCommandTxt));
107+
var expectedCommandTxt =
108+
"select (case when col = @p0 then cast(@p1 as INTEGER) else cast(@p2 as INTEGER) end) from table";
109+
Assert.That(cmd.CommandText, Is.EqualTo(expectedCommandTxt));
110+
}
97111
}
98112

99113
[Test]
100114
public void AdjustCommand_ParameterWithinSelectConcat_ParameterIsCasted()
101115
{
102-
MakeDriver();
103-
var cmd = BuildSelectConcatCommand(SqlTypeFactory.GetString(255));
104-
105-
_driver.AdjustCommand(cmd);
116+
using (var cmd = BuildSelectConcatCommand(SqlTypeFactory.GetString(255)))
117+
{
118+
_driver.AdjustCommand(cmd);
106119

107-
var expected = "select col || cast(@p0 as VARCHAR(255)) || col from table";
108-
Assert.That(cmd.CommandText, Is.EqualTo(expected));
120+
var expected = "select col || cast(@p0 as VARCHAR(4000)) || col from table";
121+
Assert.That(cmd.CommandText, Is.EqualTo(expected));
122+
}
109123
}
110124

111125
[Test]
112126
public void AdjustCommand_ParameterWithinSelectAddFunction_ParameterIsCasted()
113127
{
114-
MakeDriver();
115-
var cmd = BuildSelectAddCommand(SqlTypeFactory.GetString(255));
116-
117-
_driver.AdjustCommand(cmd);
128+
using (var cmd = BuildSelectAddCommand(SqlTypeFactory.GetString(255)))
129+
{
130+
_driver.AdjustCommand(cmd);
118131

119-
var expected = "select col + cast(@p0 as VARCHAR(255)) from table";
120-
Assert.That(cmd.CommandText, Is.EqualTo(expected));
132+
var expected = "select col + cast(@p0 as VARCHAR(4000)) from table";
133+
Assert.That(cmd.CommandText, Is.EqualTo(expected));
134+
}
121135
}
122136

123137
[Test]
124138
public void AdjustCommand_InsertWithParamsInSelect_ParameterIsCasted()
125139
{
126-
MakeDriver();
127-
var cmd = BuildInsertWithParamsInSelectCommand(SqlTypeFactory.Int32);
128-
129-
_driver.AdjustCommand(cmd);
140+
using (var cmd = BuildInsertWithParamsInSelectCommand(SqlTypeFactory.Int32))
141+
{
142+
_driver.AdjustCommand(cmd);
130143

131-
var expected = "insert into table1 (col1, col2) select col1, cast(@p0 as INTEGER) from table2";
132-
Assert.That(cmd.CommandText, Is.EqualTo(expected));
144+
var expected = "insert into table1 (col1, col2) select col1, cast(@p0 as INTEGER) from table2";
145+
Assert.That(cmd.CommandText, Is.EqualTo(expected));
146+
}
133147
}
134148

135149
[Test]
136150
public void AdjustCommand_InsertWithParamsInSelect_ParameterIsNotCasted_WhenColumnNameContainsSelect()
137151
{
138-
MakeDriver();
139-
var cmd = BuildInsertWithParamsInSelectCommandWithSelectInColumnName(SqlTypeFactory.Int32);
140-
141-
_driver.AdjustCommand(cmd);
152+
using (var cmd = BuildInsertWithParamsInSelectCommandWithSelectInColumnName(SqlTypeFactory.Int32))
153+
{
154+
_driver.AdjustCommand(cmd);
142155

143-
var expected = "insert into table1 (col1_select_aaa) values(@p0) from table2";
144-
Assert.That(cmd.CommandText, Is.EqualTo(expected));
156+
var expected = "insert into table1 (col1_select_aaa) values(@p0) from table2";
157+
Assert.That(cmd.CommandText, Is.EqualTo(expected));
158+
}
145159
}
146160

147161
[Test]
148162
public void AdjustCommand_InsertWithParamsInSelect_ParameterIsNotCasted_WhenColumnNameContainsWhere()
149163
{
150-
MakeDriver();
151-
var cmd = BuildInsertWithParamsInSelectCommandWithWhereInColumnName(SqlTypeFactory.Int32);
152-
153-
_driver.AdjustCommand(cmd);
154-
155-
var expected = "insert into table1 (col1_where_aaa) values(@p0) from table2";
156-
Assert.That(cmd.CommandText, Is.EqualTo(expected));
157-
}
158-
159-
private void MakeDriver()
160-
{
161-
var cfg = TestConfigurationHelper.GetDefaultConfiguration();
162-
var dlct = cfg.GetProperty("dialect");
163-
if (!dlct.Contains("Firebird"))
164-
Assert.Ignore("Applies only to Firebird");
164+
using (var cmd = BuildInsertWithParamsInSelectCommandWithWhereInColumnName(SqlTypeFactory.Int32))
165+
{
166+
_driver.AdjustCommand(cmd);
165167

166-
_driver = new FirebirdClientDriver();
167-
_connectionString = cfg.GetProperty("connection.connection_string");
168+
var expected = "insert into table1 (col1_where_aaa) values(@p0) from table2";
169+
Assert.That(cmd.CommandText, Is.EqualTo(expected));
170+
}
168171
}
169172

170173
private DbConnection MakeConnection()
@@ -197,38 +200,38 @@ private int GetEstablishedConnections()
197200
private DbCommand BuildSelectCaseCommand(SqlType paramType)
198201
{
199202
var sqlString = new SqlStringBuilder()
200-
.Add("select (case when col = ")
201-
.AddParameter()
202-
.Add(" then ")
203-
.AddParameter()
204-
.Add(" else ")
205-
.AddParameter()
206-
.Add(" end) from table")
207-
.ToSqlString();
203+
.Add("select (case when col = ")
204+
.AddParameter()
205+
.Add(" then ")
206+
.AddParameter()
207+
.Add(" else ")
208+
.AddParameter()
209+
.Add(" end) from table")
210+
.ToSqlString();
208211

209212
return _driver.GenerateCommand(CommandType.Text, sqlString, new[] { paramType, paramType, paramType });
210213
}
211214

212215
private DbCommand BuildSelectConcatCommand(SqlType paramType)
213216
{
214217
var sqlString = new SqlStringBuilder()
215-
.Add("select col || ")
216-
.AddParameter()
217-
.Add(" || ")
218-
.Add("col ")
219-
.Add("from table")
220-
.ToSqlString();
218+
.Add("select col || ")
219+
.AddParameter()
220+
.Add(" || ")
221+
.Add("col ")
222+
.Add("from table")
223+
.ToSqlString();
221224

222225
return _driver.GenerateCommand(CommandType.Text, sqlString, new[] { paramType });
223226
}
224227

225228
private DbCommand BuildSelectAddCommand(SqlType paramType)
226229
{
227230
var sqlString = new SqlStringBuilder()
228-
.Add("select col + ")
229-
.AddParameter()
230-
.Add(" from table")
231-
.ToSqlString();
231+
.Add("select col + ")
232+
.AddParameter()
233+
.Add(" from table")
234+
.ToSqlString();
232235

233236
return _driver.GenerateCommand(CommandType.Text, sqlString, new[] { paramType });
234237
}
@@ -244,6 +247,7 @@ private DbCommand BuildInsertWithParamsInSelectCommand(SqlType paramType)
244247

245248
return _driver.GenerateCommand(CommandType.Text, sqlString, new[] { paramType });
246249
}
250+
247251
private DbCommand BuildInsertWithParamsInSelectCommandWithSelectInColumnName(SqlType paramType)
248252
{
249253
var sqlString = new SqlStringBuilder()
@@ -256,7 +260,7 @@ private DbCommand BuildInsertWithParamsInSelectCommandWithSelectInColumnName(Sql
256260
return _driver.GenerateCommand(CommandType.Text, sqlString, new[] { paramType });
257261
}
258262

259-
private DbCommand BuildInsertWithParamsInSelectCommandWithWhereInColumnName(SqlType paramType)
263+
private DbCommand BuildInsertWithParamsInSelectCommandWithWhereInColumnName(SqlType paramType)
260264
{
261265
var sqlString = new SqlStringBuilder()
262266
.Add("insert into table1 (col1_where_aaa) ")

src/NHibernate/Dialect/Dialect.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,11 @@ protected virtual string GetCastTypeName(SqlType sqlType, TypeNames castTypeName
275275
switch (sqlType.DbType)
276276
{
277277
case DbType.Decimal:
278+
// Oracle dialect defines precision and scale for double, because it uses number instead of binary_double.
279+
case DbType.Double:
278280
// We cannot know if the user needs its digit after or before the dot, so use a configurable
279281
// default.
280-
return castTypeNames.Get(DbType.Decimal, 0, DefaultCastPrecision, DefaultCastScale);
282+
return castTypeNames.Get(sqlType.DbType, 0, DefaultCastPrecision, DefaultCastScale);
281283
case DbType.DateTime:
282284
case DbType.DateTime2:
283285
case DbType.DateTimeOffset:

src/NHibernate/Dialect/SybaseSQLAnywhere10Dialect.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ protected virtual void RegisterNumericTypeMappings()
9292
RegisterColumnType(DbType.Double, "DOUBLE");
9393
RegisterColumnType(DbType.Decimal, "NUMERIC(19,5)"); // Precision ranges from 0-127
9494
// Anywhere max precision is 127, but .Net is limited to 28-29.
95-
RegisterColumnType(DbType.Decimal, 38, "NUMERIC($p, $s)"); // Precision ranges from 0-127
95+
RegisterColumnType(DbType.Decimal, 28, "NUMERIC($p, $s)"); // Precision ranges from 0-127
9696
}
9797

9898
protected virtual void RegisterDateTimeTypeMappings()

0 commit comments

Comments
 (0)