Skip to content

Commit

Permalink
Sync to latest upstream PR and support inner join over subquery
Browse files Browse the repository at this point in the history
  • Loading branch information
roji committed Jul 30, 2022
1 parent b0fd912 commit 346d413
Show file tree
Hide file tree
Showing 17 changed files with 246 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ public sealed class PostgresDeleteExpression : Expression, IPrintableExpression
/// <summary>
/// Additional tables which can be referenced in the predicate.
/// </summary>
public IReadOnlyList<TableExpression> FromItems { get; }
public IReadOnlyList<TableExpressionBase> FromItems { get; }

/// <summary>
/// The WHERE predicate for the DELETE.
/// </summary>
public SqlExpression? Predicate { get; }

public PostgresDeleteExpression(TableExpression table, IReadOnlyList<TableExpression> fromItems, SqlExpression? predicate)
public PostgresDeleteExpression(TableExpression table, IReadOnlyList<TableExpressionBase> fromItems, SqlExpression? predicate)
=> (Table, FromItems, Predicate) = (table, fromItems, predicate);

/// <inheritdoc />
Expand All @@ -44,9 +44,21 @@ public void Print(ExpressionPrinter expressionPrinter)

if (FromItems.Count > 0)
{
expressionPrinter
.Append("USING ")
.Append(string.Join(", ", FromItems.Select(fi => $"{fi.Name} AS {fi.Alias}")));
var first = true;
foreach (var fromItem in FromItems)
{
if (first)
{
expressionPrinter.Append("USING ");
first = false;
}
else
{
expressionPrinter.Append(", ");
}

expressionPrinter.Visit(fromItem);
}
}

if (Predicate is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ protected virtual Expression VisitDelete(DeleteExpression deleteExpression)
|| selectExpression.Projection.Count > 0)
{
throw new InvalidOperationException(
RelationalStrings.BulkOperationWithUnsupportedOperatorInSqlGeneration(nameof(RelationalQueryableExtensions.BulkDelete)));
RelationalStrings.BulkOperationWithUnsupportedOperatorInSqlGeneration(nameof(RelationalQueryableExtensions.ExecuteDelete)));
}

var fromItems = new List<TableExpression>();
var fromItems = new List<TableExpressionBase>();
SqlExpression? joinPredicates = null;

// The SelectExpression also contains the target table being modified (same as deleteExpression.Table).
Expand All @@ -50,7 +50,7 @@ protected virtual Expression VisitDelete(DeleteExpression deleteExpression)

break;

case InnerJoinExpression { Table: TableExpression tableExpression } innerJoinExpression:
case InnerJoinExpression { Table: { } tableExpression } innerJoinExpression:
if (tableExpression != deleteExpression.Table)
{
fromItems.Add(tableExpression);
Expand All @@ -66,7 +66,7 @@ protected virtual Expression VisitDelete(DeleteExpression deleteExpression)
default:
throw new InvalidOperationException(
RelationalStrings.BulkOperationWithUnsupportedOperatorInSqlGeneration(
nameof(RelationalQueryableExtensions.BulkDelete)));
nameof(RelationalQueryableExtensions.ExecuteDelete)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected override bool IsValidSelectExpressionForBulkDelete(
{
table = selectExpression.Tables[0];
}
else if (selectExpression.Tables.All(t => t is TableExpression or InnerJoinExpression { Table: TableExpression }))
else if (selectExpression.Tables.All(t => t is TableExpression or InnerJoinExpression))
{
var projectionBindingExpression = (ProjectionBindingExpression)entityShaperExpression.ValueBufferExpression;
var entityProjectionExpression = (EntityProjectionExpression)selectExpression.GetProjection(projectionBindingExpression);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class FiltersInheritanceBulkUpdatesNpgsqlFixture : InheritanceBulkUpdatesNpgsqlFixture
{
protected override bool EnableFilters
=> true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class FiltersInheritanceBulkUpdatesNpgsqlTest : FiltersInheritanceBulkUpdatesTestBase<FiltersInheritanceQueryNpgsqlFixture>
public class FiltersInheritanceBulkUpdatesNpgsqlTest : FiltersInheritanceBulkUpdatesTestBase<FiltersInheritanceBulkUpdatesNpgsqlFixture>
{
public FiltersInheritanceBulkUpdatesNpgsqlTest(FiltersInheritanceQueryNpgsqlFixture fixture)
public FiltersInheritanceBulkUpdatesNpgsqlTest(FiltersInheritanceBulkUpdatesNpgsqlFixture fixture)
: base(fixture)
{
ClearLog();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Microsoft.EntityFrameworkCore.BulkUpdates;
using Npgsql.EntityFrameworkCore.PostgreSQL.TestUtilities;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class InheritanceBulkUpdatesNpgsqlFixture : InheritanceBulkUpdatesRelationalFixture
{
protected override ITestStoreFactory TestStoreFactory
=> NpgsqlTestStoreFactory.Instance;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using Microsoft.EntityFrameworkCore.BulkUpdates;
using Npgsql.EntityFrameworkCore.PostgreSQL.Query;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class InheritanceBulkUpdatesNpgsqlTest : InheritanceBulkUpdatesTestBase<InheritanceQueryNpgsqlFixture>
public class InheritanceBulkUpdatesNpgsqlTest : InheritanceBulkUpdatesTestBase<InheritanceBulkUpdatesNpgsqlFixture>
{
public InheritanceBulkUpdatesNpgsqlTest(InheritanceQueryNpgsqlFixture fixture)
public InheritanceBulkUpdatesNpgsqlTest(InheritanceBulkUpdatesNpgsqlFixture fixture)
: base(fixture)
{
ClearLog();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Microsoft.EntityFrameworkCore.BulkUpdates;
using Microsoft.EntityFrameworkCore.TestModels.Northwind;
using Npgsql.EntityFrameworkCore.PostgreSQL.TestUtilities;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class NorthwindBulkUpdatesNpgsqlFixture<TModelCustomizer> : NorthwindBulkUpdatesFixture<TModelCustomizer>
where TModelCustomizer: IModelCustomizer, new()
{
protected override ITestStoreFactory TestStoreFactory
=> NpgsqlNorthwindTestStoreFactory.Instance;

protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
{
base.OnModelCreating(modelBuilder, context);

modelBuilder.Entity<Customer>()
.Property(c => c.CustomerID)
.HasColumnType("char(5)");

modelBuilder.Entity<Employee>(
b =>
{
b.Property(c => c.EmployeeID).HasColumnType("int");
b.Property(c => c.ReportsTo).HasColumnType("int");
});

modelBuilder.Entity<Order>(
b =>
{
b.Property(o => o.EmployeeID).HasColumnType("int");
b.Property(o => o.OrderDate).HasColumnType("timestamp without time zone");
});

modelBuilder.Entity<OrderDetail>()
.Property(od => od.UnitPrice)
.HasColumnType("money");

modelBuilder.Entity<Product>(
b =>
{
b.Property(p => p.UnitPrice).HasColumnType("money");
b.Property(p => p.UnitsInStock).HasColumnType("smallint");
});

modelBuilder.Entity<MostExpensiveProduct>()
.Property(p => p.UnitPrice)
.HasColumnType("money");
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using Microsoft.EntityFrameworkCore.BulkUpdates;
using Npgsql.EntityFrameworkCore.PostgreSQL.Query;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class NorthwindBulkUpdatesNpgsqlTest : NorthwindBulkUpdatesTestBase<NorthwindQueryNpgsqlFixture<NoopModelCustomizer>>
public class NorthwindBulkUpdatesNpgsqlTest : NorthwindBulkUpdatesTestBase<NorthwindBulkUpdatesNpgsqlFixture<NoopModelCustomizer>>
{
public NorthwindBulkUpdatesNpgsqlTest(NorthwindQueryNpgsqlFixture<NoopModelCustomizer> fixture, ITestOutputHelper testOutputHelper)
public NorthwindBulkUpdatesNpgsqlTest(
NorthwindBulkUpdatesNpgsqlFixture<NoopModelCustomizer> fixture,
ITestOutputHelper testOutputHelper)
: base(fixture)
{
ClearLog();
Expand Down Expand Up @@ -400,6 +401,104 @@ SELECT 1
WHERE ""OrderID"" < 10300
) AS m
WHERE m.""OrderID"" = o.""OrderID"" AND m.""ProductID"" = o.""ProductID"")");
}

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

AssertSql(
@"@__p_1='100'
@__p_0='0'
DELETE FROM ""Order Details"" AS o
USING (
SELECT o0.""OrderID"", o0.""CustomerID"", o0.""EmployeeID"", o0.""OrderDate""
FROM ""Orders"" AS o0
WHERE o0.""OrderID"" < 10300
ORDER BY o0.""OrderID"" NULLS FIRST
LIMIT @__p_1 OFFSET @__p_0
) AS t
WHERE o.""OrderID"" = t.""OrderID""");
}

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

AssertSql(
@"@__p_1='100'
@__p_0='0'
DELETE FROM ""Order Details"" AS o
WHERE EXISTS (
SELECT 1
FROM ""Order Details"" AS o0
LEFT JOIN (
SELECT o1.""OrderID"", o1.""CustomerID"", o1.""EmployeeID"", o1.""OrderDate""
FROM ""Orders"" AS o1
WHERE o1.""OrderID"" < 10300
ORDER BY o1.""OrderID"" NULLS FIRST
LIMIT @__p_1 OFFSET @__p_0
) AS t ON o0.""OrderID"" = t.""OrderID""
WHERE o0.""OrderID"" < 10276 AND o0.""OrderID"" = o.""OrderID"" AND o0.""ProductID"" = o.""ProductID"")");
}

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

AssertSql(
@"DELETE FROM ""Order Details"" AS o
WHERE EXISTS (
SELECT 1
FROM ""Order Details"" AS o0
CROSS JOIN (
SELECT o1.""OrderID"", o1.""CustomerID"", o1.""EmployeeID"", o1.""OrderDate""
FROM ""Orders"" AS o1
WHERE o1.""OrderID"" < 10300
ORDER BY o1.""OrderID"" NULLS FIRST
LIMIT 100 OFFSET 0
) AS t
WHERE o0.""OrderID"" < 10276 AND o0.""OrderID"" = o.""OrderID"" AND o0.""ProductID"" = o.""ProductID"")");
}

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

AssertSql(
@"DELETE FROM ""Order Details"" AS o
WHERE EXISTS (
SELECT 1
FROM ""Order Details"" AS o0
JOIN LATERAL (
SELECT o1.""OrderID"", o1.""CustomerID"", o1.""EmployeeID"", o1.""OrderDate""
FROM ""Orders"" AS o1
WHERE o1.""OrderID"" < o0.""OrderID""
ORDER BY o1.""OrderID"" NULLS FIRST
LIMIT 100 OFFSET 0
) AS t ON TRUE
WHERE o0.""OrderID"" < 10276 AND o0.""OrderID"" = o.""OrderID"" AND o0.""ProductID"" = o.""ProductID"")");
}

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

AssertSql(
@"DELETE FROM ""Order Details"" AS o
WHERE EXISTS (
SELECT 1
FROM ""Order Details"" AS o0
LEFT JOIN LATERAL (
SELECT o1.""OrderID"", o1.""CustomerID"", o1.""EmployeeID"", o1.""OrderDate""
FROM ""Orders"" AS o1
WHERE o1.""OrderID"" < o0.""OrderID""
ORDER BY o1.""OrderID"" NULLS FIRST
LIMIT 100 OFFSET 0
) AS t ON TRUE
WHERE o0.""OrderID"" < 10276 AND o0.""OrderID"" = o.""OrderID"" AND o0.""ProductID"" = o.""ProductID"")");
}

private void AssertSql(params string[] expected)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class TPCFiltersInheritanceBulkUpdatesNpgsqlFixture : TPCInheritanceBulkUpdatesNpgsqlFixture
{
protected override bool EnableFilters => true;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using Microsoft.EntityFrameworkCore.BulkUpdates;
using Npgsql.EntityFrameworkCore.PostgreSQL.Query;
using Npgsql.EntityFrameworkCore.PostgreSQL.TestUtilities;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class TPCFiltersInheritanceBulkUpdatesNpgsqlTest : TPCFiltersInheritanceBulkUpdatesTestBase<TPCFiltersInheritanceQueryNpgsqlFixture>
public class TPCFiltersInheritanceBulkUpdatesNpgsqlTest
: TPCFiltersInheritanceBulkUpdatesTestBase<TPCFiltersInheritanceBulkUpdatesNpgsqlFixture>
{
public TPCFiltersInheritanceBulkUpdatesNpgsqlTest(TPCFiltersInheritanceQueryNpgsqlFixture fixture)
public TPCFiltersInheritanceBulkUpdatesNpgsqlTest(TPCFiltersInheritanceBulkUpdatesNpgsqlFixture fixture)
: base(fixture)
{
ClearLog();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Microsoft.EntityFrameworkCore.BulkUpdates;
using Npgsql.EntityFrameworkCore.PostgreSQL.TestUtilities;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class TPCInheritanceBulkUpdatesNpgsqlFixture : TPCInheritanceBulkUpdatesFixture
{
protected override ITestStoreFactory TestStoreFactory
=> NpgsqlTestStoreFactory.Instance;

protected override bool UseGeneratedKeys
=> false;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using Microsoft.EntityFrameworkCore.BulkUpdates;
using Npgsql.EntityFrameworkCore.PostgreSQL.Query;
using Npgsql.EntityFrameworkCore.PostgreSQL.TestUtilities;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class TPCInheritanceBulkUpdatesNpgsqlTest : TPCInheritanceBulkUpdatesTestBase<TPCInheritanceQueryNpgsqlFixture>
public class TPCInheritanceBulkUpdatesNpgsqlTest
: TPCInheritanceBulkUpdatesTestBase<TPCInheritanceBulkUpdatesNpgsqlFixture>
{
public TPCInheritanceBulkUpdatesNpgsqlTest(TPCInheritanceQueryNpgsqlFixture fixture)
public TPCInheritanceBulkUpdatesNpgsqlTest(TPCInheritanceBulkUpdatesNpgsqlFixture fixture)
: base(fixture)
{
ClearLog();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class TPTFiltersInheritanceBulkUpdatesNpgsqlFixture : TPTInheritanceBulkUpdatesNpgsqlFixture
{
protected override bool EnableFilters => true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class TPTFiltersInheritanceBulkUpdatesSqlServerTest : TPTFiltersInheritanceBulkUpdatesTestBase<TPTFiltersInheritanceQuerySqlServerFixture>
public class TPTFiltersInheritanceBulkUpdatesSqlServerTest
: TPTFiltersInheritanceBulkUpdatesTestBase<TPTFiltersInheritanceBulkUpdatesNpgsqlFixture>
{
public TPTFiltersInheritanceBulkUpdatesSqlServerTest(TPTFiltersInheritanceQuerySqlServerFixture fixture)
public TPTFiltersInheritanceBulkUpdatesSqlServerTest(TPTFiltersInheritanceBulkUpdatesNpgsqlFixture fixture)
: base(fixture)
{
ClearLog();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Microsoft.EntityFrameworkCore.BulkUpdates;
using Npgsql.EntityFrameworkCore.PostgreSQL.TestUtilities;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class TPTInheritanceBulkUpdatesNpgsqlFixture : TPTInheritanceBulkUpdatesFixture
{
protected override ITestStoreFactory TestStoreFactory
=> NpgsqlTestStoreFactory.Instance;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

namespace Npgsql.EntityFrameworkCore.PostgreSQL.BulkUpdates;

public class TPTInheritanceBulkUpdatesNpgsqlTest : TPTInheritanceBulkUpdatesTestBase<TPTInheritanceQueryNpgsqlFixture>
public class TPTInheritanceBulkUpdatesNpgsqlTest : TPTInheritanceBulkUpdatesTestBase<TPTInheritanceBulkUpdatesNpgsqlFixture>
{
public TPTInheritanceBulkUpdatesNpgsqlTest(TPTInheritanceQueryNpgsqlFixture fixture)
public TPTInheritanceBulkUpdatesNpgsqlTest(TPTInheritanceBulkUpdatesNpgsqlFixture fixture)
: base(fixture)
{
ClearLog();
Expand Down

0 comments on commit 346d413

Please sign in to comment.