Skip to content

Commit db1a9ef

Browse files
Add support for CROSS APPLY and OUTER APPLY generation (#1238)
1 parent 1a397a7 commit db1a9ef

File tree

3 files changed

+61
-7
lines changed

3 files changed

+61
-7
lines changed

src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/NorthwindJoinQueryFbTest.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,21 @@ public NorthwindJoinQueryFbTest(NorthwindQueryFbFixture<NoopModelCustomizer> fix
2929
: base(fixture)
3030
{ }
3131

32-
[NotSupportedOnFirebirdTheory]
32+
[Theory]
3333
[MemberData(nameof(IsAsyncData))]
3434
public override Task GroupJoin_as_final_operator(bool async)
3535
{
3636
return base.GroupJoin_as_final_operator(async);
3737
}
3838

39-
[NotSupportedOnFirebirdTheory]
39+
[Theory]
4040
[MemberData(nameof(IsAsyncData))]
4141
public override Task GroupJoin_SelectMany_subquery_with_filter_orderby(bool async)
4242
{
4343
return base.GroupJoin_SelectMany_subquery_with_filter_orderby(async);
4444
}
4545

46-
[NotSupportedOnFirebirdTheory]
46+
[Theory]
4747
[MemberData(nameof(IsAsyncData))]
4848
public override Task GroupJoin_SelectMany_subquery_with_filter_orderby_and_DefaultIfEmpty(bool async)
4949
{
@@ -99,14 +99,14 @@ public override Task Take_in_collection_projection_with_FirstOrDefault_on_top_le
9999
return base.Take_in_collection_projection_with_FirstOrDefault_on_top_level(async);
100100
}
101101

102-
[NotSupportedOnFirebirdTheory]
102+
[Theory]
103103
[MemberData(nameof(IsAsyncData))]
104104
public override Task Unflattened_GroupJoin_composed(bool async)
105105
{
106106
return base.Unflattened_GroupJoin_composed(async);
107107
}
108108

109-
[NotSupportedOnFirebirdTheory]
109+
[Theory]
110110
[MemberData(nameof(IsAsyncData))]
111111
public override Task Unflattened_GroupJoin_composed_2(bool async)
112112
{

src/FirebirdSql.EntityFrameworkCore.Firebird.FunctionalTests/Query/UdfDbFunctionFbTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public override void Udf_with_argument_being_comparison_of_nullable_columns()
5151
base.Udf_with_argument_being_comparison_of_nullable_columns();
5252
}
5353

54-
[NotSupportedOnFirebirdFact]
54+
[Fact]
5555
public override void QF_Select_Correlated_Subquery_In_Anonymous_MultipleCollections()
5656
{
5757
base.QF_Select_Correlated_Subquery_In_Anonymous_MultipleCollections();

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

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstant
191191
base.VisitSqlConstant(sqlConstantExpression);
192192
if (shouldExplicitStringLiteralTypes)
193193
{
194-
var isUnicode = FbTypeMappingSource.IsUnicode(sqlConstantExpression.TypeMapping);
194+
var isUnicode = FbTypeMappingSource.IsUnicode(sqlConstantExpression.TypeMapping);
195195
Sql.Append(" AS ");
196196
Sql.Append(((IFbSqlGenerationHelper)Dependencies.SqlGenerationHelper).StringLiteralQueryType(sqlConstantExpression.Value as string, isUnicode));
197197
Sql.Append(")");
@@ -280,6 +280,60 @@ protected override void GenerateOrderings(SelectExpression selectExpression)
280280
}
281281
}
282282

283+
// Adapted from Npgsql Entity Framework Core provider
284+
// (https://github.com/npgsql/efcore.pg)
285+
// Copyright (c) 2002-2021, Npgsql
286+
protected override Expression VisitCrossApply(CrossApplyExpression crossApplyExpression)
287+
{
288+
Sql.Append("JOIN LATERAL ");
289+
290+
if (crossApplyExpression.Table is TableExpression table)
291+
{
292+
// Firebird doesn't support LATERAL JOIN over table, and it doesn't really make sense to do it - but EF Core
293+
// will sometimes generate that.
294+
Sql
295+
.Append("(SELECT * FROM ")
296+
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(table.Name, table.Schema))
297+
.Append(")")
298+
.Append(AliasSeparator)
299+
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(table.Alias));
300+
}
301+
else
302+
{
303+
Visit(crossApplyExpression.Table);
304+
}
305+
306+
Sql.Append(" ON TRUE");
307+
return crossApplyExpression;
308+
}
309+
310+
// Adapted from Npgsql Entity Framework Core provider
311+
// (https://github.com/npgsql/efcore.pg)
312+
// Copyright (c) 2002-2021, Npgsql
313+
protected override Expression VisitOuterApply(OuterApplyExpression outerApplyExpression)
314+
{
315+
Sql.Append("LEFT JOIN LATERAL ");
316+
317+
if (outerApplyExpression.Table is TableExpression table)
318+
{
319+
// Firebird doesn't support LATERAL JOIN over table, and it doesn't really make sense to do it - but EF Core
320+
// will sometimes generate that.
321+
Sql
322+
.Append("(SELECT * FROM ")
323+
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(table.Name, table.Schema))
324+
.Append(")")
325+
.Append(AliasSeparator)
326+
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(table.Alias));
327+
}
328+
else
329+
{
330+
Visit(outerApplyExpression.Table);
331+
}
332+
333+
Sql.Append(" ON TRUE");
334+
return outerApplyExpression;
335+
}
336+
283337
protected override void GeneratePseudoFromClause()
284338
{
285339
Sql.Append(" FROM RDB$DATABASE");

0 commit comments

Comments
 (0)