Skip to content

Commit

Permalink
Sync to latest upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
roji committed Jul 29, 2022
1 parent f5adc78 commit b0fd912
Show file tree
Hide file tree
Showing 9 changed files with 452 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ protected virtual Expression VisitDelete(DeleteExpression deleteExpression)
|| selectExpression.GroupBy.Count > 0
|| selectExpression.Projection.Count > 0)
{
throw new InvalidOperationException(RelationalStrings.BulkOperationWithUnsupportedOperatorInSqlGeneration);
throw new InvalidOperationException(
RelationalStrings.BulkOperationWithUnsupportedOperatorInSqlGeneration(nameof(RelationalQueryableExtensions.BulkDelete)));
}

var fromItems = new List<TableExpression>();
Expand Down Expand Up @@ -63,7 +64,9 @@ protected virtual Expression VisitDelete(DeleteExpression deleteExpression)
break;

default:
throw new InvalidOperationException(RelationalStrings.BulkOperationWithUnsupportedOperatorInSqlGeneration);
throw new InvalidOperationException(
RelationalStrings.BulkOperationWithUnsupportedOperatorInSqlGeneration(
nameof(RelationalQueryableExtensions.BulkDelete)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ protected override bool IsValidSelectExpressionForBulkDelete(
// Here we extend this to also inner joins to tables, which we generate via the PostgreSQL-specific USING construct.
if (selectExpression.Offset == null
&& selectExpression.Limit == null
// If entity type has primary key then Distinct is no-op
&& (!selectExpression.IsDistinct || entityShaperExpression.EntityType.FindPrimaryKey() != null)
&& selectExpression.GroupBy.Count == 0
&& selectExpression.Having == null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,71 @@ public class FiltersInheritanceBulkUpdatesNpgsqlTest : FiltersInheritanceBulkUpd
public FiltersInheritanceBulkUpdatesNpgsqlTest(FiltersInheritanceQueryNpgsqlFixture fixture)
: base(fixture)
{
ClearLog();
}

public override async Task Delete_where_hierarchy(bool async)
{
await base.Delete_where_hierarchy(async);

AssertSql(
@"DELETE FROM ""Animals"" AS a
WHERE a.""CountryId"" = 1 AND a.""Name"" = 'Great spotted kiwi'");
}

public override async Task Delete_where_hierarchy_derived(bool async)
{
await base.Delete_where_hierarchy_derived(async);

AssertSql(
@"DELETE FROM ""Animals"" AS a
WHERE a.""Discriminator"" = 'Kiwi' AND a.""CountryId"" = 1 AND a.""Name"" = 'Great spotted kiwi'");
}

public override async Task Delete_where_using_hierarchy(bool async)
{
await base.Delete_where_using_hierarchy(async);

AssertSql(
@"DELETE FROM ""Countries"" AS c
WHERE (
SELECT count(*)::int
FROM ""Animals"" AS a
WHERE a.""CountryId"" = 1 AND c.""Id"" = a.""CountryId"" AND a.""CountryId"" > 0) > 0");
}

public override async Task Delete_where_using_hierarchy_derived(bool async)
{
await base.Delete_where_using_hierarchy_derived(async);

AssertSql(
@"DELETE FROM ""Countries"" AS c
WHERE (
SELECT count(*)::int
FROM ""Animals"" AS a
WHERE a.""CountryId"" = 1 AND c.""Id"" = a.""CountryId"" AND a.""Discriminator"" = 'Kiwi' AND a.""CountryId"" > 0) > 0");
}

public override async Task Delete_where_keyless_entity_mapped_to_sql_query(bool async)
{
await base.Delete_where_keyless_entity_mapped_to_sql_query(async);

AssertSql();
}

public override async Task Delete_where_hierarchy_subquery(bool async)
{
await base.Delete_where_hierarchy_subquery(async);

AssertSql();
}

[ConditionalFact]
public virtual void Check_all_tests_overridden()
=> TestHelpers.AssertAllMethodsOverridden(GetType());

protected override void ClearLog() => Fixture.TestSqlLoggerFactory.Clear();

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,71 @@ public class InheritanceBulkUpdatesNpgsqlTest : InheritanceBulkUpdatesTestBase<I
public InheritanceBulkUpdatesNpgsqlTest(InheritanceQueryNpgsqlFixture fixture)
: base(fixture)
{
ClearLog();
}

public override async Task Delete_where_hierarchy(bool async)
{
await base.Delete_where_hierarchy(async);

AssertSql(
@"DELETE FROM ""Animals"" AS a
WHERE a.""Name"" = 'Great spotted kiwi'");
}

public override async Task Delete_where_hierarchy_derived(bool async)
{
await base.Delete_where_hierarchy_derived(async);

AssertSql(
@"DELETE FROM ""Animals"" AS a
WHERE a.""Discriminator"" = 'Kiwi' AND a.""Name"" = 'Great spotted kiwi'");
}

public override async Task Delete_where_using_hierarchy(bool async)
{
await base.Delete_where_using_hierarchy(async);

AssertSql(
@"DELETE FROM ""Countries"" AS c
WHERE (
SELECT count(*)::int
FROM ""Animals"" AS a
WHERE c.""Id"" = a.""CountryId"" AND a.""CountryId"" > 0) > 0");
}

public override async Task Delete_where_using_hierarchy_derived(bool async)
{
await base.Delete_where_using_hierarchy_derived(async);

AssertSql(
@"DELETE FROM ""Countries"" AS c
WHERE (
SELECT count(*)::int
FROM ""Animals"" AS a
WHERE c.""Id"" = a.""CountryId"" AND a.""Discriminator"" = 'Kiwi' AND a.""CountryId"" > 0) > 0");
}

public override async Task Delete_where_keyless_entity_mapped_to_sql_query(bool async)
{
await base.Delete_where_keyless_entity_mapped_to_sql_query(async);

AssertSql();
}

public override async Task Delete_where_hierarchy_subquery(bool async)
{
await base.Delete_where_hierarchy_subquery(async);

AssertSql();
}

[ConditionalFact]
public virtual void Check_all_tests_overridden()
=> TestHelpers.AssertAllMethodsOverridden(GetType());

protected override void ClearLog() => Fixture.TestSqlLoggerFactory.Clear();

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public NorthwindBulkUpdatesNpgsqlTest(NorthwindQueryNpgsqlFixture<NoopModelCusto
: base(fixture)
{
ClearLog();
Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
// Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}

[ConditionalFact]
Expand Down Expand Up @@ -386,6 +386,22 @@ public override async Task Delete_non_entity_projection_3(bool async)
AssertSql();
}

public override async Task Delete_FromSql_converted_to_subquery(bool async)
{
await base.Delete_FromSql_converted_to_subquery(async);

AssertSql(
@"DELETE FROM ""Order Details"" AS o
WHERE EXISTS (
SELECT 1
FROM (
SELECT ""OrderID"", ""ProductID"", ""UnitPrice"", ""Quantity"", ""Discount""
FROM ""Order Details""
WHERE ""OrderID"" < 10300
) AS m
WHERE m.""OrderID"" = o.""OrderID"" AND m.""ProductID"" = o.""ProductID"")");
}

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using Microsoft.EntityFrameworkCore.BulkUpdates;
using Npgsql.EntityFrameworkCore.PostgreSQL.Query;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class TPCFiltersInheritanceBulkUpdatesNpgsqlTest : TPCFiltersInheritanceBulkUpdatesTestBase<TPCFiltersInheritanceQueryNpgsqlFixture>
{
public TPCFiltersInheritanceBulkUpdatesNpgsqlTest(TPCFiltersInheritanceQueryNpgsqlFixture fixture)
: base(fixture)
{
ClearLog();
}

[ConditionalFact]
public virtual void Check_all_tests_overridden()
=> TestHelpers.AssertAllMethodsOverridden(GetType());

public override async Task Delete_where_hierarchy(bool async)
{
await base.Delete_where_hierarchy(async);

AssertSql();
}

public override async Task Delete_where_hierarchy_derived(bool async)
{
await base.Delete_where_hierarchy_derived(async);

AssertSql(
@"DELETE FROM ""Kiwi"" AS k
WHERE k.""CountryId"" = 1 AND k.""Name"" = 'Great spotted kiwi'");
}

public override async Task Delete_where_using_hierarchy(bool async)
{
await base.Delete_where_using_hierarchy(async);

AssertSql(
@"DELETE FROM ""Countries"" AS c
WHERE (
SELECT count(*)::int
FROM (
SELECT e.""Id"", e.""CountryId"", e.""Name"", e.""Species"", e.""EagleId"", e.""IsFlightless"", e.""Group"", NULL AS ""FoundOn"", 'Eagle' AS ""Discriminator""
FROM ""Eagle"" AS e
UNION ALL
SELECT k.""Id"", k.""CountryId"", k.""Name"", k.""Species"", k.""EagleId"", k.""IsFlightless"", NULL AS ""Group"", k.""FoundOn"", 'Kiwi' AS ""Discriminator""
FROM ""Kiwi"" AS k
) AS t
WHERE t.""CountryId"" = 1 AND c.""Id"" = t.""CountryId"" AND t.""CountryId"" > 0) > 0");
}

public override async Task Delete_where_using_hierarchy_derived(bool async)
{
await base.Delete_where_using_hierarchy_derived(async);

AssertSql(
@"DELETE FROM ""Countries"" AS c
WHERE (
SELECT count(*)::int
FROM (
SELECT k.""Id"", k.""CountryId"", k.""Name"", k.""Species"", k.""EagleId"", k.""IsFlightless"", NULL AS ""Group"", k.""FoundOn"", 'Kiwi' AS ""Discriminator""
FROM ""Kiwi"" AS k
) AS t
WHERE t.""CountryId"" = 1 AND c.""Id"" = t.""CountryId"" AND t.""CountryId"" > 0) > 0");
}

public override async Task Delete_where_keyless_entity_mapped_to_sql_query(bool async)
{
await base.Delete_where_keyless_entity_mapped_to_sql_query(async);

AssertSql();
}

public override async Task Delete_where_hierarchy_subquery(bool async)
{
await base.Delete_where_hierarchy_subquery(async);

AssertSql();
}

protected override void ClearLog() => Fixture.TestSqlLoggerFactory.Clear();

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Microsoft.EntityFrameworkCore.BulkUpdates;
using Npgsql.EntityFrameworkCore.PostgreSQL.Query;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class TPCInheritanceBulkUpdatesNpgsqlTest : TPCInheritanceBulkUpdatesTestBase<TPCInheritanceQueryNpgsqlFixture>
{
public TPCInheritanceBulkUpdatesNpgsqlTest(TPCInheritanceQueryNpgsqlFixture fixture)
: base(fixture)
{
ClearLog();
}

[ConditionalFact]
public virtual void Check_all_tests_overridden()
=> TestHelpers.AssertAllMethodsOverridden(GetType());

public override async Task Delete_where_hierarchy(bool async)
{
await base.Delete_where_hierarchy(async);

AssertSql();
}

public override async Task Delete_where_hierarchy_derived(bool async)
{
await base.Delete_where_hierarchy_derived(async);

AssertSql(
@"DELETE FROM ""Kiwi"" AS k
WHERE k.""Name"" = 'Great spotted kiwi'");
}

public override async Task Delete_where_using_hierarchy(bool async)
{
await base.Delete_where_using_hierarchy(async);

AssertSql(
@"DELETE FROM ""Countries"" AS c
WHERE (
SELECT count(*)::int
FROM (
SELECT e.""Id"", e.""CountryId"", e.""Name"", e.""Species"", e.""EagleId"", e.""IsFlightless"", e.""Group"", NULL AS ""FoundOn"", 'Eagle' AS ""Discriminator""
FROM ""Eagle"" AS e
UNION ALL
SELECT k.""Id"", k.""CountryId"", k.""Name"", k.""Species"", k.""EagleId"", k.""IsFlightless"", NULL AS ""Group"", k.""FoundOn"", 'Kiwi' AS ""Discriminator""
FROM ""Kiwi"" AS k
) AS t
WHERE c.""Id"" = t.""CountryId"" AND t.""CountryId"" > 0) > 0");
}

public override async Task Delete_where_using_hierarchy_derived(bool async)
{
await base.Delete_where_using_hierarchy_derived(async);

AssertSql(
@"DELETE FROM ""Countries"" AS c
WHERE (
SELECT count(*)::int
FROM (
SELECT k.""Id"", k.""CountryId"", k.""Name"", k.""Species"", k.""EagleId"", k.""IsFlightless"", NULL AS ""Group"", k.""FoundOn"", 'Kiwi' AS ""Discriminator""
FROM ""Kiwi"" AS k
) AS t
WHERE c.""Id"" = t.""CountryId"" AND t.""CountryId"" > 0) > 0");
}

public override async Task Delete_where_keyless_entity_mapped_to_sql_query(bool async)
{
await base.Delete_where_keyless_entity_mapped_to_sql_query(async);

AssertSql();
}

public override async Task Delete_where_hierarchy_subquery(bool async)
{
await base.Delete_where_hierarchy_subquery(async);

AssertSql();
}

protected override void ClearLog() => Fixture.TestSqlLoggerFactory.Clear();

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}

Loading

0 comments on commit b0fd912

Please sign in to comment.