Skip to content

Commit

Permalink
Query: Throw better exception message for non-composable SQL in FromSql
Browse files Browse the repository at this point in the history
Resolves #17558
  • Loading branch information
smitpatel committed Oct 10, 2019
1 parent 1ceabe8 commit df0d72c
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 201 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion src/EFCore.Relational/Properties/RelationalStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -494,4 +494,7 @@
<data name="SetOperationNotWithinEntityTypeHierarchy" xml:space="preserve">
<value>Set operations (Union, Concat, Intersect, Except) are only supported over entity types within the same type hierarchy.</value>
</data>
</root>
<data name="FromSqlNonComposable" xml:space="preserve">
<value>FromSqlRaw/FromSqlInterpolated API is being used with non-composable SQL but query is composing over it. Considering using `AsEnumerable` after FromSqlRaw/FromSqlInterpolated method to avoid composing on server side.</value>
</data>
</root>
15 changes: 15 additions & 0 deletions src/EFCore.Relational/Query/QuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Internal;
Expand Down Expand Up @@ -312,6 +313,11 @@ protected override Expression VisitFromSql(FromSqlExpression fromSqlExpression)
{
_relationalCommandBuilder.AppendLine("(");

if (!IsComposableSql(fromSqlExpression.Sql))
{
throw new InvalidOperationException(RelationalStrings.FromSqlNonComposable);
}

using (_relationalCommandBuilder.Indent())
{
GenerateFromSql(fromSqlExpression);
Expand All @@ -324,6 +330,15 @@ protected override Expression VisitFromSql(FromSqlExpression fromSqlExpression)
return fromSqlExpression;
}

private bool IsComposableSql(string sql)
{
var trimmedSql = sql.TrimStart('\r', '\n', '\t', ' ');

return trimmedSql.StartsWith("SELECT ", StringComparison.OrdinalIgnoreCase)
|| trimmedSql.StartsWith("SELECT" + Environment.NewLine, StringComparison.OrdinalIgnoreCase)
|| trimmedSql.StartsWith("SELECT\t", StringComparison.OrdinalIgnoreCase);
}

protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpression)
{
if (sqlBinaryExpression.OperatorType == ExpressionType.Coalesce)
Expand Down
Loading

0 comments on commit df0d72c

Please sign in to comment.