diff --git a/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs b/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs index 4c3e8a1cf..6335c3429 100644 --- a/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs +++ b/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs @@ -114,7 +114,6 @@ public static IServiceCollection AddEntityFrameworkNpgsql(this IServiceCollectio .TryAdd() .TryAdd() .TryAdd() - .TryAdd() .TryAdd() .TryAdd() .TryAdd() diff --git a/src/EFCore.PG/Query/Internal/NpgsqlQueryRootProcessor.cs b/src/EFCore.PG/Query/Internal/NpgsqlQueryRootProcessor.cs deleted file mode 100644 index ade336f61..000000000 --- a/src/EFCore.PG/Query/Internal/NpgsqlQueryRootProcessor.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; - -namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal; - -/// -/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to -/// the same compatibility standards as public APIs. It may be changed or removed without notice in -/// any release. You should only use it directly in your code with extreme caution and knowing that -/// doing so can result in application failures when updating to a new Entity Framework Core release. -/// -public class NpgsqlQueryRootProcessor : RelationalQueryRootProcessor -{ - private readonly bool _supportsUnnest; - - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public NpgsqlQueryRootProcessor( - QueryTranslationPreprocessorDependencies dependencies, - RelationalQueryTranslationPreprocessorDependencies relationalDependencies, - QueryCompilationContext queryCompilationContext, - INpgsqlSingletonOptions npgsqlSingletonOptions) - : base(dependencies, relationalDependencies, queryCompilationContext) - { - _supportsUnnest = !npgsqlSingletonOptions.UseRedshift; - } - - /// - /// Converts a to a , to be later translated to - /// PostgreSQL unnest over an array parameter. - /// - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - protected override bool ShouldConvertToParameterQueryRoot(ParameterExpression parameterExpression) - => _supportsUnnest; -} diff --git a/src/EFCore.PG/Query/Internal/NpgsqlQueryTranslationPreprocessor.cs b/src/EFCore.PG/Query/Internal/NpgsqlQueryTranslationPreprocessor.cs deleted file mode 100644 index b7ccfc05d..000000000 --- a/src/EFCore.PG/Query/Internal/NpgsqlQueryTranslationPreprocessor.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; - -namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal; - -/// -/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to -/// the same compatibility standards as public APIs. It may be changed or removed without notice in -/// any release. You should only use it directly in your code with extreme caution and knowing that -/// doing so can result in application failures when updating to a new Entity Framework Core release. -/// -public class NpgsqlQueryTranslationPreprocessor : RelationalQueryTranslationPreprocessor -{ - private readonly INpgsqlSingletonOptions _npgsqlSingletonOptions; - - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public NpgsqlQueryTranslationPreprocessor( - QueryTranslationPreprocessorDependencies dependencies, - RelationalQueryTranslationPreprocessorDependencies relationalDependencies, - INpgsqlSingletonOptions npgsqlSingletonOptions, - QueryCompilationContext queryCompilationContext) - : base(dependencies, relationalDependencies, queryCompilationContext) - { - _npgsqlSingletonOptions = npgsqlSingletonOptions; - } - - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - protected override Expression ProcessQueryRoots(Expression expression) - => new NpgsqlQueryRootProcessor(Dependencies, RelationalDependencies, QueryCompilationContext, _npgsqlSingletonOptions) - .Visit(expression); -} diff --git a/src/EFCore.PG/Query/Internal/NpgsqlQueryTranslationPreprocessorFactory.cs b/src/EFCore.PG/Query/Internal/NpgsqlQueryTranslationPreprocessorFactory.cs deleted file mode 100644 index c1f9e818b..000000000 --- a/src/EFCore.PG/Query/Internal/NpgsqlQueryTranslationPreprocessorFactory.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; - -namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal; - -/// -/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to -/// the same compatibility standards as public APIs. It may be changed or removed without notice in -/// any release. You should only use it directly in your code with extreme caution and knowing that -/// doing so can result in application failures when updating to a new Entity Framework Core release. -/// -public class NpgsqlQueryTranslationPreprocessorFactory : IQueryTranslationPreprocessorFactory -{ - private readonly INpgsqlSingletonOptions _npgsqlSingletonOptions; - - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public NpgsqlQueryTranslationPreprocessorFactory( - QueryTranslationPreprocessorDependencies dependencies, - RelationalQueryTranslationPreprocessorDependencies relationalDependencies, - INpgsqlSingletonOptions npgsqlSingletonOptions) - { - Dependencies = dependencies; - RelationalDependencies = relationalDependencies; - _npgsqlSingletonOptions = npgsqlSingletonOptions; - } - - /// - /// Dependencies for this service. - /// - protected virtual QueryTranslationPreprocessorDependencies Dependencies { get; } - - /// - /// Relational provider-specific dependencies for this service. - /// - protected virtual RelationalQueryTranslationPreprocessorDependencies RelationalDependencies { get; } - - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public virtual QueryTranslationPreprocessor Create(QueryCompilationContext queryCompilationContext) - => new NpgsqlQueryTranslationPreprocessor(Dependencies, RelationalDependencies, _npgsqlSingletonOptions, queryCompilationContext); -} diff --git a/src/EFCore.PG/Query/Internal/NpgsqlQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.PG/Query/Internal/NpgsqlQueryableMethodTranslatingExpressionVisitor.cs index d258ebb8c..84ec8668a 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlQueryableMethodTranslatingExpressionVisitor.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions; using Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal; @@ -18,9 +19,9 @@ public class NpgsqlQueryableMethodTranslatingExpressionVisitor : RelationalQuery private readonly RelationalQueryCompilationContext _queryCompilationContext; private readonly NpgsqlTypeMappingSource _typeMappingSource; private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly bool _isRedshift; private RelationalTypeMapping? _ordinalityTypeMapping; - #region MethodInfos private static readonly MethodInfo Like2MethodInfo = @@ -46,12 +47,14 @@ private static readonly MethodInfo ILike2MethodInfo public NpgsqlQueryableMethodTranslatingExpressionVisitor( QueryableMethodTranslatingExpressionVisitorDependencies dependencies, RelationalQueryableMethodTranslatingExpressionVisitorDependencies relationalDependencies, - RelationalQueryCompilationContext queryCompilationContext) + RelationalQueryCompilationContext queryCompilationContext, + INpgsqlSingletonOptions npgsqlSingletonOptions) : base(dependencies, relationalDependencies, queryCompilationContext) { _queryCompilationContext = queryCompilationContext; _typeMappingSource = (NpgsqlTypeMappingSource)relationalDependencies.TypeMappingSource; _sqlExpressionFactory = (NpgsqlSqlExpressionFactory)relationalDependencies.SqlExpressionFactory; + _isRedshift = npgsqlSingletonOptions.UseRedshift; } /// @@ -66,6 +69,7 @@ protected NpgsqlQueryableMethodTranslatingExpressionVisitor(NpgsqlQueryableMetho _queryCompilationContext = parentVisitor._queryCompilationContext; _typeMappingSource = parentVisitor._typeMappingSource; _sqlExpressionFactory = parentVisitor._sqlExpressionFactory; + _isRedshift = parentVisitor._isRedshift; } /// @@ -83,11 +87,18 @@ protected override QueryableMethodTranslatingExpressionVisitor CreateSubqueryVis /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override ShapedQueryExpression TranslatePrimitiveCollection( + protected override ShapedQueryExpression? TranslatePrimitiveCollection( SqlExpression sqlExpression, IProperty? property, string tableAlias) { + if (_isRedshift) + { + AddTranslationErrorDetails("Redshift does not support unnest, which is required for most forms of querying of JSON arrays."); + + return null; + } + var elementClrType = sqlExpression.Type.GetSequenceType(); var elementTypeMapping = (RelationalTypeMapping?)sqlExpression.TypeMapping?.ElementTypeMapping; diff --git a/src/EFCore.PG/Query/Internal/NpgsqlQueryableMethodTranslatingExpressionVisitorFactory.cs b/src/EFCore.PG/Query/Internal/NpgsqlQueryableMethodTranslatingExpressionVisitorFactory.cs index b6e2eb279..39d8377f7 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlQueryableMethodTranslatingExpressionVisitorFactory.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlQueryableMethodTranslatingExpressionVisitorFactory.cs @@ -1,3 +1,5 @@ +using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; + namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal; /// @@ -8,6 +10,8 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal; /// public class NpgsqlQueryableMethodTranslatingExpressionVisitorFactory : IQueryableMethodTranslatingExpressionVisitorFactory { + private readonly INpgsqlSingletonOptions _npgsqlSingletonOptions; + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -16,10 +20,12 @@ public class NpgsqlQueryableMethodTranslatingExpressionVisitorFactory : IQueryab /// public NpgsqlQueryableMethodTranslatingExpressionVisitorFactory( QueryableMethodTranslatingExpressionVisitorDependencies dependencies, - RelationalQueryableMethodTranslatingExpressionVisitorDependencies relationalDependencies) + RelationalQueryableMethodTranslatingExpressionVisitorDependencies relationalDependencies, + INpgsqlSingletonOptions npgsqlSingletonOptions) { Dependencies = dependencies; RelationalDependencies = relationalDependencies; + _npgsqlSingletonOptions = npgsqlSingletonOptions; } /// @@ -48,5 +54,6 @@ public virtual QueryableMethodTranslatingExpressionVisitor Create(QueryCompilati => new NpgsqlQueryableMethodTranslatingExpressionVisitor( Dependencies, RelationalDependencies, - (RelationalQueryCompilationContext)queryCompilationContext); + (RelationalQueryCompilationContext)queryCompilationContext, + _npgsqlSingletonOptions); }