Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,24 @@ public class SqliteByteArrayMethodTranslator(ISqlExpressionFactory sqlExpression
&& arguments is [var source, var item]
&& source.Type == typeof(byte[]))
{
// A non-constant byte has to be turned into a one-byte BLOB. char() would produce TEXT (the UTF-8 encoding of
// the code point), which makes instr() compare as text and gives wrong results for values above 0x7F.
var value = item is SqlConstantExpression constantValue
? sqlExpressionFactory.Constant(new[] { (byte)constantValue.Value! }, source.TypeMapping)
: sqlExpressionFactory.Function(
"char",
[item],
nullable: false,
argumentsPropagateNullability: Statics.FalseArrays[1],
typeof(string));
"unhex",
[
sqlExpressionFactory.Function(
"printf",
[sqlExpressionFactory.Constant("%02X"), item],
nullable: true,
argumentsPropagateNullability: Statics.FalseTrue,
typeof(string))
],
nullable: true,
argumentsPropagateNullability: Statics.TrueArrays[1],
typeof(byte[]),
source.TypeMapping);

return sqlExpressionFactory.GreaterThan(
sqlExpressionFactory.Function(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public override Task Contains_with_parameter()
public override Task Contains_with_column()
=> AssertTranslationFailed(base.Contains_with_column);

public override Task Contains_with_parameter_above_ascii_range()
=> AssertTranslationFailed(base.Contains_with_parameter_above_ascii_range);

public override Task Any()
=> AssertTranslationFailed(base.Any);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ public virtual Task Contains_with_parameter()
public virtual Task Contains_with_column()
=> AssertQuery(ss => ss.Set<BasicTypesEntity>().Where(s => s.ByteArray.Contains(s.Byte)));

[Fact]
public virtual Task Contains_with_parameter_above_ascii_range()
{
byte someByte = 0xDE;

return AssertQuery(ss => ss.Set<BasicTypesEntity>().Where(s => s.ByteArray.Contains(someByte)));
}

[Fact]
public virtual Task Any()
=> AssertQuery(ss => ss.Set<BasicTypesEntity>().Where(e => e.ByteArray.Any()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ WHERE CHARINDEX(CAST([b].[Byte] AS varbinary(max)), [b].[ByteArray]) > 0
""");
}

public override async Task Contains_with_parameter_above_ascii_range()
{
await base.Contains_with_parameter_above_ascii_range();

AssertSql(
"""
@someByte='222' (Size = 1)

SELECT [b].[Id], [b].[Bool], [b].[Byte], [b].[ByteArray], [b].[DateOnly], [b].[DateTime], [b].[DateTimeOffset], [b].[Decimal], [b].[Double], [b].[Enum], [b].[FlagsEnum], [b].[Float], [b].[Guid], [b].[Int], [b].[Long], [b].[Short], [b].[String], [b].[TimeOnly], [b].[TimeSpan]
FROM [BasicTypesEntities] AS [b]
WHERE CHARINDEX(CAST(@someByte AS varbinary(max)), [b].[ByteArray]) > 0
""");
}

public override async Task Any()
{
await base.Any();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public override async Task Contains_with_parameter()

SELECT "b"."Id", "b"."Bool", "b"."Byte", "b"."ByteArray", "b"."DateOnly", "b"."DateTime", "b"."DateTimeOffset", "b"."Decimal", "b"."Double", "b"."Enum", "b"."FlagsEnum", "b"."Float", "b"."Guid", "b"."Int", "b"."Long", "b"."Short", "b"."String", "b"."TimeOnly", "b"."TimeSpan"
FROM "BasicTypesEntities" AS "b"
WHERE instr("b"."ByteArray", char(@someByte)) > 0
WHERE instr("b"."ByteArray", unhex(printf('%02X', @someByte))) > 0
""");
}

Expand All @@ -66,7 +66,21 @@ public override async Task Contains_with_column()
"""
SELECT "b"."Id", "b"."Bool", "b"."Byte", "b"."ByteArray", "b"."DateOnly", "b"."DateTime", "b"."DateTimeOffset", "b"."Decimal", "b"."Double", "b"."Enum", "b"."FlagsEnum", "b"."Float", "b"."Guid", "b"."Int", "b"."Long", "b"."Short", "b"."String", "b"."TimeOnly", "b"."TimeSpan"
FROM "BasicTypesEntities" AS "b"
WHERE instr("b"."ByteArray", char("b"."Byte")) > 0
WHERE instr("b"."ByteArray", unhex(printf('%02X', "b"."Byte"))) > 0
""");
}

public override async Task Contains_with_parameter_above_ascii_range()
{
await base.Contains_with_parameter_above_ascii_range();

AssertSql(
"""
@someByte='222'

SELECT "b"."Id", "b"."Bool", "b"."Byte", "b"."ByteArray", "b"."DateOnly", "b"."DateTime", "b"."DateTimeOffset", "b"."Decimal", "b"."Double", "b"."Enum", "b"."FlagsEnum", "b"."Float", "b"."Guid", "b"."Int", "b"."Long", "b"."Short", "b"."String", "b"."TimeOnly", "b"."TimeSpan"
FROM "BasicTypesEntities" AS "b"
WHERE instr("b"."ByteArray", unhex(printf('%02X', @someByte))) > 0
""");
}

Expand Down
Loading