Skip to content

Commit 33c1555

Browse files
Allow disabling Firebird driver parameter casting
The NHibernate Firebird driver does hack SQL commands for explicitly casting their parameters. This may cause issues in some cases, while, depending on the application, it may not be required. See #1886.
1 parent d01f8a8 commit 33c1555

File tree

6 files changed

+126
-0
lines changed

6 files changed

+126
-0
lines changed

doc/reference/modules/configuration.xml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,28 @@ var session = sessions.OpenSession(conn);
10091009
</para>
10101010
</entry>
10111011
</row>
1012+
<row>
1013+
<entry>
1014+
<literal>firebird.disable_parameter_casting</literal>
1015+
</entry>
1016+
<entry>
1017+
<para>
1018+
Firebird with FirebirdSql.Data.FirebirdClient may be unable to determine the type
1019+
of parameters in many circumstances, unless they are explicitly casted in the SQL
1020+
query. To avoid this trouble, the NHibernate <literal>FirebirdClientDriver</literal> parses SQL
1021+
commands for detecting parameters in them and adding an explicit SQL cast around
1022+
parameters which may trigger the issue.
1023+
</para>
1024+
<para>
1025+
Defaults to <literal>false</literal>.
1026+
For disabling this behavior, set this setting to true.
1027+
</para>
1028+
<para>
1029+
<emphasis role="strong">eg.</emphasis>
1030+
<literal>true</literal> | <literal>false</literal>
1031+
</para>
1032+
</entry>
1033+
</row>
10121034
<row>
10131035
<entry>
10141036
<literal>oracle.use_n_prefixed_types_for_unicode</literal>

src/NHibernate.Test/Async/DriverTest/FirebirdClientDriverFixture.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class FirebirdClientDriverFixtureAsync
2525
{
2626
private string _connectionString;
2727
private FirebirdClientDriver _driver;
28+
private FirebirdClientDriver _driverWithoutCasting;
2829

2930
[OneTimeSetUp]
3031
public void OneTimeSetup()
@@ -38,6 +39,10 @@ public void OneTimeSetup()
3839
_driver = new FirebirdClientDriver();
3940
_driver.Configure(cfg.Properties);
4041
_connectionString = cfg.GetProperty("connection.connection_string");
42+
43+
_driverWithoutCasting = new FirebirdClientDriver();
44+
cfg.SetProperty(Cfg.Environment.FirebirdDisableParameterCasting, "true");
45+
_driverWithoutCasting.Configure(cfg.Properties);
4146
}
4247

4348
[Test]

src/NHibernate.Test/DriverTest/FirebirdClientDriverFixture.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class FirebirdClientDriverFixture
1313
{
1414
private string _connectionString;
1515
private FirebirdClientDriver _driver;
16+
private FirebirdClientDriver _driverWithoutCasting;
1617

1718
[OneTimeSetUp]
1819
public void OneTimeSetup()
@@ -26,6 +27,10 @@ public void OneTimeSetup()
2627
_driver = new FirebirdClientDriver();
2728
_driver.Configure(cfg.Properties);
2829
_connectionString = cfg.GetProperty("connection.connection_string");
30+
31+
_driverWithoutCasting = new FirebirdClientDriver();
32+
cfg.SetProperty(Cfg.Environment.FirebirdDisableParameterCasting, "true");
33+
_driverWithoutCasting.Configure(cfg.Properties);
2934
}
3035

3136
[Test]
@@ -206,6 +211,66 @@ public void AdjustCommand_ParameterWithinIn_ParameterIsNotCasted()
206211
}
207212
}
208213

214+
[Test]
215+
public void AdjustCommand_StringParametersWithinConditionalSelect_NotCastedWhenDisabled()
216+
{
217+
using (var cmd = BuildSelectCaseCommand(SqlTypeFactory.GetString(255)))
218+
{
219+
var originalSql = cmd.CommandText;
220+
_driver.AdjustCommand(cmd);
221+
222+
Assert.That(cmd.CommandText, Is.EqualTo(originalSql));
223+
}
224+
}
225+
226+
[Test]
227+
public void AdjustCommand_IntParametersWithinConditionalSelect_NotCastedWhenDisabled()
228+
{
229+
using (var cmd = BuildSelectCaseCommand(SqlTypeFactory.Int32))
230+
{
231+
var originalSql = cmd.CommandText;
232+
_driver.AdjustCommand(cmd);
233+
234+
Assert.That(cmd.CommandText, Is.EqualTo(originalSql));
235+
}
236+
}
237+
238+
[Test]
239+
public void AdjustCommand_ParameterWithinSelectConcat_NotCastedWhenDisabled()
240+
{
241+
using (var cmd = BuildSelectConcatCommand(SqlTypeFactory.GetString(255)))
242+
{
243+
var originalSql = cmd.CommandText;
244+
_driver.AdjustCommand(cmd);
245+
246+
Assert.That(cmd.CommandText, Is.EqualTo(originalSql));
247+
}
248+
}
249+
250+
[Test]
251+
public void AdjustCommand_ParameterWithinSelectAddFunction_NotCastedWhenDisabled()
252+
{
253+
using (var cmd = BuildSelectAddCommand(SqlTypeFactory.GetString(255)))
254+
{
255+
var originalSql = cmd.CommandText;
256+
_driver.AdjustCommand(cmd);
257+
258+
Assert.That(cmd.CommandText, Is.EqualTo(originalSql));
259+
}
260+
}
261+
262+
[Test]
263+
public void AdjustCommand_InsertWithParamsInSelect_NotCastedWhenDisabled()
264+
{
265+
using (var cmd = BuildInsertWithParamsInSelectCommand(SqlTypeFactory.Int32))
266+
{
267+
var originalSql = cmd.CommandText;
268+
_driver.AdjustCommand(cmd);
269+
270+
Assert.That(cmd.CommandText, Is.EqualTo(originalSql));
271+
}
272+
}
273+
209274
private DbConnection MakeConnection()
210275
{
211276
var result = _driver.CreateConnection();

src/NHibernate/Cfg/Environment.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,20 @@ public static string Version
266266
/// </remarks>
267267
public const string OracleUseNPrefixedTypesForUnicode = "oracle.use_n_prefixed_types_for_unicode";
268268

269+
/// <summary>
270+
/// <para>
271+
/// Firebird with FirebirdSql.Data.FirebirdClient may be unable to determine the type
272+
/// of parameters in many circumstances, unless they are explicitly casted in the SQL
273+
/// query. To avoid this trouble, the NHibernate <c>FirebirdClientDriver</c> parses SQL
274+
/// commands for detecting parameters in them and adding an explicit SQL cast around
275+
/// parameters which may trigger the issue.
276+
/// </para>
277+
/// <para>
278+
/// For disabling this behavior, set this setting to true.
279+
/// </para>
280+
/// </summary>
281+
public const string FirebirdDisableParameterCasting = "firebird.disable_parameter_casting";
282+
269283
/// <summary>
270284
/// <para>Set whether tracking the session id or not. When <see langword="true"/>, each session
271285
/// will have an unique <see cref="Guid"/> that can be retrieved by <see cref="ISessionImplementor.SessionId"/>,

src/NHibernate/Driver/FirebirdClientDriver.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using NHibernate.SqlCommand;
1010
using NHibernate.SqlTypes;
1111
using NHibernate.Util;
12+
using Environment = NHibernate.Cfg.Environment;
1213

1314
namespace NHibernate.Driver
1415
{
@@ -40,6 +41,8 @@ public class FirebirdClientDriver : ReflectionBasedDriver
4041
private static readonly Regex _castCandidateRegEx = new Regex(CAST_PARAMS_EXP, RegexOptions.IgnoreCase);
4142
private readonly FirebirdDialect _fbDialect = new FirebirdDialect();
4243

44+
private bool _disableParameterCasting;
45+
4346
/// <summary>
4447
/// Initializes a new instance of the <see cref="FirebirdClientDriver"/> class.
4548
/// </summary>
@@ -59,6 +62,8 @@ public override void Configure(IDictionary<string, string> settings)
5962
{
6063
base.Configure(settings);
6164
_fbDialect.Configure(settings);
65+
66+
_disableParameterCasting = PropertiesHelper.GetBoolean(Environment.FirebirdDisableParameterCasting, settings);
6267
}
6368

6469
public override bool UseNamedPrefixInSql => true;
@@ -80,6 +85,9 @@ public override DbCommand GenerateCommand(CommandType type, SqlString sqlString,
8085
{
8186
var command = base.GenerateCommand(type, sqlString, parameterTypes);
8287

88+
if (_disableParameterCasting)
89+
return command;
90+
8391
var expWithParams = GetStatementsWithCastCandidates(command.CommandText);
8492
if (!string.IsNullOrWhiteSpace(expWithParams))
8593
{

src/NHibernate/nhibernate-configuration.xsd

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,18 @@
188188
</xs:documentation>
189189
</xs:annotation>
190190
</xs:enumeration>
191+
<xs:enumeration value="firebird.disable_parameter_casting">
192+
<xs:annotation>
193+
<xs:documentation>
194+
Firebird with FirebirdSql.Data.FirebirdClient may be unable to determine the type
195+
of parameters in many circumstances, unless they are explicitly casted in the SQL
196+
query. To avoid this trouble, the NHibernate FirebirdClientDriver parses SQL
197+
commands for detecting parameters in them and adding an explicit SQL cast around
198+
parameters which may trigger the issue.
199+
For disabling this behavior, set this setting to true.
200+
</xs:documentation>
201+
</xs:annotation>
202+
</xs:enumeration>
191203
<xs:enumeration value="sql_types.keep_datetime">
192204
<xs:annotation>
193205
<xs:documentation>

0 commit comments

Comments
 (0)