Skip to content

Commit

Permalink
Fix Contains with byte array. and fix getting length if an odd number…
Browse files Browse the repository at this point in the history
… of bytes
  • Loading branch information
ChrisJollyAU committed Mar 9, 2024
1 parent c3b43a3 commit f083485
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,30 @@ public JetByteArrayMethodTranslator(ISqlExpressionFactory sqlExpressionFactory)

var value = arguments[1] is SqlConstantExpression constantValue
? (SqlExpression)_sqlExpressionFactory.Constant(new[] { (byte)constantValue.Value! }, sourceTypeMapping)
: _sqlExpressionFactory.Convert(arguments[1], typeof(byte[]), sourceTypeMapping);
: _sqlExpressionFactory.Function(
"CHR",
new SqlExpression[] { arguments[1] },
nullable: true,
argumentsPropagateNullability: new[] { true },
typeof(string));



return _sqlExpressionFactory.GreaterThan(
_sqlExpressionFactory.Function(
"INSTRB",
new[] { _sqlExpressionFactory.Constant(1), source, value, _sqlExpressionFactory.Constant(0) },
"INSTR",
new[]
{
_sqlExpressionFactory.Constant(1),
_sqlExpressionFactory.Function(
"STRCONV",
new [] { source, _sqlExpressionFactory.Constant(64) },
nullable: true,
argumentsPropagateNullability: new[] { true, false },
typeof(string)),
value,
_sqlExpressionFactory.Constant(0)
},
nullable: true,
argumentsPropagateNullability: new[] { true, true },
typeof(int)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,33 @@ protected override Expression VisitUnary(UnaryExpression unaryExpression)
}

var isBinaryMaxDataType = GetProviderType(sqlExpression) == "varbinary(max)" || sqlExpression is SqlParameterExpression;
var dataLengthSqlFunction = Dependencies.SqlExpressionFactory.Function(
SqlExpression dataLengthSqlFunction = Dependencies.SqlExpressionFactory.Function(
"LENB",
new[] { sqlExpression },
nullable: true,
argumentsPropagateNullability: new[] { true },
isBinaryMaxDataType ? typeof(long) : typeof(int));

var rightval = Dependencies.SqlExpressionFactory.Function(
"ASCB",
new[]
{
Dependencies.SqlExpressionFactory.Function(
"RIGHTB",
new[] { sqlExpression, Dependencies.SqlExpressionFactory.Constant(1) },
nullable: true,
argumentsPropagateNullability: new[] { true, true, true },
typeof(byte[]))
},
nullable: true,
argumentsPropagateNullability: new[] { true },
typeof(int));

var minusOne = Dependencies.SqlExpressionFactory.Subtract(dataLengthSqlFunction, Dependencies.SqlExpressionFactory.Constant(1));
var whenClause = new CaseWhenClause(Dependencies.SqlExpressionFactory.Equal(rightval, Dependencies.SqlExpressionFactory.Constant(0)), minusOne);

dataLengthSqlFunction = Dependencies.SqlExpressionFactory.Case(new[] { whenClause }, dataLengthSqlFunction);

return isBinaryMaxDataType
? Dependencies.SqlExpressionFactory.Convert(dataLengthSqlFunction, typeof(int))
: dataLengthSqlFunction;
Expand Down
33 changes: 20 additions & 13 deletions test/EFCore.Jet.FunctionalTests/Query/GearsOfWarQueryJetTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7256,10 +7256,10 @@ public override async Task Byte_array_contains_literal(bool async)
await base.Byte_array_contains_literal(async);

AssertSql(
"""
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE CHARINDEX(0x01, `s`.`Banner`) > 0
WHERE INSTR(1, STRCONV(`s`.`Banner`, 64), 0x01, 0) > 0
""");
}

Expand All @@ -7271,7 +7271,7 @@ public override async Task Byte_array_filter_by_length_literal(bool async)
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE LENB(`s`.`Banner`) = 2
WHERE IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) = 2
""");
}

Expand All @@ -7285,7 +7285,7 @@ public override async Task Byte_array_filter_by_length_parameter(bool async)

SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE LENB(`s`.`Banner`) = @__p_0
WHERE IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) = @__p_0
""");
}

Expand All @@ -7297,10 +7297,17 @@ public override void Byte_array_filter_by_length_parameter_compiled()
"""
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)

SELECT COUNT(*)
FROM `Squads` AS `s`
WHERE LENB(`s`.`Banner`) = IIF(LENB(@__byteArrayParam) IS NULL, NULL, CLNG(LENB(@__byteArrayParam)))
WHERE IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) = IIF(IIF(ASCB(RIGHTB(@__byteArrayParam, 1)) = 0, LENB(@__byteArrayParam) - 1, LENB(@__byteArrayParam)) IS NULL, NULL, CLNG(IIF(ASCB(RIGHTB(@__byteArrayParam, 1)) = 0, LENB(@__byteArrayParam) - 1, LENB(@__byteArrayParam)))) OR (IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) IS NULL AND IIF(ASCB(RIGHTB(@__byteArrayParam, 1)) = 0, LENB(@__byteArrayParam) - 1, LENB(@__byteArrayParam)) IS NULL)
""");
}

Expand All @@ -7309,12 +7316,12 @@ public override async Task Byte_array_contains_parameter(bool async)
await base.Byte_array_contains_parameter(async);

AssertSql(
"""
"""
@__someByte_0='1' (Size = 1)

SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE CHARINDEX(CAST(@__someByte_0 AS varbinary(max)), `s`.`Banner`) > 0
WHERE INSTR(1, STRCONV(`s`.`Banner`, 64), CHR(@__someByte_0), 0) > 0
""");
}

Expand All @@ -7323,10 +7330,10 @@ public override async Task Byte_array_filter_by_length_literal_does_not_cast_on_
await base.Byte_array_filter_by_length_literal_does_not_cast_on_varbinary_n(async);

AssertSql(
"""
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE DATALENGTH(`s`.`Banner5`) = 5
WHERE IIF(ASCB(RIGHTB(`s`.`Banner5`, 1)) = 0, LENB(`s`.`Banner5`) - 1, LENB(`s`.`Banner5`)) = 5
""");
}

Expand Down Expand Up @@ -7651,11 +7658,11 @@ public override async Task Contains_on_byte_array_property_using_byte_column(boo
await base.Contains_on_byte_array_property_using_byte_column(async);

AssertSql(
"""
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`, `l`.`Name`, `l`.`Discriminator`, `l`.`LocustHordeId`, `l`.`ThreatLevel`, `l`.`ThreatLevelByte`, `l`.`ThreatLevelNullableByte`, `l`.`DefeatedByNickname`, `l`.`DefeatedBySquadId`, `l`.`HighCommandId`
FROM `Squads` AS `s`
CROSS JOIN `LocustLeaders` AS `l`
WHERE CHARINDEX(CAST(`l`.`ThreatLevelByte` AS varbinary(max)), `s`.`Banner`) > 0
FROM `Squads` AS `s`,
`LocustLeaders` AS `l`
WHERE INSTR(1, STRCONV(`s`.`Banner`, 64), CHR(`l`.`ThreatLevelByte`), 0) > 0
""");
}

Expand Down
57 changes: 32 additions & 25 deletions test/EFCore.Jet.FunctionalTests/Query/TPCGearsOfWarQueryJetTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10038,10 +10038,10 @@ public override async Task Byte_array_contains_literal(bool async)
await base.Byte_array_contains_literal(async);

AssertSql(
"""
SELECT [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name]
FROM [Squads] AS [s]
WHERE CHARINDEX(0x01, [s].[Banner]) > 0
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE INSTR(1, STRCONV(`s`.`Banner`, 64), 0x01, 0) > 0
""");
}

Expand All @@ -10053,7 +10053,7 @@ public override async Task Byte_array_filter_by_length_literal(bool async)
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE LENB(`s`.`Banner`) = 2
WHERE IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) = 2
""");
}

Expand All @@ -10067,7 +10067,7 @@ public override async Task Byte_array_filter_by_length_parameter(bool async)

SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE LENB(`s`.`Banner`) = @__p_0
WHERE IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) = @__p_0
""");
}

Expand All @@ -10079,10 +10079,17 @@ public override void Byte_array_filter_by_length_parameter_compiled()
"""
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)

SELECT COUNT(*)
FROM `Squads` AS `s`
WHERE LENB(`s`.`Banner`) = IIF(LENB(@__byteArrayParam) IS NULL, NULL, CLNG(LENB(@__byteArrayParam)))
WHERE IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) = IIF(IIF(ASCB(RIGHTB(@__byteArrayParam, 1)) = 0, LENB(@__byteArrayParam) - 1, LENB(@__byteArrayParam)) IS NULL, NULL, CLNG(IIF(ASCB(RIGHTB(@__byteArrayParam, 1)) = 0, LENB(@__byteArrayParam) - 1, LENB(@__byteArrayParam)))) OR (IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) IS NULL AND IIF(ASCB(RIGHTB(@__byteArrayParam, 1)) = 0, LENB(@__byteArrayParam) - 1, LENB(@__byteArrayParam)) IS NULL)
""");
}

Expand All @@ -10091,12 +10098,12 @@ public override async Task Byte_array_contains_parameter(bool async)
await base.Byte_array_contains_parameter(async);

AssertSql(
"""
"""
@__someByte_0='1' (Size = 1)

SELECT [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name]
FROM [Squads] AS [s]
WHERE CHARINDEX(CAST(@__someByte_0 AS varbinary(max)), [s].[Banner]) > 0
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE INSTR(1, STRCONV(`s`.`Banner`, 64), CHR(@__someByte_0), 0) > 0
""");
}

Expand All @@ -10105,10 +10112,10 @@ public override async Task Byte_array_filter_by_length_literal_does_not_cast_on_
await base.Byte_array_filter_by_length_literal_does_not_cast_on_varbinary_n(async);

AssertSql(
"""
SELECT [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name]
FROM [Squads] AS [s]
WHERE DATALENGTH([s].[Banner5]) = 5
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE IIF(ASCB(RIGHTB(`s`.`Banner5`, 1)) = 0, LENB(`s`.`Banner5`) - 1, LENB(`s`.`Banner5`)) = 5
""");
}

Expand Down Expand Up @@ -10523,17 +10530,17 @@ public override async Task Contains_on_byte_array_property_using_byte_column(boo
await base.Contains_on_byte_array_property_using_byte_column(async);

AssertSql(
"""
SELECT [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name], [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator]
FROM [Squads] AS [s]
CROSS JOIN (
SELECT [l].[Name], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], NULL AS [DefeatedByNickname], NULL AS [DefeatedBySquadId], NULL AS [HighCommandId], N'LocustLeader' AS [Discriminator]
FROM [LocustLeaders] AS [l]
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`, `t`.`Name`, `t`.`LocustHordeId`, `t`.`ThreatLevel`, `t`.`ThreatLevelByte`, `t`.`ThreatLevelNullableByte`, `t`.`DefeatedByNickname`, `t`.`DefeatedBySquadId`, `t`.`HighCommandId`, `t`.`Discriminator`
FROM `Squads` AS `s`,
(
SELECT `l`.`Name`, `l`.`LocustHordeId`, `l`.`ThreatLevel`, `l`.`ThreatLevelByte`, `l`.`ThreatLevelNullableByte`, NULL AS `DefeatedByNickname`, CVar(NULL) AS `DefeatedBySquadId`, CVar(NULL) AS `HighCommandId`, 'LocustLeader' AS `Discriminator`
FROM `LocustLeaders` AS `l`
UNION ALL
SELECT [l0].[Name], [l0].[LocustHordeId], [l0].[ThreatLevel], [l0].[ThreatLevelByte], [l0].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], N'LocustCommander' AS [Discriminator]
FROM [LocustCommanders] AS [l0]
) AS [t]
WHERE CHARINDEX(CAST([t].[ThreatLevelByte] AS varbinary(max)), [s].[Banner]) > 0
SELECT `l0`.`Name`, `l0`.`LocustHordeId`, `l0`.`ThreatLevel`, `l0`.`ThreatLevelByte`, `l0`.`ThreatLevelNullableByte`, `l0`.`DefeatedByNickname`, `l0`.`DefeatedBySquadId`, `l0`.`HighCommandId`, 'LocustCommander' AS `Discriminator`
FROM `LocustCommanders` AS `l0`
) AS `t`
WHERE INSTR(1, STRCONV(`s`.`Banner`, 64), CHR(`t`.`ThreatLevelByte`), 0) > 0
""");
}

Expand Down
57 changes: 31 additions & 26 deletions test/EFCore.Jet.FunctionalTests/Query/TPTGearsOfWarQueryJetTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8125,10 +8125,10 @@ public override async Task Byte_array_contains_literal(bool async)
await base.Byte_array_contains_literal(async);

AssertSql(
"""
SELECT [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name]
FROM [Squads] AS [s]
WHERE CHARINDEX(0x01, [s].[Banner]) > 0
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE INSTR(1, STRCONV(`s`.`Banner`, 64), 0x01, 0) > 0
""");
}

Expand All @@ -8140,7 +8140,7 @@ public override async Task Byte_array_filter_by_length_literal(bool async)
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE LENB(`s`.`Banner`) = 2
WHERE IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) = 2
""");
}

Expand All @@ -8154,7 +8154,7 @@ public override async Task Byte_array_filter_by_length_parameter(bool async)

SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE LENB(`s`.`Banner`) = @__p_0
WHERE IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) = @__p_0
""");
}

Expand All @@ -8166,10 +8166,17 @@ public override void Byte_array_filter_by_length_parameter_compiled()
"""
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)
@__byteArrayParam='0x2A80' (Size = 510)

SELECT COUNT(*)
FROM `Squads` AS `s`
WHERE LENB(`s`.`Banner`) = IIF(LENB(@__byteArrayParam) IS NULL, NULL, CLNG(LENB(@__byteArrayParam)))
WHERE IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) = IIF(IIF(ASCB(RIGHTB(@__byteArrayParam, 1)) = 0, LENB(@__byteArrayParam) - 1, LENB(@__byteArrayParam)) IS NULL, NULL, CLNG(IIF(ASCB(RIGHTB(@__byteArrayParam, 1)) = 0, LENB(@__byteArrayParam) - 1, LENB(@__byteArrayParam)))) OR (IIF(ASCB(RIGHTB(`s`.`Banner`, 1)) = 0, LENB(`s`.`Banner`) - 1, LENB(`s`.`Banner`)) IS NULL AND IIF(ASCB(RIGHTB(@__byteArrayParam, 1)) = 0, LENB(@__byteArrayParam) - 1, LENB(@__byteArrayParam)) IS NULL)
""");
}

Expand All @@ -8178,12 +8185,12 @@ public override async Task Byte_array_contains_parameter(bool async)
await base.Byte_array_contains_parameter(async);

AssertSql(
"""
"""
@__someByte_0='1' (Size = 1)

SELECT [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name]
FROM [Squads] AS [s]
WHERE CHARINDEX(CAST(@__someByte_0 AS varbinary(max)), [s].[Banner]) > 0
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE INSTR(1, STRCONV(`s`.`Banner`, 64), CHR(@__someByte_0), 0) > 0
""");
}

Expand All @@ -8192,10 +8199,10 @@ public override async Task Byte_array_filter_by_length_literal_does_not_cast_on_
await base.Byte_array_filter_by_length_literal_does_not_cast_on_varbinary_n(async);

AssertSql(
"""
SELECT [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name]
FROM [Squads] AS [s]
WHERE DATALENGTH([s].[Banner5]) = 5
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`
FROM `Squads` AS `s`
WHERE IIF(ASCB(RIGHTB(`s`.`Banner5`, 1)) = 0, LENB(`s`.`Banner5`) - 1, LENB(`s`.`Banner5`)) = 5
""");
}

Expand Down Expand Up @@ -8532,17 +8539,15 @@ public override async Task Contains_on_byte_array_property_using_byte_column(boo
await base.Contains_on_byte_array_property_using_byte_column(async);

AssertSql(
"""
SELECT [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name], [t].[Name], [t].[LocustHordeId], [t].[ThreatLevel], [t].[ThreatLevelByte], [t].[ThreatLevelNullableByte], [t].[DefeatedByNickname], [t].[DefeatedBySquadId], [t].[HighCommandId], [t].[Discriminator]
FROM [Squads] AS [s]
CROSS JOIN (
SELECT [l].[Name], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], CASE
WHEN [l0].[Name] IS NOT NULL THEN N'LocustCommander'
END AS [Discriminator]
FROM [LocustLeaders] AS [l]
LEFT JOIN [LocustCommanders] AS [l0] ON [l].[Name] = [l0].[Name]
) AS [t]
WHERE CHARINDEX(CAST([t].[ThreatLevelByte] AS varbinary(max)), [s].[Banner]) > 0
"""
SELECT `s`.`Id`, `s`.`Banner`, `s`.`Banner5`, `s`.`InternalNumber`, `s`.`Name`, `t`.`Name`, `t`.`LocustHordeId`, `t`.`ThreatLevel`, `t`.`ThreatLevelByte`, `t`.`ThreatLevelNullableByte`, `t`.`DefeatedByNickname`, `t`.`DefeatedBySquadId`, `t`.`HighCommandId`, `t`.`Discriminator`
FROM `Squads` AS `s`,
(
SELECT `l`.`Name`, `l`.`LocustHordeId`, `l`.`ThreatLevel`, `l`.`ThreatLevelByte`, `l`.`ThreatLevelNullableByte`, `l0`.`DefeatedByNickname`, `l0`.`DefeatedBySquadId`, `l0`.`HighCommandId`, IIF(`l0`.`Name` IS NOT NULL, 'LocustCommander', NULL) AS `Discriminator`
FROM `LocustLeaders` AS `l`
LEFT JOIN `LocustCommanders` AS `l0` ON `l`.`Name` = `l0`.`Name`
) AS `t`
WHERE INSTR(1, STRCONV(`s`.`Banner`, 64), CHR(`t`.`ThreatLevelByte`), 0) > 0
""");
}

Expand Down

0 comments on commit f083485

Please sign in to comment.