Skip to content

Commit efc5203

Browse files
authored
String parameters in queries to varchar (not blob) directly (#89)
1 parent fe501e5 commit efc5203

File tree

3 files changed

+83
-8
lines changed

3 files changed

+83
-8
lines changed

Provider/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Sql/Internal/FbQuerySqlGenerator.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,22 @@ protected override Expression VisitParameter(ParameterExpression parameterExpres
111111
if (_fbOptions.ExplicitParameterTypes)
112112
{
113113
Sql.Append(" AS ");
114-
Sql.Append(Dependencies.TypeMappingSource.GetMapping(parameterExpression.Type).StoreType);
114+
if (parameterExpression.Type == typeof(string))
115+
{
116+
if (ParameterValues.TryGetValue(parameterExpression.Name, out var parameterValue))
117+
{
118+
Sql.Append(((IFbTypeMappingSource)Dependencies.TypeMappingSource).StringParameterQueryType((string)parameterValue));
119+
IsCacheable = false;
120+
}
121+
else
122+
{
123+
Sql.Append(((IFbTypeMappingSource)Dependencies.TypeMappingSource).StringParameterQueryType());
124+
}
125+
}
126+
else
127+
{
128+
Sql.Append(Dependencies.TypeMappingSource.GetMapping(parameterExpression.Type).StoreType);
129+
}
115130
Sql.Append(")");
116131
}
117132
return parameterExpression;
@@ -173,17 +188,16 @@ protected override string GenerateOperator(Expression expression)
173188
protected override Expression VisitConstant(ConstantExpression constantExpression)
174189
{
175190
var svalue = constantExpression.Value as string;
176-
var explicitVarcharPossible = constantExpression.Type == typeof(string) && svalue?.Length > 0;
177-
if (_fbOptions.ExplicitStringLiteralTypes && explicitVarcharPossible)
191+
if (_fbOptions.ExplicitStringLiteralTypes && constantExpression.Type == typeof(string))
178192
{
179193
Sql.Append("CAST(");
180194
}
181195
base.VisitConstant(constantExpression);
182-
if (_fbOptions.ExplicitStringLiteralTypes && explicitVarcharPossible)
196+
if (_fbOptions.ExplicitStringLiteralTypes && constantExpression.Type == typeof(string))
183197
{
184-
Sql.Append(" AS VARCHAR(");
185-
Sql.Append(svalue.Length);
186-
Sql.Append(") CHARACTER SET UTF8)");
198+
Sql.Append(" AS ");
199+
Sql.Append(((IFbTypeMappingSource)Dependencies.TypeMappingSource).StringLiteralQueryType(svalue));
200+
Sql.Append(")");
187201
}
188202
return constantExpression;
189203
}

Provider/src/FirebirdSql.EntityFrameworkCore.Firebird/Storage/Internal/FbTypeMappingSource.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
namespace FirebirdSql.EntityFrameworkCore.Firebird.Storage.Internal
2626
{
27-
public class FbTypeMappingSource : RelationalTypeMappingSource
27+
public class FbTypeMappingSource : RelationalTypeMappingSource, IFbTypeMappingSource
2828
{
2929
public const int BinaryMaxSize = Int32.MaxValue;
3030
public const int VarcharMaxSize = 32765 / 4;
@@ -190,5 +190,38 @@ RelationalTypeMapping FindRawMapping(RelationalTypeMappingInfo mappingInfo)
190190

191191
return null;
192192
}
193+
194+
public virtual string StringLiteralQueryType(string s)
195+
{
196+
var length = MinimumStringQueryTypeLength(s);
197+
EnsureStringQueryTypeLength(length);
198+
return $"VARCHAR({length}) CHARACTER SET UTF8";
199+
}
200+
201+
public virtual string StringParameterQueryType(string s)
202+
{
203+
var length = MinimumStringQueryTypeLength(s);
204+
EnsureStringQueryTypeLength(length);
205+
return $"VARCHAR({length})";
206+
}
207+
208+
public virtual string StringParameterQueryType()
209+
{
210+
return $"VARCHAR({VarcharMaxSize})";
211+
}
212+
213+
static int MinimumStringQueryTypeLength(string s)
214+
{
215+
var length = s?.Length ?? 0;
216+
if (length == 0)
217+
length = 1;
218+
return length;
219+
}
220+
221+
static void EnsureStringQueryTypeLength(int length)
222+
{
223+
if (length > VarcharMaxSize)
224+
throw new ArgumentOutOfRangeException(nameof(length));
225+
}
193226
}
194227
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* The contents of this file are subject to the Initial
3+
* Developer's Public License Version 1.0 (the "License");
4+
* you may not use this file except in compliance with the
5+
* License. You may obtain a copy of the License at
6+
* https://github.com/FirebirdSQL/NETProvider/blob/master/license.txt.
7+
*
8+
* Software distributed under the License is distributed on
9+
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
10+
* express or implied. See the License for the specific
11+
* language governing rights and limitations under the License.
12+
*
13+
* All Rights Reserved.
14+
*/
15+
16+
//$Authors = Jiri Cincura ([email protected])
17+
18+
using Microsoft.EntityFrameworkCore.Storage;
19+
20+
namespace FirebirdSql.EntityFrameworkCore.Firebird.Storage.Internal
21+
{
22+
public interface IFbTypeMappingSource : IRelationalTypeMappingSource
23+
{
24+
string StringLiteralQueryType(string s);
25+
string StringParameterQueryType(string s);
26+
string StringParameterQueryType();
27+
}
28+
}

0 commit comments

Comments
 (0)