Skip to content

Commit b5d272a

Browse files
niekschoemakerua-niekschoemaker
authored andcommitted
Add support for CROSS APPLY and OUTER APPLY generation
Implement `VisitCrossApply` and `VisitOuterApply` methods to translate CROSS APPLY and OUTER APPLY constructs for Firebird using lateral joins. Adapted logic from Npgsql EF Core provider.
1 parent ac0fc79 commit b5d272a

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

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)