Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ public static T Greatest<T>(this DbFunctions _, [NotParameterized] params T[] va
/// <param name="_">The <see cref="DbFunctions" /> instance.</param>
/// <param name="json">The JSON value to check.</param>
/// <param name="path">The JSON path to look for.</param>
public static bool JsonExists(this DbFunctions _, object json, string path)
=> throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(JsonExists)));
public static bool JsonPathExists(this DbFunctions _, object json, string path)
=> throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(JsonPathExists)));
Comment thread
roji marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -2072,7 +2072,6 @@ private void ApplySetOperation(
SelectExpression select2,
bool distinct)
{
// TODO: Introduce clone method? See issue#24460
var select1 = new SelectExpression(
alias: null, tables: _tables.ToList(), groupBy: _groupBy.ToList(), projections: [], orderings: _orderings.ToList(),
annotations: Annotations, sqlAliasManager: _sqlAliasManager)
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore.Relational/Query/SqlNullabilityProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1957,7 +1957,7 @@ protected virtual bool TryMakeNonNullable(
var rewrittenCollectionTable = UpdateParameterCollection(collectionTable, rewrittenParameter);

// We clone the select expression since Update below doesn't create a pure copy, mutating the original as well (because of
// TableReferenceExpression). TODO: Remove this after #31327.
// TableReferenceExpression). TODO: Remove this after SelectExpression becomes fully mutable (#32927).
#pragma warning disable EF1001
rewrittenSelectExpression = selectExpression.Clone();
#pragma warning restore EF1001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,9 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
typeof(int));
}

// We translate EF.Functions.JsonExists here and not in a method translator since we need to support JsonExists over
// We translate EF.Functions.JsonPathExists here and not in a method translator since we need to support JsonPathExists over
// complex and owned JSON properties, which requires special handling.
case nameof(RelationalDbFunctionsExtensions.JsonExists)
case nameof(RelationalDbFunctionsExtensions.JsonPathExists)
when declaringType == typeof(RelationalDbFunctionsExtensions)
&& @object is null
&& arguments is [_, var json, var path]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,9 @@ when methodCallExpression.Object is not null
method.Name is nameof(string.StartsWith));
}

// We translate EF.Functions.JsonExists here and not in a method translator since we need to support JsonExists over
// We translate EF.Functions.JsonPathExists here and not in a method translator since we need to support JsonPathExists over
// complex and owned JSON properties, which requires special handling.
case nameof(RelationalDbFunctionsExtensions.JsonExists)
case nameof(RelationalDbFunctionsExtensions.JsonPathExists)
when declaringType == typeof(RelationalDbFunctionsExtensions)
&& @object is null
&& arguments is [_, var json, var path]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,32 @@

namespace Microsoft.EntityFrameworkCore.Query.Translations;

// This test suite covers translations of JSON functions on EF.Functions (e.g. EF.Functions.JsonExists).
// This test suite covers translations of JSON functions on EF.Functions (e.g. EF.Functions.JsonPathExists).
// It does not cover general, built-in JSON support via complex type mapping, etc.
public abstract class JsonTranslationsRelationalTestBase<TFixture>(TFixture fixture) : QueryTestBase<TFixture>(fixture)
where TFixture : JsonTranslationsRelationalTestBase<TFixture>.JsonTranslationsQueryFixtureBase, new()
{
[ConditionalFact]
public virtual Task JsonExists_on_scalar_string_column()
public virtual Task JsonPathExists_on_scalar_string_column()
=> AssertQuery(
ss => ss.Set<JsonTranslationsEntity>()
.Where(b => EF.Functions.JsonExists(b.JsonString, "$.OptionalInt")),
.Where(b => EF.Functions.JsonPathExists(b.JsonString, "$.OptionalInt")),
ss => ss.Set<JsonTranslationsEntity>()
.Where(b => ((IDictionary<string, JsonNode>)JsonNode.Parse(b.JsonString)!).ContainsKey("OptionalInt")));

[ConditionalFact]
public virtual Task JsonExists_on_complex_property()
public virtual Task JsonPathExists_on_complex_property()
=> AssertQuery(
ss => ss.Set<JsonTranslationsEntity>()
.Where(b => EF.Functions.JsonExists(b.JsonComplexType, "$.OptionalInt")),
.Where(b => EF.Functions.JsonPathExists(b.JsonComplexType, "$.OptionalInt")),
ss => ss.Set<JsonTranslationsEntity>()
.Where(b => ((IDictionary<string, JsonNode>)JsonNode.Parse(b.JsonString)!).ContainsKey("OptionalInt")));

[ConditionalFact]
public virtual Task JsonExists_on_owned_entity()
public virtual Task JsonPathExists_on_owned_entity()
=> AssertQuery(
ss => ss.Set<JsonTranslationsEntity>()
.Where(b => EF.Functions.JsonExists(b.JsonOwnedType, "$.OptionalInt")),
.Where(b => EF.Functions.JsonPathExists(b.JsonOwnedType, "$.OptionalInt")),
ss => ss.Set<JsonTranslationsEntity>()
.Where(b => ((IDictionary<string, JsonNode>)JsonNode.Parse(b.JsonString)!).ContainsKey("OptionalInt")));

Expand Down Expand Up @@ -103,12 +103,12 @@ protected override async Task SeedAsync(JsonTranslationsQueryContext context)

await context.Database.ExecuteSqlRawAsync(
$$"""
UPDATE {{table}} SET {{complexTypeColumn}} = {{RemoveJsonProperty(complexTypeColumn, "$.OptionalInt")}} WHERE {{idColumn}} = 4;
UPDATE {{table}} SET {{ownedColumn}} = {{RemoveJsonProperty(ownedColumn, "$.OptionalInt")}} WHERE {{idColumn}} = 4;
UPDATE {{table}} SET {{complexTypeColumn}} = {{RemoveJsonProperty(complexTypeColumn, "OptionalInt")}} WHERE {{idColumn}} = 4;
UPDATE {{table}} SET {{ownedColumn}} = {{RemoveJsonProperty(ownedColumn, "OptionalInt")}} WHERE {{idColumn}} = 4;
""");
}

protected abstract string RemoveJsonProperty(string column, string jsonPath);
protected abstract string RemoveJsonProperty(string column, string property);

public virtual ISetSource GetExpectedData()
=> _expectedData ??= new JsonTranslationsData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public JsonTranslationsSqlServerTest(JsonTranslationsQuerySqlServerFixture fixtu
}

[ConditionalFact, SqlServerCondition(SqlServerCondition.SupportsFunctions2022)]
public override async Task JsonExists_on_scalar_string_column()
public override async Task JsonPathExists_on_scalar_string_column()
{
await base.JsonExists_on_scalar_string_column();
await base.JsonPathExists_on_scalar_string_column();

AssertSql(
"""
Expand All @@ -28,9 +28,9 @@ WHERE JSON_PATH_EXISTS([j].[JsonString], N'$.OptionalInt') = 1
}

[ConditionalFact, SqlServerCondition(SqlServerCondition.SupportsFunctions2022)]
public override async Task JsonExists_on_complex_property()
public override async Task JsonPathExists_on_complex_property()
{
await base.JsonExists_on_complex_property();
await base.JsonPathExists_on_complex_property();

AssertSql(
"""
Expand All @@ -41,9 +41,9 @@ WHERE JSON_PATH_EXISTS([j].[JsonComplexType], N'$.OptionalInt') = 1
}

[ConditionalFact, SqlServerCondition(SqlServerCondition.SupportsFunctions2022)]
public override async Task JsonExists_on_owned_entity()
public override async Task JsonPathExists_on_owned_entity()
{
await base.JsonExists_on_owned_entity();
await base.JsonPathExists_on_owned_entity();

AssertSql(
"""
Expand Down Expand Up @@ -133,8 +133,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con
}
}

protected override string RemoveJsonProperty(string column, string jsonPath)
=> $"JSON_MODIFY({column}, '{jsonPath}', NULL)";
protected override string RemoveJsonProperty(string column, string property)
=> $"JSON_MODIFY({column}, '$.{property}', NULL)";
}

[ConditionalFact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public JsonTranslationsSqliteTest(JsonTranslationsQuerySqliteFixture fixture, IT
}

[ConditionalFact]
public override async Task JsonExists_on_scalar_string_column()
public override async Task JsonPathExists_on_scalar_string_column()
{
await base.JsonExists_on_scalar_string_column();
await base.JsonPathExists_on_scalar_string_column();

AssertSql(
"""
Expand All @@ -26,9 +26,9 @@ WHERE json_type("j"."JsonString", '$.OptionalInt') IS NOT NULL
}

[ConditionalFact]
public override async Task JsonExists_on_complex_property()
public override async Task JsonPathExists_on_complex_property()
{
await base.JsonExists_on_complex_property();
await base.JsonPathExists_on_complex_property();

AssertSql(
"""
Expand All @@ -39,9 +39,9 @@ WHERE json_type("j"."JsonComplexType", '$.OptionalInt') IS NOT NULL
}

[ConditionalFact]
public override async Task JsonExists_on_owned_entity()
public override async Task JsonPathExists_on_owned_entity()
{
await base.JsonExists_on_owned_entity();
await base.JsonPathExists_on_owned_entity();

AssertSql(
"""
Expand All @@ -56,8 +56,8 @@ public class JsonTranslationsQuerySqliteFixture : JsonTranslationsQueryFixtureBa
protected override ITestStoreFactory TestStoreFactory
=> SqliteTestStoreFactory.Instance;

protected override string RemoveJsonProperty(string column, string jsonPath)
=> $"json_remove({column}, '{jsonPath}')";
protected override string RemoveJsonProperty(string column, string property)
=> $"json_remove({column}, '$.{property}')";
}

[ConditionalFact]
Expand Down
Loading