Skip to content

Commit

Permalink
Fix to #24569 - TableValuedFunctionExpression does not take the IsBui…
Browse files Browse the repository at this point in the history
…ltIn option into account (DbFunctions)

The TableValuedFunctionExpression does not take the IsBuiltIn option into account. This results in brackets being added to build in database functions.

Fixes #24569
  • Loading branch information
jgveire authored and maumar committed Apr 26, 2021
1 parent 3e2db5e commit 393b60c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/EFCore.Relational/Query/QuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,12 @@ protected override Expression VisitTableValuedFunction(TableValuedFunctionExpres
.Append(".");
}

var name = tableValuedFunctionExpression.StoreFunction.IsBuiltIn
? tableValuedFunctionExpression.StoreFunction.Name
: _sqlGenerationHelper.DelimitIdentifier(tableValuedFunctionExpression.StoreFunction.Name);

_relationalCommandBuilder
.Append(_sqlGenerationHelper.DelimitIdentifier(tableValuedFunctionExpression.StoreFunction.Name))
.Append(name)
.Append("(");

GenerateList(tableValuedFunctionExpression.Arguments, e => Visit(e));
Expand Down
67 changes: 67 additions & 0 deletions test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10099,6 +10099,73 @@ public class AnOwnedTypeWithPrimitiveProperties2

#endregion

#region Issue24569

// TODO: Remove when JSON is first class and we have proper tests. See issue#4021

[ConditionalFact]
public virtual async Task Builtin_tvf_translated_correctly()
{
var contextFactory = await InitializeAsync<MyContext24569>(seed: c => c.Seed());

using (var context = contextFactory.CreateContext())
{
var query = await (from c in context.Cars
from j in context.OpenJson(c.Json, "$.items")
select new { c, j }).ToListAsync();

AssertSql(
new[] {
@"SELECT [c].[Id], [c].[Json], [o].[Value]
FROM [Cars] AS [c]
CROSS APPLY OPENJSON([c].[Json], N'$.items') AS [o]" });
}
}

protected class MyContext24569 : DbContext
{
public DbSet<Car24569> Cars { get; set; }

public MyContext24569(DbContextOptions options)
: base(options)
{
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDbFunction(() => OpenJson(string.Empty, string.Empty)).HasStoreType("nvarchar(max)");
}

[DbFunction("OPENJSON", IsBuiltIn = true)]
public IQueryable<JsonResult> OpenJson(string column, string jsonPath)
=> FromExpression(() => OpenJson(column, jsonPath));

public void Seed()
{
Cars.Add(new Car24569
{
Json = @"{ ""name"": ""test"", ""items"": [{""id"": 1}, {""id"": 2}] }",
});

SaveChanges();
}

public class Car24569
{
public int Id { get; set; }

public string Json { get; set; }
}

[Keyless]
public class JsonResult
{
public string Value { get; set; }
}
}

#endregion

protected override string StoreName => "QueryBugsTest";
protected TestSqlLoggerFactory TestSqlLoggerFactory
=> (TestSqlLoggerFactory)ListLoggerFactory;
Expand Down

0 comments on commit 393b60c

Please sign in to comment.