Substring function does not work in Firebird

Description

Given

Following query would produce unexpected SQL (for Firebird):

C#:
var items = session.Query<TestEntity>()
.Where(i => i.Name.Substring(0, 4) == "Item")
.ToArray();

SQL:

select
testentity0_.Id as Id0_,
testentity0_.Name as Name0_
from
TestEntity testentity0_
where
substring(testentity0_.Name from @p0+1 for @p1)=@p2;

@p0 = 0 [Type: Int32 (0)],
@p1 = 4 [Type: Int32 (0)],
@p2 = 'Item' [Type: String (4)]

And an exception occurs ("expression evaluation not supported"):

NHibernate.Exceptions.GenericADOException: could not execute query [ select testentity0_.Id as Id0_, testentity0_.Name as Name0_ from TestEntity testentity0_ where substring(testentity0_.Name from @p0+1 for @p1)=@p2 ] Name1 - Value:0 Name2 - Value:4 Name3 - Value:Item [SQL: select testentity0_.Id as Id0_, testentity0_.Name as Name0_ from TestEntity testentity0_ where substring(testentity0_.Name from @p0+1 for @p1)=@p2] ---> FirebirdSql.Data.FirebirdClient.FbException: expression evaluation not supported ---> FirebirdSql.Data.Common.IscException: expression evaluation not supported
at FirebirdSql.Data.Client.Managed.Version10.GdsDatabase.ProcessResponse(IResponse response) in c:\Users\Jiri\Documents\devel\NETProvider\working\trunk\NETProvider\source\FirebirdSql\Data\Client\Managed\Version10\GdsDatabase.cs:line 647
. . .

Expected

Firebird expected query that look like this:

select
testentity0_.Id as Id0_,
testentity0_.Name as Name0_
from
TestEntity testentity0_
where
substring(testentity0_.Name from cast(coalesce(@p0+1, 1) as Integer) for @p1)=@p2;

@p0 = 0 [Type: Int32 (0)],
@p1 = 4 [Type: Int32 (0)],
@p2 = 'Item' [Type: String (4)]

Fix

For example, change FirebirdDialect:

[Serializable]
public class FirebirdSubstringFunction : ISQLFunction
{
public bool HasArguments
{
get
{
return true;
}
}

public bool HasParenthesesIfNoArguments
{
get
{
return true;
}
}

public IType ReturnType(IType columnType, IMapping mapping)
{
return NHibernateUtil.String;
}

public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
if (args.Count < 2 || args.Count > 3)
{
throw new QueryException("substring(): Incorrect number of parameters (expected 2 or 3, got " + args.Count + ")");
}

var sqlStringBuilder = new SqlStringBuilder();

sqlStringBuilder.Add("substring(").AddObject(args[0]).Add(" from cast(coalesce(").AddObject(args[1]).Add(", 1) as Integer)");

if (args.Count > 2)
{
sqlStringBuilder.Add(" for ").AddObject(args[2]);
}

sqlStringBuilder.Add(")");

return sqlStringBuilder.ToSqlString();
}
}

Additionally

Environment

None

Attachments

1

Activity

Show:

Oskar Berggren August 16, 2014 at 4:14 PM

We had four test cases involving substring that were ignored on Firebird. I've reenabled them and they work now (efed80df578b1e7f58968449f70f7cc34597d35f).

Amro August 12, 2014 at 5:06 PM

This Issue should be resolved after the fix for

Alex Zaytsev June 1, 2013 at 10:53 AM

I'm getting "Dynamic SQL Error SQL error code = -104" with 3-arg variant

Fixed

Details

Assignee

Reporter

Labels

Components

Fix versions

Affects versions

Priority

Who's Looking?

Open Who's Looking?

Created March 1, 2013 at 5:37 AM
Updated September 21, 2014 at 12:42 PM
Resolved August 16, 2014 at 4:14 PM
Who's Looking?