Skip to content

Commit 16fabdf

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 b1b4fd9 commit 16fabdf

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]
@@ -170,6 +175,66 @@ public void AdjustCommand_InsertWithParamsInSelect_ParameterIsNotCasted_WhenColu
170175
}
171176
}
172177

178+
[Test]
179+
public void AdjustCommand_StringParametersWithinConditionalSelect_NotCastedWhenDisabled()
180+
{
181+
using (var cmd = BuildSelectCaseCommand(SqlTypeFactory.GetString(255)))
182+
{
183+
var originalSql = cmd.CommandText;
184+
_driver.AdjustCommand(cmd);
185+
186+
Assert.That(cmd.CommandText, Is.EqualTo(originalSql));
187+
}
188+
}
189+
190+
[Test]
191+
public void AdjustCommand_IntParametersWithinConditionalSelect_NotCastedWhenDisabled()
192+
{
193+
using (var cmd = BuildSelectCaseCommand(SqlTypeFactory.Int32))
194+
{
195+
var originalSql = cmd.CommandText;
196+
_driver.AdjustCommand(cmd);
197+
198+
Assert.That(cmd.CommandText, Is.EqualTo(originalSql));
199+
}
200+
}
201+
202+
[Test]
203+
public void AdjustCommand_ParameterWithinSelectConcat_NotCastedWhenDisabled()
204+
{
205+
using (var cmd = BuildSelectConcatCommand(SqlTypeFactory.GetString(255)))
206+
{
207+
var originalSql = cmd.CommandText;
208+
_driver.AdjustCommand(cmd);
209+
210+
Assert.That(cmd.CommandText, Is.EqualTo(originalSql));
211+
}
212+
}
213+
214+
[Test]
215+
public void AdjustCommand_ParameterWithinSelectAddFunction_NotCastedWhenDisabled()
216+
{
217+
using (var cmd = BuildSelectAddCommand(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_InsertWithParamsInSelect_NotCastedWhenDisabled()
228+
{
229+
using (var cmd = BuildInsertWithParamsInSelectCommand(SqlTypeFactory.Int32))
230+
{
231+
var originalSql = cmd.CommandText;
232+
_driver.AdjustCommand(cmd);
233+
234+
Assert.That(cmd.CommandText, Is.EqualTo(originalSql));
235+
}
236+
}
237+
173238
private DbConnection MakeConnection()
174239
{
175240
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
{
@@ -24,6 +25,8 @@ public class FirebirdClientDriver : ReflectionBasedDriver
2425
private static readonly Regex _castCandidateRegEx = new Regex(CAST_PARAMS_EXP, RegexOptions.IgnoreCase);
2526
private readonly FirebirdDialect _fbDialect = new FirebirdDialect();
2627

28+
private bool _disableParameterCasting;
29+
2730
/// <summary>
2831
/// Initializes a new instance of the <see cref="FirebirdClientDriver"/> class.
2932
/// </summary>
@@ -43,6 +46,8 @@ public override void Configure(IDictionary<string, string> settings)
4346
{
4447
base.Configure(settings);
4548
_fbDialect.Configure(settings);
49+
50+
_disableParameterCasting = PropertiesHelper.GetBoolean(Environment.FirebirdDisableParameterCasting, settings);
4651
}
4752

4853
public override bool UseNamedPrefixInSql => true;
@@ -64,6 +69,9 @@ public override DbCommand GenerateCommand(CommandType type, SqlString sqlString,
6469
{
6570
var command = base.GenerateCommand(type, sqlString, parameterTypes);
6671

72+
if (_disableParameterCasting)
73+
return command;
74+
6775
var expWithParams = GetStatementsWithCastCandidates(command.CommandText);
6876
if (!string.IsNullOrWhiteSpace(expWithParams))
6977
{

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)