diff --git a/Directory.Packages.props b/Directory.Packages.props index 64d0ed81aa698f49e3431258a7f05b0d9bd8fadb..0dd8d893ab327ae770c923fe606be5ccecf4b4b8 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,8 +1,8 @@ - 6.0.0 - 6.0.0 - 7.0.0-preview.1-ci.20211203T135215 + 7.0.0-alpha.1.22058.1 + 7.0.0-alpha.1.22052.8 + 7.0.0-preview.1-ci.20220109T124254 @@ -22,7 +22,7 @@ - + diff --git a/NuGet.config b/NuGet.config index f1a8d07a32ef9bedb9fe00adb7ab22fb402f0d2b..6fdd95f98ac51a1b553a00d05baae7839b690378 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,7 +1,9 @@ - + + + diff --git a/src/EFCore.PG/Diagnostics/NpgsqlEventId.cs b/src/EFCore.PG/Diagnostics/NpgsqlEfEventId.cs similarity index 99% rename from src/EFCore.PG/Diagnostics/NpgsqlEventId.cs rename to src/EFCore.PG/Diagnostics/NpgsqlEfEventId.cs index 1aeadf87ca6bc9cd4c866a1a4923bcc5f393252a..8f25a13d21d54910f4b13ff60b20d60bf25eabe3 100644 --- a/src/EFCore.PG/Diagnostics/NpgsqlEventId.cs +++ b/src/EFCore.PG/Diagnostics/NpgsqlEfEventId.cs @@ -11,7 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Diagnostics; /// behavior of warnings. /// /// -public static class NpgsqlEventId +public static class NpgsqlEfEventId { // Warning: These values must not change between releases. // Only add new values to the end of sections, never in the middle. diff --git a/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs b/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs index ebbc20a3bcff41de59884a0eeebc2fdc7fa98c98..bed5e6042bcef9f7b8c893937bb65f2d51cbfdf1 100644 --- a/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs +++ b/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs @@ -564,7 +564,7 @@ protected override void Generate(AlterColumnOperation operation, IModel? model, { case null: // Drop the identity, converting the column to a regular int - builder.AppendLine(alterBase).AppendLine("DROP IDENTITY;"); + builder.Append(alterBase).AppendLine("DROP IDENTITY;"); break; case NpgsqlValueGenerationStrategy.IdentityAlwaysColumn: builder.Append(alterBase).AppendLine("SET GENERATED ALWAYS;"); diff --git a/src/EFCore.PG/Properties/NpgsqlStrings.Designer.cs b/src/EFCore.PG/Properties/NpgsqlStrings.Designer.cs index f91d5eb5509a3bfb872fcbadb5a37b0e51febe2c..6c01246bb44b493d645f16522cea14a2225644a1 100644 --- a/src/EFCore.PG/Properties/NpgsqlStrings.Designer.cs +++ b/src/EFCore.PG/Properties/NpgsqlStrings.Designer.cs @@ -158,12 +158,12 @@ public static EventDefinition LogEnumColumnSkipped(IDiagnosticsLogger lo logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.EnumColumnSkippedWarning, + NpgsqlEfEventId.EnumColumnSkippedWarning, LogLevel.Warning, - "NpgsqlEventId.EnumColumnSkippedWarning", + "NpgsqlEfEventId.EnumColumnSkippedWarning", level => LoggerMessage.Define( level, - NpgsqlEventId.EnumColumnSkippedWarning, + NpgsqlEfEventId.EnumColumnSkippedWarning, _resourceManager.GetString("LogEnumColumnSkipped")!))); } @@ -183,12 +183,12 @@ public static EventDefinition LogEnumColumnSkipped(IDiagnosticsLogger lo logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.ExpressionIndexSkippedWarning, + NpgsqlEfEventId.ExpressionIndexSkippedWarning, LogLevel.Warning, - "NpgsqlEventId.ExpressionIndexSkippedWarning", + "NpgsqlEfEventId.ExpressionIndexSkippedWarning", level => LoggerMessage.Define( level, - NpgsqlEventId.ExpressionIndexSkippedWarning, + NpgsqlEfEventId.ExpressionIndexSkippedWarning, _resourceManager.GetString("LogExpressionIndexSkipped")!))); } @@ -208,12 +208,12 @@ public static EventDefinition LogEnumColumnSkipped(IDiagnosticsLogger lo logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.CollationFound, + NpgsqlEfEventId.CollationFound, LogLevel.Debug, - "NpgsqlEventId.CollationFound", + "NpgsqlEfEventId.CollationFound", level => LoggerMessage.Define( level, - NpgsqlEventId.CollationFound, + NpgsqlEfEventId.CollationFound, _resourceManager.GetString("LogFoundCollation")!))); } @@ -233,9 +233,9 @@ public static FallbackEventDefinition LogFoundColumn(IDiagnosticsLogger logger) logger, static logger => new FallbackEventDefinition( logger.Options, - NpgsqlEventId.ColumnFound, + NpgsqlEfEventId.ColumnFound, LogLevel.Debug, - "NpgsqlEventId.ColumnFound", + "NpgsqlEfEventId.ColumnFound", _resourceManager.GetString("LogFoundColumn")!)); } @@ -255,12 +255,12 @@ public static FallbackEventDefinition LogFoundColumn(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.ForeignKeyFound, + NpgsqlEfEventId.ForeignKeyFound, LogLevel.Debug, - "NpgsqlEventId.ForeignKeyFound", + "NpgsqlEfEventId.ForeignKeyFound", level => LoggerMessage.Define( level, - NpgsqlEventId.ForeignKeyFound, + NpgsqlEfEventId.ForeignKeyFound, _resourceManager.GetString("LogFoundForeignKey")!))); } @@ -280,12 +280,12 @@ public static FallbackEventDefinition LogFoundColumn(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.IndexFound, + NpgsqlEfEventId.IndexFound, LogLevel.Debug, - "NpgsqlEventId.IndexFound", + "NpgsqlEfEventId.IndexFound", level => LoggerMessage.Define( level, - NpgsqlEventId.IndexFound, + NpgsqlEfEventId.IndexFound, _resourceManager.GetString("LogFoundIndex")!))); } @@ -305,12 +305,12 @@ public static FallbackEventDefinition LogFoundColumn(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.PrimaryKeyFound, + NpgsqlEfEventId.PrimaryKeyFound, LogLevel.Debug, - "NpgsqlEventId.PrimaryKeyFound", + "NpgsqlEfEventId.PrimaryKeyFound", level => LoggerMessage.Define( level, - NpgsqlEventId.PrimaryKeyFound, + NpgsqlEfEventId.PrimaryKeyFound, _resourceManager.GetString("LogFoundPrimaryKey")!))); } @@ -330,9 +330,9 @@ public static FallbackEventDefinition LogFoundSequence(IDiagnosticsLogger logger logger, static logger => new FallbackEventDefinition( logger.Options, - NpgsqlEventId.SequenceFound, + NpgsqlEfEventId.SequenceFound, LogLevel.Debug, - "NpgsqlEventId.SequenceFound", + "NpgsqlEfEventId.SequenceFound", _resourceManager.GetString("LogFoundSequence")!)); } @@ -352,12 +352,12 @@ public static EventDefinition LogFoundTable(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.TableFound, + NpgsqlEfEventId.TableFound, LogLevel.Debug, - "NpgsqlEventId.TableFound", + "NpgsqlEfEventId.TableFound", level => LoggerMessage.Define( level, - NpgsqlEventId.TableFound, + NpgsqlEfEventId.TableFound, _resourceManager.GetString("LogFoundTable")!))); } @@ -377,12 +377,12 @@ public static EventDefinition LogFoundTable(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.UniqueConstraintFound, + NpgsqlEfEventId.UniqueConstraintFound, LogLevel.Debug, - "NpgsqlEventId.UniqueConstraintFound", + "NpgsqlEfEventId.UniqueConstraintFound", level => LoggerMessage.Define( level, - NpgsqlEventId.UniqueConstraintFound, + NpgsqlEfEventId.UniqueConstraintFound, _resourceManager.GetString("LogFoundUniqueConstraint")!))); } @@ -402,12 +402,12 @@ public static EventDefinition LogFoundTable(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.MissingSchemaWarning, + NpgsqlEfEventId.MissingSchemaWarning, LogLevel.Warning, - "NpgsqlEventId.MissingSchemaWarning", + "NpgsqlEfEventId.MissingSchemaWarning", level => LoggerMessage.Define( level, - NpgsqlEventId.MissingSchemaWarning, + NpgsqlEfEventId.MissingSchemaWarning, _resourceManager.GetString("LogMissingSchema")!))); } @@ -427,12 +427,12 @@ public static EventDefinition LogFoundTable(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.MissingTableWarning, + NpgsqlEfEventId.MissingTableWarning, LogLevel.Warning, - "NpgsqlEventId.MissingTableWarning", + "NpgsqlEfEventId.MissingTableWarning", level => LoggerMessage.Define( level, - NpgsqlEventId.MissingTableWarning, + NpgsqlEfEventId.MissingTableWarning, _resourceManager.GetString("LogMissingTable")!))); } @@ -452,12 +452,12 @@ public static EventDefinition LogFoundTable(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.ForeignKeyPrincipalColumnMissingWarning, + NpgsqlEfEventId.ForeignKeyPrincipalColumnMissingWarning, LogLevel.Warning, - "NpgsqlEventId.ForeignKeyPrincipalColumnMissingWarning", + "NpgsqlEfEventId.ForeignKeyPrincipalColumnMissingWarning", level => LoggerMessage.Define( level, - NpgsqlEventId.ForeignKeyPrincipalColumnMissingWarning, + NpgsqlEfEventId.ForeignKeyPrincipalColumnMissingWarning, _resourceManager.GetString("LogPrincipalColumnNotFound")!))); } @@ -477,12 +477,12 @@ public static EventDefinition LogFoundTable(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.ForeignKeyReferencesMissingPrincipalTableWarning, + NpgsqlEfEventId.ForeignKeyReferencesMissingPrincipalTableWarning, LogLevel.Warning, - "NpgsqlEventId.ForeignKeyReferencesMissingPrincipalTableWarning", + "NpgsqlEfEventId.ForeignKeyReferencesMissingPrincipalTableWarning", level => LoggerMessage.Define( level, - NpgsqlEventId.ForeignKeyReferencesMissingPrincipalTableWarning, + NpgsqlEfEventId.ForeignKeyReferencesMissingPrincipalTableWarning, _resourceManager.GetString("LogPrincipalTableNotInSelectionSet")!))); } @@ -502,12 +502,12 @@ public static EventDefinition LogFoundTable(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.UnsupportedColumnConstraintSkippedWarning, + NpgsqlEfEventId.UnsupportedColumnConstraintSkippedWarning, LogLevel.Warning, - "NpgsqlEventId.UnsupportedColumnConstraintSkippedWarning", + "NpgsqlEfEventId.UnsupportedColumnConstraintSkippedWarning", level => LoggerMessage.Define( level, - NpgsqlEventId.UnsupportedColumnConstraintSkippedWarning, + NpgsqlEfEventId.UnsupportedColumnConstraintSkippedWarning, _resourceManager.GetString("LogUnsupportedColumnConstraintSkipped")!))); } @@ -527,12 +527,12 @@ public static EventDefinition LogFoundTable(IDiagnosticsLogger logger) logger, static logger => new EventDefinition( logger.Options, - NpgsqlEventId.UnsupportedColumnIndexSkippedWarning, + NpgsqlEfEventId.UnsupportedColumnIndexSkippedWarning, LogLevel.Warning, - "NpgsqlEventId.UnsupportedColumnIndexSkippedWarning", + "NpgsqlEfEventId.UnsupportedColumnIndexSkippedWarning", level => LoggerMessage.Define( level, - NpgsqlEventId.UnsupportedColumnIndexSkippedWarning, + NpgsqlEfEventId.UnsupportedColumnIndexSkippedWarning, _resourceManager.GetString("LogUnsupportedColumnIndexSkipped")!))); } diff --git a/test/EFCore.PG.FunctionalTests/BuiltInDataTypesNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/BuiltInDataTypesNpgsqlTest.cs index 6ee5c2a1f951141ce185af99e19486e9f323171b..99734396643222d1ea3d576be16f5d8ac1876685 100644 --- a/test/EFCore.PG.FunctionalTests/BuiltInDataTypesNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/BuiltInDataTypesNpgsqlTest.cs @@ -882,6 +882,9 @@ public override void Can_query_with_null_parameters_using_any_nullable_data_type } } + [ConditionalFact(Skip = "DateTimeOffset with non-zero offset, https://github.com/dotnet/efcore/issues/26068")] + public override void Can_insert_and_read_back_all_nullable_data_types_with_values_set_to_non_null() {} + [ConditionalFact(Skip = "DateTimeOffset with non-zero offset, https://github.com/dotnet/efcore/issues/26068")] public override void Can_insert_and_read_back_non_nullable_backed_data_types() {} @@ -951,6 +954,8 @@ public class BuiltInDataTypesNpgsqlFixture : BuiltInDataTypesFixtureBase public override bool SupportsDecimalComparisons => true; + public override bool PreservesDateTimeKind => false; + protected override ITestStoreFactory TestStoreFactory => NpgsqlTestStoreFactory.Instance; protected override bool ShouldLogCategory(string logCategory) diff --git a/test/EFCore.PG.FunctionalTests/ConvertToProviderTypesNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/ConvertToProviderTypesNpgsqlTest.cs index 2ed737d169a41f9d6e46b6690b9600f699b4c483..90f7baabeb4dc70672e36cc8d79239e60d69ea99 100644 --- a/test/EFCore.PG.FunctionalTests/ConvertToProviderTypesNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/ConvertToProviderTypesNpgsqlTest.cs @@ -77,6 +77,8 @@ public class ConvertToProviderTypesNpgsqlFixture : ConvertToProviderTypesFixture public override DateTime DefaultDateTime => new(); + public override bool PreservesDateTimeKind => false; + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { base.OnModelCreating(modelBuilder, context); @@ -104,4 +106,4 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con = new DateTimeOffset(new DateTime(), TimeSpan.Zero); } } -} \ No newline at end of file +} diff --git a/test/EFCore.PG.FunctionalTests/CustomConvertersNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/CustomConvertersNpgsqlTest.cs index b3575d2b3381c608e0804c8837c5994421f1aae5..1de900b9b50083119de0fa382ebff07e1e15ff70 100644 --- a/test/EFCore.PG.FunctionalTests/CustomConvertersNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/CustomConvertersNpgsqlTest.cs @@ -49,6 +49,8 @@ public class CustomConvertersNpgsqlFixture : CustomConvertersFixtureBase public override DateTime DefaultDateTime => new(); + public override bool PreservesDateTimeKind => false; + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { base.OnModelCreating(modelBuilder, context); @@ -76,4 +78,4 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con = new DateTimeOffset(new DateTime(), TimeSpan.Zero); } } -} \ No newline at end of file +} diff --git a/test/EFCore.PG.FunctionalTests/EFCore.PG.FunctionalTests.csproj b/test/EFCore.PG.FunctionalTests/EFCore.PG.FunctionalTests.csproj index faae63d321a41a9f8d5e21ff2c4f85d00d883190..d842ad664a583abe0f6d9cbadc88c102251512bd 100644 --- a/test/EFCore.PG.FunctionalTests/EFCore.PG.FunctionalTests.csproj +++ b/test/EFCore.PG.FunctionalTests/EFCore.PG.FunctionalTests.csproj @@ -3,6 +3,7 @@ Npgsql.EntityFrameworkCore.PostgreSQL.FunctionalTests Npgsql.EntityFrameworkCore.PostgreSQL + true diff --git a/test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs index bd4a9625a7f3b5bbd7fa32bc82978cc283286c90..11c3c725a1577d0aac147c50197f51a1666eba76 100644 --- a/test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs @@ -25,7 +25,7 @@ public override async Task Create_table() AssertSql( @"CREATE TABLE ""People"" ( - ""Id"" integer NOT NULL, + ""Id"" integer GENERATED BY DEFAULT AS IDENTITY, ""Name"" text NULL, CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") );"); @@ -45,16 +45,18 @@ public override async Task Create_table_all_settings() END $EF$;", // @"CREATE TABLE dbo2.""People"" ( - ""CustomId"" integer NOT NULL, + ""CustomId"" integer GENERATED BY DEFAULT AS IDENTITY, ""EmployerId"" integer NOT NULL, ""SSN"" character varying(11) COLLATE ""POSIX"" NOT NULL, CONSTRAINT ""PK_People"" PRIMARY KEY (""CustomId""), CONSTRAINT ""AK_People_SSN"" UNIQUE (""SSN""), CONSTRAINT ""CK_People_EmployerId"" CHECK (""EmployerId"" > 0), - CONSTRAINT ""FK_People_Employers_EmployerId"" FOREIGN KEY (""EmployerId"") REFERENCES ""Employers"" (""Id"") + CONSTRAINT ""FK_People_Employers_EmployerId"" FOREIGN KEY (""EmployerId"") REFERENCES ""Employers"" (""Id"") ON DELETE CASCADE ); COMMENT ON TABLE dbo2.""People"" IS 'Table comment'; -COMMENT ON COLUMN dbo2.""People"".""EmployerId"" IS 'Employer ID comment';"); +COMMENT ON COLUMN dbo2.""People"".""EmployerId"" IS 'Employer ID comment';", + // + @"CREATE INDEX ""IX_People_EmployerId"" ON dbo2.""People"" (""EmployerId"");"); } public override async Task Create_table_no_key() @@ -73,8 +75,9 @@ public override async Task Create_table_with_comments() AssertSql( @"CREATE TABLE ""People"" ( - ""Id"" integer NOT NULL, - ""Name"" text NULL + ""Id"" integer GENERATED BY DEFAULT AS IDENTITY, + ""Name"" text NULL, + CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") ); COMMENT ON TABLE ""People"" IS 'Table comment'; COMMENT ON COLUMN ""People"".""Name"" IS 'Column comment';"); @@ -86,8 +89,9 @@ public override async Task Create_table_with_multiline_comments() AssertSql( @"CREATE TABLE ""People"" ( - ""Id"" integer NOT NULL, - ""Name"" text NULL + ""Id"" integer GENERATED BY DEFAULT AS IDENTITY, + ""Name"" text NULL, + CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") ); COMMENT ON TABLE ""People"" IS 'This is a multi-line table comment. @@ -118,10 +122,11 @@ public override async Task Create_table_with_computed_column(bool? stored) AssertSql( @"CREATE TABLE ""People"" ( - ""Id"" integer NOT NULL, + ""Id"" integer GENERATED BY DEFAULT AS IDENTITY, ""Sum"" text GENERATED ALWAYS AS (""X"" + ""Y"") STORED, ""X"" integer NOT NULL, - ""Y"" integer NOT NULL + ""Y"" integer NOT NULL, + CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") );"); } @@ -142,7 +147,8 @@ public virtual async Task Create_table_with_identity_by_default() AssertSql( @"CREATE TABLE ""People"" ( - ""Id"" integer GENERATED BY DEFAULT AS IDENTITY + ""Id"" integer GENERATED BY DEFAULT AS IDENTITY, + CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") );"); } @@ -163,7 +169,8 @@ public virtual async Task Create_table_with_identity_always() AssertSql( @"CREATE TABLE ""People"" ( - ""Id"" integer GENERATED ALWAYS AS IDENTITY + ""Id"" integer GENERATED ALWAYS AS IDENTITY, + CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") );"); } @@ -191,7 +198,8 @@ public virtual async Task Create_table_with_identity_always_with_options() AssertSql( @"CREATE TABLE ""People"" ( - ""Id"" integer GENERATED ALWAYS AS IDENTITY (START WITH 10 INCREMENT BY 2 MAXVALUE 2000) + ""Id"" integer GENERATED ALWAYS AS IDENTITY (START WITH 10 INCREMENT BY 2 MAXVALUE 2000), + CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") );"); } @@ -213,7 +221,8 @@ public virtual async Task Create_table_with_serial() AssertSql( @"CREATE TABLE ""People"" ( - ""Id"" serial NOT NULL + ""Id"" serial NOT NULL, + CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") );"); } @@ -239,7 +248,7 @@ public virtual async Task Create_table_with_system_column() AssertSql( @"CREATE TABLE ""People"" ( - ""Id"" integer NOT NULL, + ""Id"" integer GENERATED BY DEFAULT AS IDENTITY, CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") );"); } @@ -261,7 +270,7 @@ public virtual async Task Create_table_with_storage_parameter() AssertSql( @"CREATE TABLE ""People"" ( - ""Id"" integer NOT NULL, + ""Id"" integer GENERATED BY DEFAULT AS IDENTITY, CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") ) WITH (fillfactor=70, user_catalog_table=true);"); @@ -283,7 +292,7 @@ public virtual async Task Create_table_with_unlogged() AssertSql( @"CREATE UNLOGGED TABLE ""People"" ( - ""Id"" integer NOT NULL, + ""Id"" integer GENERATED BY DEFAULT AS IDENTITY, CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") );"); } @@ -404,7 +413,11 @@ public override async Task Rename_table() await base.Rename_table(); AssertSql( - @"ALTER TABLE ""People"" RENAME TO ""Persons"";"); + @"ALTER TABLE ""People"" DROP CONSTRAINT ""PK_People"";", + // + @"ALTER TABLE ""People"" RENAME TO ""Persons"";", + // + @"ALTER TABLE ""Persons"" ADD CONSTRAINT ""PK_Persons"" PRIMARY KEY (""Id"");"); } public override async Task Rename_table_with_primary_key() @@ -451,7 +464,8 @@ public override async Task Create_schema() END $EF$;", // @"CREATE TABLE ""SomeOtherSchema"".""People"" ( - ""Id"" integer NOT NULL + ""Id"" integer GENERATED BY DEFAULT AS IDENTITY, + CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") );"); } @@ -467,7 +481,8 @@ public virtual async Task Create_schema_public_is_ignored() AssertSql( @"CREATE TABLE public.""People"" ( - ""Id"" integer NOT NULL + ""Id"" integer GENERATED BY DEFAULT AS IDENTITY, + CONSTRAINT ""PK_People"" PRIMARY KEY (""Id"") );"); } @@ -1042,7 +1057,7 @@ public override async Task Alter_column_change_computed() } [ConditionalFact] - public virtual async Task Alter_column_change_computed_recreates_indexes() + public override async Task Alter_column_change_computed_recreates_indexes() { if (TestEnvironment.PostgresVersion.IsUnder(12)) { @@ -1184,13 +1199,8 @@ public override async Task Alter_column_remove_comment() public virtual async Task Alter_column_make_identity_by_default() { await Test( - builder => builder.Entity( - "People", e => - { - e.Property("Id"); - e.HasKey("Id"); - }), - _ => { }, + builder => builder.Entity("People").Property("Id") + .ValueGeneratedNever(), builder => builder.Entity("People").Property("Id") .UseIdentityByDefaultColumn(), model => @@ -1228,8 +1238,7 @@ public virtual async Task Alter_column_make_identity_always() }); AssertSql( - @"ALTER TABLE ""People"" ALTER COLUMN ""Id"" DROP DEFAULT; -ALTER TABLE ""People"" ALTER COLUMN ""Id"" ADD GENERATED ALWAYS AS IDENTITY;"); + @"ALTER TABLE ""People"" ALTER COLUMN ""Id"" SET GENERATED ALWAYS;"); } [Fact] @@ -1262,13 +1271,8 @@ public virtual async Task Alter_column_make_default_into_identity() public virtual async Task Alter_column_make_identity_by_default_with_options() { await Test( - builder => builder.Entity( - "People", e => - { - e.Property("Id"); - e.HasKey("Id"); - }), - _ => { }, + builder => builder.Entity("People").Property("Id") + .ValueGeneratedNever(), builder => builder.Entity("People").Property("Id") .UseIdentityByDefaultColumn() .HasIdentityOptions(startValue: 10, incrementBy: 2, maxValue: 2000), @@ -1320,8 +1324,8 @@ public virtual async Task Alter_column_make_identity_with_default_options() }); AssertSql( - @"ALTER TABLE ""People"" ALTER COLUMN ""Id"" DROP DEFAULT; -ALTER TABLE ""People"" ALTER COLUMN ""Id"" ADD GENERATED BY DEFAULT AS IDENTITY;"); + @"ALTER TABLE ""People"" ALTER COLUMN ""Id"" RESTART WITH 1; +ALTER TABLE ""People"" ALTER COLUMN ""Id"" SET MINVALUE 1;"); } [Fact] @@ -1390,13 +1394,8 @@ public virtual async Task Alter_column_remove_identity_options() public virtual async Task Alter_column_make_serial() { await Test( - builder => builder.Entity( - "People", e => - { - e.Property("Id"); - e.HasKey("Id"); - }), - _ => { }, + builder => builder.Entity("People").Property("Id") + .ValueGeneratedNever(), builder => builder.Entity("People").Property("Id") .UseSerialColumn(), model => @@ -1420,14 +1419,9 @@ public virtual async Task Alter_column_make_serial() public virtual async Task Alter_column_make_serial_in_non_default_schema() { await Test( - builder => builder.Entity( - "People", e => - { - e.ToTable("People", "some_schema"); - e.Property("Id"); - e.HasKey("Id"); - }), - _ => { }, + builder => builder.Entity("People", e => e.ToTable("People", "some_schema")), + builder => builder.Entity("People").Property("Id") + .ValueGeneratedNever(), builder => builder.Entity("People").Property("Id") .UseSerialColumn(), model => @@ -1451,13 +1445,8 @@ public virtual async Task Alter_column_make_serial_in_non_default_schema() public virtual async Task Alter_column_long_make_bigserial() { await Test( - builder => builder.Entity( - "People", e => - { - e.Property("Id"); - e.HasKey("Id"); - }), - _ => { }, + builder => builder.Entity("People").Property("Id") + .ValueGeneratedNever(), builder => builder.Entity("People").Property("Id") .UseSerialColumn(), model => @@ -2206,9 +2195,20 @@ public override async Task Rename_index() #region Key and constraint - public override async Task Add_primary_key() + public override async Task Add_primary_key_int() + { + await base.Add_primary_key_int(); + + AssertSql( + @"ALTER TABLE ""People"" ALTER COLUMN ""SomeField"" DROP DEFAULT; +ALTER TABLE ""People"" ALTER COLUMN ""SomeField"" ADD GENERATED BY DEFAULT AS IDENTITY;", + // + @"ALTER TABLE ""People"" ADD CONSTRAINT ""PK_People"" PRIMARY KEY (""SomeField"");"); + } + + public override async Task Add_primary_key_string() { - await base.Add_primary_key(); + await base.Add_primary_key_string(); AssertSql( @"ALTER TABLE ""People"" ADD CONSTRAINT ""PK_People"" PRIMARY KEY (""SomeField"");"); @@ -2219,6 +2219,9 @@ public override async Task Add_primary_key_with_name() await base.Add_primary_key_with_name(); AssertSql( + @"ALTER TABLE ""People"" ALTER COLUMN ""SomeField"" SET NOT NULL; +ALTER TABLE ""People"" ALTER COLUMN ""SomeField"" SET DEFAULT '';", + // @"ALTER TABLE ""People"" ADD CONSTRAINT ""PK_Foo"" PRIMARY KEY (""SomeField"");"); } @@ -2230,9 +2233,19 @@ public override async Task Add_primary_key_composite_with_name() @"ALTER TABLE ""People"" ADD CONSTRAINT ""PK_Foo"" PRIMARY KEY (""SomeField1"", ""SomeField2"");"); } - public override async Task Drop_primary_key() + public override async Task Drop_primary_key_int() + { + await base.Drop_primary_key_int(); + + AssertSql( + @"ALTER TABLE ""People"" DROP CONSTRAINT ""PK_People"";", + // + @"ALTER TABLE ""People"" ALTER COLUMN ""SomeField"" DROP IDENTITY;"); + } + + public override async Task Drop_primary_key_string() { - await base.Drop_primary_key(); + await base.Drop_primary_key_string(); AssertSql( @"ALTER TABLE ""People"" DROP CONSTRAINT ""PK_People"";"); @@ -2246,7 +2259,9 @@ public override async Task Add_foreign_key_with_name() await base.Add_foreign_key_with_name(); AssertSql( - @"ALTER TABLE ""Orders"" ADD CONSTRAINT ""FK_Foo"" FOREIGN KEY (""CustomerId"") REFERENCES ""Customers"" (""Id"");"); + @"CREATE INDEX ""IX_Orders_CustomerId"" ON ""Orders"" (""CustomerId"");", + // + @"ALTER TABLE ""Orders"" ADD CONSTRAINT ""FK_Foo"" FOREIGN KEY (""CustomerId"") REFERENCES ""Customers"" (""Id"") ON DELETE CASCADE;"); } public override async Task Drop_foreign_key() @@ -2254,7 +2269,9 @@ public override async Task Drop_foreign_key() await base.Drop_foreign_key(); AssertSql( - @"ALTER TABLE ""Orders"" DROP CONSTRAINT ""FK_Orders_Customers_CustomerId"";"); + @"ALTER TABLE ""Orders"" DROP CONSTRAINT ""FK_Orders_Customers_CustomerId"";", + // + @"DROP INDEX ""IX_Orders_CustomerId"";"); } public override async Task Add_unique_constraint() @@ -2426,7 +2443,14 @@ public override async Task InsertDataOperation() INSERT INTO ""Person"" (""Id"", ""Name"") VALUES (4, 'Harry Strickland'); INSERT INTO ""Person"" (""Id"", ""Name"") -VALUES (5, NULL);"); +VALUES (5, NULL);", + // + @"SELECT setval( + pg_get_serial_sequence('""Person""', 'Id'), + GREATEST( + (SELECT MAX(""Id"") FROM ""Person"") + 1, + nextval(pg_get_serial_sequence('""Person""', 'Id'))), + false);"); } public override async Task DeleteDataOperation_simple_key() @@ -2781,7 +2805,7 @@ public virtual Task Alter_collation_throws() public class MigrationsNpgsqlFixture : MigrationsFixtureBase { - protected override string StoreName { get; } = nameof(MigrationsNpgsqlTest); + protected override string StoreName => nameof(MigrationsNpgsqlTest); protected override ITestStoreFactory TestStoreFactory => NpgsqlTestStoreFactory.Instance; public override TestHelpers TestHelpers => NpgsqlTestHelpers.Instance; @@ -2794,7 +2818,7 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build new NpgsqlDbContextOptionsBuilder(base.AddOptions(builder) // Some tests create expression indexes, but these cannot be reverse-engineered. .ConfigureWarnings( - w => { w.Ignore(NpgsqlEventId.ExpressionIndexSkippedWarning); })) + w => { w.Ignore(NpgsqlEfEventId.ExpressionIndexSkippedWarning); })) // Various migration operations PG-version sensitive, configure the context with the actual version // we're connecting to. .SetPostgresVersion(TestEnvironment.PostgresVersion); @@ -2802,4 +2826,9 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build return builder; } } + + protected override ICollection GetAdditionalReferences() + => AdditionalReferences; + + private static readonly BuildReference[] AdditionalReferences = { BuildReference.ByName("Npgsql") }; } diff --git a/test/EFCore.PG.FunctionalTests/NpgsqlDatabaseCreatorTest.cs b/test/EFCore.PG.FunctionalTests/NpgsqlDatabaseCreatorTest.cs index d89be2f0abc51161cd2895a0c34c0fe83f8f4e44..f8616423110d3069189a2c578bc60c2434af2931 100644 --- a/test/EFCore.PG.FunctionalTests/NpgsqlDatabaseCreatorTest.cs +++ b/test/EFCore.PG.FunctionalTests/NpgsqlDatabaseCreatorTest.cs @@ -258,7 +258,7 @@ public async Task Throws_when_database_does_not_exist(bool async) { using var testDatabase = NpgsqlTestStore.GetOrCreate("NonExisting"); var databaseCreator = GetDatabaseCreator(testDatabase); - await databaseCreator.ExecutionStrategyFactory.Create().ExecuteAsync( + await databaseCreator.ExecutionStrategy.ExecuteAsync( databaseCreator, async creator => { @@ -652,9 +652,7 @@ public bool HasTablesBase() public Task HasTablesAsyncBase(CancellationToken cancellationToken = default) => HasTablesAsync(cancellationToken); - public IExecutionStrategyFactory ExecutionStrategyFactory -#pragma warning disable CS0618 // Type or member is obsolete - => Dependencies.ExecutionStrategyFactory; -#pragma warning restore CS0618 // Type or member is obsolete + public IExecutionStrategy ExecutionStrategy + => Dependencies.ExecutionStrategy; } -} \ No newline at end of file +} diff --git a/test/EFCore.PG.FunctionalTests/Query/CitextQueryTest.cs b/test/EFCore.PG.FunctionalTests/Query/CitextQueryTest.cs index 712989142433b84218216df0e49a715fdeec3d0c..a0e25fe316e3f39738fafb3be56f1b7c813db687 100644 --- a/test/EFCore.PG.FunctionalTests/Query/CitextQueryTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/CitextQueryTest.cs @@ -42,10 +42,11 @@ public void StartsWith_param_pattern() Assert.Equal(1, result.Id); AssertSql( @"@__param_0='some' +@__param_0_1='some' SELECT s.""Id"", s.""CaseInsensitiveText"" FROM ""SomeEntities"" AS s -WHERE (@__param_0 = '') OR ((s.""CaseInsensitiveText"" IS NOT NULL) AND ((s.""CaseInsensitiveText"" LIKE @__param_0 || '%' ESCAPE '') AND (left(s.""CaseInsensitiveText"", length(@__param_0))::citext = @__param_0::citext))) +WHERE @__param_0 = '' OR ((s.""CaseInsensitiveText"" IS NOT NULL) AND (s.""CaseInsensitiveText"" LIKE @__param_0_1 || '%' ESCAPE '') AND left(s.""CaseInsensitiveText"", length(@__param_0))::citext = @__param_0::citext) LIMIT 2"); } @@ -62,7 +63,7 @@ public void StartsWith_param_instance() SELECT s.""Id"", s.""CaseInsensitiveText"" FROM ""SomeEntities"" AS s -WHERE (s.""CaseInsensitiveText"" = '') OR ((s.""CaseInsensitiveText"" IS NOT NULL) AND ((@__param_0 LIKE s.""CaseInsensitiveText"" || '%' ESCAPE '') AND (left(@__param_0, length(s.""CaseInsensitiveText""))::citext = s.""CaseInsensitiveText""::citext))) +WHERE s.""CaseInsensitiveText"" = '' OR ((s.""CaseInsensitiveText"" IS NOT NULL) AND (@__param_0 LIKE s.""CaseInsensitiveText"" || '%' ESCAPE '') AND left(@__param_0, length(s.""CaseInsensitiveText""))::citext = s.""CaseInsensitiveText""::citext) LIMIT 2"); } @@ -90,10 +91,11 @@ public void EndsWith_param_pattern() Assert.Equal(1, result.Id); AssertSql( @"@__param_0='sometext' +@__param_0_1='sometext' SELECT s.""Id"", s.""CaseInsensitiveText"" FROM ""SomeEntities"" AS s -WHERE (@__param_0 = '') OR ((s.""CaseInsensitiveText"" IS NOT NULL) AND (right(s.""CaseInsensitiveText"", length(@__param_0))::citext = @__param_0::citext)) +WHERE @__param_0 = '' OR ((s.""CaseInsensitiveText"" IS NOT NULL) AND right(s.""CaseInsensitiveText"", length(@__param_0_1))::citext = @__param_0::citext) LIMIT 2"); } @@ -110,7 +112,7 @@ public void EndsWith_param_instance() SELECT s.""Id"", s.""CaseInsensitiveText"" FROM ""SomeEntities"" AS s -WHERE (s.""CaseInsensitiveText"" = '') OR ((s.""CaseInsensitiveText"" IS NOT NULL) AND (right(@__param_0, length(s.""CaseInsensitiveText""))::citext = s.""CaseInsensitiveText""::citext)) +WHERE s.""CaseInsensitiveText"" = '' OR ((s.""CaseInsensitiveText"" IS NOT NULL) AND right(@__param_0, length(s.""CaseInsensitiveText""))::citext = s.""CaseInsensitiveText""::citext) LIMIT 2"); } @@ -141,7 +143,7 @@ public void Contains_param_pattern() SELECT s.""Id"", s.""CaseInsensitiveText"" FROM ""SomeEntities"" AS s -WHERE (@__param_0 = '') OR (strpos(s.""CaseInsensitiveText"", @__param_0) > 0) +WHERE @__param_0 = '' OR strpos(s.""CaseInsensitiveText"", @__param_0) > 0 LIMIT 2"); } @@ -158,7 +160,7 @@ public void Contains_param_instance() SELECT s.""Id"", s.""CaseInsensitiveText"" FROM ""SomeEntities"" AS s -WHERE (s.""CaseInsensitiveText"" = '') OR (strpos(@__param_0, s.""CaseInsensitiveText"") > 0) +WHERE s.""CaseInsensitiveText"" = '' OR strpos(@__param_0, s.""CaseInsensitiveText"") > 0 LIMIT 2"); } diff --git a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsQueryNpgsqlTest.cs index df1e5efea26e9909083d51cce8704f8effca3c9f..7e3676da5595185f1ba569aa617365d14e03e86f 100644 --- a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsQueryNpgsqlTest.cs @@ -10,4 +10,9 @@ public class ComplexNavigationsCollectionsQueryNpgsqlTest : ComplexNavigationsCo Fixture.TestSqlLoggerFactory.Clear(); //Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); } -} \ No newline at end of file + + public override async Task Complex_query_with_let_collection_projection_FirstOrDefault_with_ToList_on_inner_and_outer(bool async) + // Nested collection with ToList. Issue #23303. + => await Assert.ThrowsAsync( + () => base.Complex_query_with_let_collection_projection_FirstOrDefault_with_ToList_on_inner_and_outer(async)); +} diff --git a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSharedTypeQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSharedTypeQueryNpgsqlTest.cs index dc4f60d03d13c90ce7603933064a75d5d9a8584b..20bc259920078bb5518158e704e8cf87df5195c1 100644 --- a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSharedTypeQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSharedTypeQueryNpgsqlTest.cs @@ -11,4 +11,9 @@ public class ComplexNavigationsCollectionsSharedTypeQueryNpgsqlTest : ComplexNav Fixture.TestSqlLoggerFactory.Clear(); //Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); } -} \ No newline at end of file + + public override async Task Complex_query_with_let_collection_projection_FirstOrDefault_with_ToList_on_inner_and_outer(bool async) + // Nested collection with ToList. Issue #23303. + => await Assert.ThrowsAsync( + () => base.Complex_query_with_let_collection_projection_FirstOrDefault_with_ToList_on_inner_and_outer(async)); +} diff --git a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQueryNpgsqlTest.cs index dbdcdf28a8e506528335e380f2e5d985b6930098..9fa763ac9369be6183b9d3ec972094de14eeda12 100644 --- a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSplitQueryNpgsqlTest.cs @@ -10,4 +10,9 @@ public class ComplexNavigationsCollectionsSplitQueryNpgsqlTest : ComplexNavigati Fixture.TestSqlLoggerFactory.Clear(); //Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); } -} \ No newline at end of file + + public override async Task Complex_query_with_let_collection_projection_FirstOrDefault_with_ToList_on_inner_and_outer(bool async) + // Nested collection with ToList. Issue #23303. + => await Assert.ThrowsAsync( + () => base.Complex_query_with_let_collection_projection_FirstOrDefault_with_ToList_on_inner_and_outer(async)); +} diff --git a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQueryNpgsqlTest.cs index 45cdf96e6b8ee9ac0e27d81ad3cf6e6492a9c863..1e599486ac648836050f6302ec94b49394090f0d 100644 --- a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsCollectionsSplitSharedTypeQueryNpgsqlTest.cs @@ -11,4 +11,9 @@ public class ComplexNavigationsCollectionsSplitSharedTypeQueryNpgsqlTest : Compl Fixture.TestSqlLoggerFactory.Clear(); //Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); } -} \ No newline at end of file + + public override async Task Complex_query_with_let_collection_projection_FirstOrDefault_with_ToList_on_inner_and_outer(bool async) + // Nested collection with ToList. Issue #23303. + => await Assert.ThrowsAsync( + () => base.Complex_query_with_let_collection_projection_FirstOrDefault_with_ToList_on_inner_and_outer(async)); +} diff --git a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsQueryNpgsqlTest.cs index 04e013c1eb67bf4577a203842551223cc0f977be..6ec76cd82ddc2f84f0df3982c437fe9aa15672f0 100644 --- a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsQueryNpgsqlTest.cs @@ -1,4 +1,6 @@ -namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query; +using Xunit.Sdk; + +namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query; public class ComplexNavigationsQueryNpgsqlTest : ComplexNavigationsQueryRelationalTestBase { @@ -11,4 +13,19 @@ public ComplexNavigationsQueryNpgsqlTest(ComplexNavigationsQueryNpgsqlFixture fi [ConditionalTheory(Skip = "https://github.com/dotnet/efcore/issues/26353")] public override Task Subquery_with_Distinct_Skip_FirstOrDefault_without_OrderBy(bool async) => base.Subquery_with_Distinct_Skip_FirstOrDefault_without_OrderBy(async); -} \ No newline at end of file + + public override async Task Join_with_result_selector_returning_queryable_throws_validation_error(bool async) + => await Assert.ThrowsAsync( + () => base.Join_with_result_selector_returning_queryable_throws_validation_error(async)); + + public override Task GroupJoin_client_method_in_OrderBy(bool async) + => AssertTranslationFailedWithDetails( + () => base.GroupJoin_client_method_in_OrderBy(async), + CoreStrings.QueryUnableToTranslateMethod( + "Microsoft.EntityFrameworkCore.Query.ComplexNavigationsQueryTestBase", + "ClientMethodNullableInt")); + + public override Task Nested_SelectMany_correlated_with_join_table_correctly_translated_to_apply(bool async) + => Assert.ThrowsAsync( + async () => await base.Nested_SelectMany_correlated_with_join_table_correctly_translated_to_apply(async)); +} diff --git a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsSharedTypeQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsSharedTypeQueryNpgsqlTest.cs index 23da08274b111a1477609197244b4c0bd9d5448c..6c4ba63a10ee585cd8d954e47df262e4e1207b7b 100644 --- a/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsSharedTypeQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/ComplexNavigationsSharedTypeQueryNpgsqlTest.cs @@ -1,3 +1,5 @@ +using Xunit.Sdk; + namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query; public class ComplexNavigationsSharedTypeQueryNpgsqlTest @@ -24,4 +26,19 @@ public override Task Distinct_skip_without_orderby(bool async) [ConditionalTheory(Skip = "https://github.com/dotnet/efcore/pull/22532")] public override Task Distinct_take_without_orderby(bool async) => base.Distinct_take_without_orderby(async); + + public override async Task Join_with_result_selector_returning_queryable_throws_validation_error(bool async) + => await Assert.ThrowsAsync( + () => base.Join_with_result_selector_returning_queryable_throws_validation_error(async)); + + public override Task GroupJoin_client_method_in_OrderBy(bool async) + => AssertTranslationFailedWithDetails( + () => base.GroupJoin_client_method_in_OrderBy(async), + CoreStrings.QueryUnableToTranslateMethod( + "Microsoft.EntityFrameworkCore.Query.ComplexNavigationsQueryTestBase", + "ClientMethodNullableInt")); + + public override Task Nested_SelectMany_correlated_with_join_table_correctly_translated_to_apply(bool async) + => Assert.ThrowsAsync( + async () => await base.Nested_SelectMany_correlated_with_join_table_correctly_translated_to_apply(async)); } diff --git a/test/EFCore.PG.FunctionalTests/Query/Ef6GroupByNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/Ef6GroupByNpgsqlTest.cs new file mode 100644 index 0000000000000000000000000000000000000000..8f39ba2d949907314008aebd070408d4587d066b --- /dev/null +++ b/test/EFCore.PG.FunctionalTests/Query/Ef6GroupByNpgsqlTest.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Npgsql.EntityFrameworkCore.PostgreSQL.TestUtilities; + +namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query; + +public class Ef6GroupByNpgsqlTest : Ef6GroupByTestBase +{ + public Ef6GroupByNpgsqlTest(Ef6GroupByNpgsqlFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + //Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + [ConditionalTheory(Skip = "https://github.com/dotnet/efcore/issues/27155")] + public override Task Average_Grouped_from_LINQ_101(bool async) + => base.Average_Grouped_from_LINQ_101(async); + + [ConditionalTheory(Skip = "https://github.com/dotnet/efcore/issues/27155")] + public override Task Whats_new_2021_sample_10(bool async) + => base.Whats_new_2021_sample_10(async); + + public class Ef6GroupByNpgsqlFixture : Ef6GroupByFixtureBase + { + public TestSqlLoggerFactory TestSqlLoggerFactory + => (TestSqlLoggerFactory)ListLoggerFactory; + + protected override ITestStoreFactory TestStoreFactory + => NpgsqlTestStoreFactory.Instance; + + protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + { + base.OnModelCreating(modelBuilder, context); + + modelBuilder.Entity().Property(o => o.OrderDate).HasColumnType("timestamp"); + } + } +} diff --git a/test/EFCore.PG.FunctionalTests/Query/GearsOfWarQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/GearsOfWarQueryNpgsqlTest.cs index d027379772e545233f217453d096271b2d5bf06f..c76afc9699c6a77c4946579b1abb9b0f82cf7b43 100644 --- a/test/EFCore.PG.FunctionalTests/Query/GearsOfWarQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/GearsOfWarQueryNpgsqlTest.cs @@ -162,7 +162,7 @@ public override async Task DateTimeOffset_Contains_Less_than_Greater_than(bool a SELECT m.""Id"", m.""CodeName"", m.""Date"", m.""Duration"", m.""Rating"", m.""Time"", m.""Timeline"" FROM ""Missions"" AS m -WHERE ((@__start_0 <= date_trunc('day', m.""Timeline"")::timestamptz) AND (m.""Timeline"" < @__end_1)) AND m.""Timeline"" = ANY (@__dates_2)"); +WHERE @__start_0 <= date_trunc('day', m.""Timeline"")::timestamptz AND m.""Timeline"" < @__end_1 AND m.""Timeline"" = ANY (@__dates_2)"); } // Base implementation uses DateTimeOffset.Now, which we don't translate by design. Use DateTimeOffset.UtcNow instead. diff --git a/test/EFCore.PG.FunctionalTests/Query/LTreeQueryTest.cs b/test/EFCore.PG.FunctionalTests/Query/LTreeQueryTest.cs index 8815791f7b4e978acecea1b2b057d0356fa6eb7d..e560469d8c265ba4ccf51d82dd3a8cdec24bcc33 100644 --- a/test/EFCore.PG.FunctionalTests/Query/LTreeQueryTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/LTreeQueryTest.cs @@ -354,7 +354,7 @@ public void Subpath2() AssertSql( @"SELECT l.""Id"", l.""Path"", l.""PathAsString"" FROM ""LTreeEntities"" AS l -WHERE (nlevel(l.""Path"") > 2) AND (subpath(l.""Path"", 2) = 'Astronomy.Astrophysics') +WHERE nlevel(l.""Path"") > 2 AND subpath(l.""Path"", 2) = 'Astronomy.Astrophysics' LIMIT 2"); } diff --git a/test/EFCore.PG.FunctionalTests/Query/NetworkQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/NetworkQueryNpgsqlTest.cs index 7306ed955ef5763f991ca7b234921d3f98007b30..3a48bf877eda63cf48177de9515c7240c5302c3d 100644 --- a/test/EFCore.PG.FunctionalTests/Query/NetworkQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/NetworkQueryNpgsqlTest.cs @@ -58,7 +58,10 @@ public void IPAddress_inet_parse_column() var count = context.NetTestEntities.Count(x => x.Inet.Equals(IPAddress.Parse(x.TextInet))); Assert.Equal(9, count); - AssertContainsSql(@"n.""TextInet""::inet)"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" = n.""TextInet""::inet OR ((n.""Inet"" IS NULL) AND (n.""TextInet"" IS NULL))"); } [Fact] @@ -68,7 +71,10 @@ public void PhysicalAddress_macaddr_parse_column() var count = context.NetTestEntities.Count(x => x.Macaddr.Equals(PhysicalAddress.Parse(x.TextMacaddr))); Assert.Equal(9, count); - AssertContainsSql(@"n.""TextMacaddr""::macaddr)"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Macaddr"" = n.""TextMacaddr""::macaddr OR ((n.""Macaddr"" IS NULL) AND (n.""TextMacaddr"" IS NULL))"); } [Fact] @@ -78,7 +84,10 @@ public void IPAddress_inet_parse_literal() var count = context.NetTestEntities.Count(x => x.Inet.Equals(IPAddress.Parse("192.168.1.2"))); Assert.Equal(1, count); - AssertContainsSql("INET '192.168.1.2'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" = INET '192.168.1.2'"); } [Fact] @@ -88,7 +97,10 @@ public void PhysicalAddress_macaddr_parse_literal() var count = context.NetTestEntities.Count(x => x.Macaddr.Equals(PhysicalAddress.Parse("12-34-56-00-00-02"))); Assert.Equal(1, count); - AssertContainsSql("MACADDR '123456000002'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Macaddr"" = MACADDR '123456000002'"); } [Fact] @@ -122,7 +134,10 @@ public void IPAddress_inet_LessThan_inet() var count = context.NetTestEntities.Count(x => EF.Functions.LessThan(x.Inet, IPAddress.Parse("192.168.1.7"))); Assert.Equal(6, count); - AssertContainsSql(@"WHERE n.""Inet"" < INET '192.168.1.7'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" < INET '192.168.1.7'"); } [Fact] @@ -134,7 +149,12 @@ public void ValueTuple_cidr_LessThan_cidr() .Where(x => EF.Functions.LessThan(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" < @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" < @__cidr_1"); } [Fact] @@ -144,7 +164,10 @@ public void PhysicalAddress_macaddr_LessThan_macaddr() var count = context.NetTestEntities.Count(x => EF.Functions.LessThan(x.Macaddr, PhysicalAddress.Parse("12-34-56-00-00-07"))); Assert.Equal(6, count); - AssertContainsSql(@"""Macaddr"" < MACADDR '123456000007'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Macaddr"" < MACADDR '123456000007'"); } [ConditionalFact] @@ -155,7 +178,10 @@ public void PhysicalAddress_macaddr8_LessThan_macaddr8() var count = context.NetTestEntities.Count(x => EF.Functions.LessThan(x.Macaddr8, PhysicalAddress.Parse("08-00-2B-01-02-03-04-07"))); Assert.Equal(6, count); - AssertContainsSql(@"""Macaddr8"" < MACADDR8 '08002B0102030407'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Macaddr8"" < MACADDR8 '08002B0102030407'"); } [Fact] @@ -165,7 +191,10 @@ public void IPAddress_inet_LessThanOrEqual_inet() var count = context.NetTestEntities.Count(x => EF.Functions.LessThanOrEqual(x.Inet, IPAddress.Parse("192.168.1.7"))); Assert.Equal(7, count); - AssertContainsSql(@"WHERE n.""Inet"" <= INET '192.168.1.7'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" <= INET '192.168.1.7'"); } [Fact] @@ -177,7 +206,12 @@ public void ValueTuple_cidr_LessThanOrEqual_cidr() .Where(x => EF.Functions.LessThanOrEqual(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" <= @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" <= @__cidr_1"); } [Fact] @@ -187,7 +221,10 @@ public void PhysicalAddress_macaddr_LessThanOrEqual_macaddr() var count = context.NetTestEntities.Count(x => EF.Functions.LessThanOrEqual(x.Macaddr, PhysicalAddress.Parse("12-34-56-00-00-07"))); Assert.Equal(7, count); - AssertContainsSql(@"""Macaddr"" <= MACADDR '123456000007'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Macaddr"" <= MACADDR '123456000007'"); } [ConditionalFact] @@ -198,7 +235,10 @@ public void PhysicalAddress_macaddr8_LessThanOrEqual_macaddr8() var count = context.NetTestEntities.Count(x => EF.Functions.LessThanOrEqual(x.Macaddr8, PhysicalAddress.Parse("08-00-2B-01-02-03-04-07"))); Assert.Equal(7, count); - AssertContainsSql(@"""Macaddr8"" <= MACADDR8 '08002B0102030407'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Macaddr8"" <= MACADDR8 '08002B0102030407'"); } [Fact] @@ -208,7 +248,10 @@ public void IPAddress_inet_GreaterThanOrEqual_inet() var count = context.NetTestEntities.Count(x => EF.Functions.GreaterThanOrEqual(x.Inet, IPAddress.Parse("192.168.1.7"))); Assert.Equal(3, count); - AssertContainsSql(@"WHERE n.""Inet"" >= INET '192.168.1.7'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" >= INET '192.168.1.7'"); } [Fact] @@ -220,7 +263,12 @@ public void ValueTuple_cidr_GreaterThanOrEqual_cidr() .Where(x => EF.Functions.GreaterThanOrEqual(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" >= @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" >= @__cidr_1"); } [Fact] @@ -230,7 +278,10 @@ public void PhysicalAddress_macaddr_GreaterThanOrEqual_macaddr() var count = context.NetTestEntities.Count(x => EF.Functions.GreaterThanOrEqual(x.Macaddr, PhysicalAddress.Parse("12-34-56-00-00-07"))); Assert.Equal(3, count); - AssertContainsSql(@"""Macaddr"" >= MACADDR '123456000007'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Macaddr"" >= MACADDR '123456000007'"); } [ConditionalFact] @@ -241,7 +292,10 @@ public void PhysicalAddress_macaddr8_GreaterThanOrEqual_macaddr8() var count = context.NetTestEntities.Count(x => EF.Functions.GreaterThanOrEqual(x.Macaddr8, PhysicalAddress.Parse("08-00-2B-01-02-03-04-07"))); Assert.Equal(3, count); - AssertContainsSql(@"""Macaddr8"" >= MACADDR8 '08002B0102030407'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Macaddr8"" >= MACADDR8 '08002B0102030407'"); } [Fact] @@ -251,7 +305,10 @@ public void IPAddress_inet_GreaterThan_inet() var count = context.NetTestEntities.Count(x => EF.Functions.GreaterThan(x.Inet, IPAddress.Parse("192.168.1.7"))); Assert.Equal(2, count); - AssertContainsSql(@"WHERE n.""Inet"" > INET '192.168.1.7'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" > INET '192.168.1.7'"); } [Fact] @@ -263,7 +320,12 @@ public void ValueTuple_cidr_GreaterThan_cidr() .Where(x => EF.Functions.GreaterThan(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" > @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" > @__cidr_1"); } [Fact] @@ -273,7 +335,10 @@ public void PhysicalAddress_macaddr_GreaterThan_macaddr() var count = context.NetTestEntities.Count(x => EF.Functions.GreaterThan(x.Macaddr, PhysicalAddress.Parse("12-34-56-00-00-07"))); Assert.Equal(2, count); - AssertContainsSql(@"""Macaddr"" > MACADDR '123456000007'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Macaddr"" > MACADDR '123456000007'"); } [ConditionalFact] @@ -284,7 +349,10 @@ public void PhysicalAddress_macaddr8_GreaterThan_macaddr8() var count = context.NetTestEntities.Count(x => EF.Functions.GreaterThan(x.Macaddr8, PhysicalAddress.Parse("08-00-2B-01-02-03-04-07"))); Assert.Equal(2, count); - AssertContainsSql(@"""Macaddr8"" > MACADDR8 '08002B0102030407'"); + AssertSql( + @"SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Macaddr8"" > MACADDR8 '08002B0102030407'"); } #endregion @@ -300,7 +368,12 @@ public void IPAddress_inet_ContainedBy_inet() .Where(x => EF.Functions.ContainedBy(x.Inet, inet)) .ToArray(); - AssertContainsSql(@"n.""Inet"" << @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" << @__inet_1"); } [Fact] @@ -312,7 +385,12 @@ public void IPAddress_inet_ContainedBy_cidr() .Where(x => EF.Functions.ContainedBy(x.Inet, cidr)) .ToArray(); - AssertContainsSql(@"n.""Inet"" << @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" << @__cidr_1"); } [Fact] @@ -324,7 +402,12 @@ public void ValueTuple_cidr_ContainedBy_cidr() .Where(x => EF.Functions.ContainedBy(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" << @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" << @__cidr_1"); } [Fact] @@ -336,7 +419,12 @@ public void IPAddress_inet_ContainedByOrEqual_inet() .Where(x => EF.Functions.ContainedByOrEqual(x.Inet, inet)) .ToArray(); - AssertContainsSql(@"n.""Inet"" <<= @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" <<= @__inet_1"); } [Fact] @@ -348,7 +436,12 @@ public void IPAddress_inet_ContainedByOrEqual_cidr() .Where(x => EF.Functions.ContainedByOrEqual(x.Inet, cidr)) .ToArray(); - AssertContainsSql(@"n.""Inet"" <<= @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" <<= @__cidr_1"); } [Fact] @@ -360,7 +453,12 @@ public void ValueTuple_cidr_ContainedByOrEqual_cidr() .Where(x => EF.Functions.ContainedByOrEqual(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" <<= @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" <<= @__cidr_1"); } [Fact] @@ -372,7 +470,12 @@ public void IPAddress_inet_Contains_inet() .Where(x => EF.Functions.Contains(x.Inet, inet)) .ToArray(); - AssertContainsSql(@"n.""Inet"" >> @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" >> @__inet_1"); } [Fact] @@ -384,7 +487,12 @@ public void ValueTuple_cidr_Contains_inet() .Where(x => EF.Functions.Contains(x.Cidr, inet)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" >> @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" >> @__inet_1"); } [Fact] @@ -396,7 +504,12 @@ public void ValueTuple_cidr_Contains_cidr() .Where(x => EF.Functions.Contains(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" >> @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" >> @__cidr_1"); } [Fact] @@ -408,7 +521,12 @@ public void IPAddress_inet_ContainsOrEqual_inet() .Where(x => EF.Functions.ContainsOrEqual(x.Inet, inet)) .ToArray(); - AssertContainsSql(@"n.""Inet"" >>= @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" >>= @__inet_1"); } [Fact] @@ -420,7 +538,12 @@ public void ValueTuple_cidr_ContainsOrEqual_inet() .Where(x => EF.Functions.ContainsOrEqual(x.Cidr, inet)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" >>= @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" >>= @__inet_1"); } [Fact] @@ -432,7 +555,12 @@ public void ValueTuple_cidr_ContainsOrEqual_cidr() .Where(x => EF.Functions.ContainsOrEqual(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" >>= @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" >>= @__cidr_1"); } [Fact] @@ -444,7 +572,12 @@ public void IPAddress_inet_ContainsOrContainedBy_inet() .Where(x => EF.Functions.ContainsOrContainedBy(x.Inet, inet)) .ToArray(); - AssertContainsSql(@"n.""Inet"" && @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" && @__inet_1"); } [Fact] @@ -456,7 +589,12 @@ public void IPAddress_inet_ContainsOrContainedBy_cidr() .Where(x => EF.Functions.ContainsOrContainedBy(x.Inet, cidr)) .ToArray(); - AssertContainsSql(@"n.""Inet"" && @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" && @__cidr_1"); } [Fact] @@ -468,7 +606,12 @@ public void ValueTuple_cidr_ContainsOrContainedBy_inet() .Where(x => EF.Functions.ContainsOrContainedBy(x.Cidr, inet)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" && @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" && @__inet_1"); } [Fact] @@ -480,7 +623,12 @@ public void ValueTuple_cidr_ContainsOrContainedBy_cidr() .Where(x => EF.Functions.ContainsOrContainedBy(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" && @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE n.""Cidr"" && @__cidr_1"); } #endregion @@ -495,7 +643,9 @@ public void IPAddress_inet_BitwiseNot() .Select(x => EF.Functions.BitwiseNot(x.Inet)) .ToArray(); - AssertContainsSql(@"~n.""Inet"""); + AssertSql( + @"SELECT ~n.""Inet"" +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -506,7 +656,9 @@ public void ValueTuple_cidr_BitwiseNot() .Select(x => EF.Functions.BitwiseNot(x.Cidr)) .ToArray(); - AssertContainsSql(@"~n.""Cidr"""); + AssertSql( + @"SELECT ~n.""Cidr"" +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -517,7 +669,9 @@ public void PhysicalAddress_macaddr_BitwiseNot() .Select(x => EF.Functions.BitwiseNot(x.Macaddr)) .ToArray(); - AssertContainsSql(@"~n.""Macaddr"""); + AssertSql( + @"SELECT ~n.""Macaddr"" +FROM ""NetTestEntities"" AS n"); } [ConditionalFact] @@ -529,7 +683,9 @@ public void PhysicalAddress_macaddr8_BitwiseNot() .Select(x => EF.Functions.BitwiseNot(x.Macaddr8)) .ToArray(); - AssertContainsSql(@"~n.""Macaddr8"""); + AssertSql( + @"SELECT ~n.""Macaddr8"" +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -540,7 +696,12 @@ public void IPAddress_inet_BitwiseAnd_inet() var count = context.NetTestEntities.Count(x => x.Inet == EF.Functions.BitwiseAnd(x.Inet, inet)); Assert.Equal(0, count); - AssertContainsSql(@"n.""Inet"" & @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT COUNT(*)::INT +FROM ""NetTestEntities"" AS n +WHERE n.""Inet"" = (n.""Inet"" & @__inet_1) OR (n.""Inet"" IS NULL)"); } [Fact] @@ -552,7 +713,11 @@ public void ValueTuple_cidr_BitwiseAnd_cidr() .Select(x => EF.Functions.BitwiseAnd(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" & @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Cidr"" & @__cidr_1 +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -564,7 +729,11 @@ public void PhysicalAddress_macaddr_BitwiseAnd_macaddr() .Select(x => EF.Functions.BitwiseAnd(x.Macaddr, macaddr)) .ToArray(); - AssertContainsSql(@"n.""Macaddr"" & @__macaddr_1"); + AssertSql( + @"@__macaddr_1='000000000000' (DbType = Object) + +SELECT n.""Macaddr"" & @__macaddr_1 +FROM ""NetTestEntities"" AS n"); } [ConditionalFact] @@ -576,7 +745,9 @@ public void PhysicalAddress_macaddr8_BitwiseAnd_macaddr8() .Select(x => EF.Functions.BitwiseAnd(x.Macaddr8, x.Macaddr8)) .ToArray(); - AssertContainsSql(@"n.""Macaddr8"" & n.""Macaddr8"""); + AssertSql( + @"SELECT n.""Macaddr8"" & n.""Macaddr8"" +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -588,7 +759,11 @@ public void IPAddress_inet_BitwiseOr_inet() .Select(x => EF.Functions.BitwiseOr(x.Inet, inet)) .ToArray(); - AssertContainsSql(@"n.""Inet"" | @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT n.""Inet"" | @__inet_1 +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -600,7 +775,11 @@ public void ValueTuple_cidr_BitwiseOr_cidr() .Select(x => EF.Functions.BitwiseOr(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" | @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Cidr"" | @__cidr_1 +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -612,7 +791,11 @@ public void PhysicalAddress_macaddr_BitwiseOr_macaddr() .Select(x => EF.Functions.BitwiseOr(x.Macaddr, macaddr)) .ToArray(); - AssertContainsSql(@"n.""Macaddr"" | @__macaddr_1"); + AssertSql( + @"@__macaddr_1='000000000000' (DbType = Object) + +SELECT n.""Macaddr"" | @__macaddr_1 +FROM ""NetTestEntities"" AS n"); } [ConditionalFact] @@ -624,7 +807,9 @@ public void PhysicalAddress_macaddr8_BitwiseOr_macaddr8() .Select(x => EF.Functions.BitwiseOr(x.Macaddr8, x.Macaddr8)) .ToArray(); - AssertContainsSql(@"n.""Macaddr8"" | n.""Macaddr8"""); + AssertSql( + @"SELECT n.""Macaddr8"" | n.""Macaddr8"" +FROM ""NetTestEntities"" AS n"); } #endregion @@ -638,7 +823,11 @@ public void IPAddress_inet_Add_int() var actual = context.NetTestEntities.Single(x => EF.Functions.Add(x.Inet, 1) == IPAddress.Parse("192.168.1.2")).Inet; Assert.Equal(actual, IPAddress.Parse("192.168.1.1")); - AssertContainsSql("\"Inet\" + 1"); + AssertSql( + @"SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE (n.""Inet"" + 1) = INET '192.168.1.2' +LIMIT 2"); } [Fact] @@ -649,7 +838,9 @@ public void ValueTuple_cidr_Add_int() .Select(x => EF.Functions.Add(x.Cidr, 1)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" + 1"); + AssertSql( + @"SELECT n.""Cidr"" + 1 +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -659,7 +850,11 @@ public void IPAddress_inet_Subtract_int() var actual = context.NetTestEntities.Single(x => EF.Functions.Subtract(x.Inet, 1) == IPAddress.Parse("192.168.1.1")).Inet; Assert.Equal(actual, IPAddress.Parse("192.168.1.2")); - AssertContainsSql("\"Inet\" - 1"); + AssertSql( + @"SELECT n.""Id"", n.""Cidr"", n.""Inet"", n.""Macaddr"", n.""Macaddr8"", n.""TextInet"", n.""TextMacaddr"" +FROM ""NetTestEntities"" AS n +WHERE (n.""Inet"" - 1) = INET '192.168.1.1' +LIMIT 2"); } [Fact] @@ -670,7 +865,9 @@ public void ValueTuple_cidr_Subtract_int() .Select(x => EF.Functions.Subtract(x.Cidr, 1)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" - 1"); + AssertSql( + @"SELECT n.""Cidr"" - 1 +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -682,7 +879,11 @@ public void IPAddress_inet_Subtract_inet() .Select(x => EF.Functions.Subtract(x.Inet, inet)) .ToArray(); - AssertContainsSql(@"n.""Inet"" - @__inet_1"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT n.""Inet"" - @__inet_1 +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -694,7 +895,11 @@ public void ValueTuple_cidr_Subtract_cidr() .Select(x => EF.Functions.Subtract(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"n.""Cidr"" - @__cidr_1"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT n.""Cidr"" - @__cidr_1 +FROM ""NetTestEntities"" AS n"); } #endregion @@ -709,7 +914,9 @@ public void IPAddress_inet_Abbreviate() .Select(x => EF.Functions.Abbreviate(x.Inet)) .ToArray(); - AssertContainsSql(@"abbrev(n.""Inet"")"); + AssertSql( + @"SELECT abbrev(n.""Inet"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -720,7 +927,9 @@ public void ValueTuple_cidr_Abbreviate() .Select(x => EF.Functions.Abbreviate(x.Cidr)) .ToArray(); - AssertContainsSql(@"abbrev(n.""Cidr"")"); + AssertSql( + @"SELECT abbrev(n.""Cidr"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -731,7 +940,9 @@ public void IPAddress_inet_Broadcast() .Select(x => EF.Functions.Broadcast(x.Inet)) .ToArray(); - AssertContainsSql(@"broadcast(n.""Inet"")"); + AssertSql( + @"SELECT broadcast(n.""Inet"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -742,7 +953,9 @@ public void ValueTuple_cidr_Broadcast() .Select(x => EF.Functions.Broadcast(x.Cidr)) .ToArray(); - AssertContainsSql(@"broadcast(n.""Cidr"")"); + AssertSql( + @"SELECT broadcast(n.""Cidr"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -753,7 +966,9 @@ public void IPAddress_inet_Family() .Select(x => EF.Functions.Family(x.Inet)) .ToArray(); - AssertContainsSql(@"family(n.""Inet"")"); + AssertSql( + @"SELECT family(n.""Inet"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -764,7 +979,9 @@ public void ValueTuple_cidr_Family() .Select(x => EF.Functions.Family(x.Cidr)) .ToArray(); - AssertContainsSql(@"family(n.""Cidr"")"); + AssertSql( + @"SELECT family(n.""Cidr"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -775,7 +992,9 @@ public void IPAddress_inet_Host() .Select(x => EF.Functions.Host(x.Inet)) .ToArray(); - AssertContainsSql(@"host(n.""Inet"")"); + AssertSql( + @"SELECT host(n.""Inet"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -786,7 +1005,9 @@ public void ValueTuple_cidr_Host() .Select(x => EF.Functions.Host(x.Cidr)) .ToArray(); - AssertContainsSql(@"host(n.""Cidr"")"); + AssertSql( + @"SELECT host(n.""Cidr"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -797,7 +1018,9 @@ public void IPAddress_inet_HostMask() .Select(x => EF.Functions.HostMask(x.Inet)) .ToArray(); - AssertContainsSql(@"hostmask(n.""Inet"")"); + AssertSql( + @"SELECT hostmask(n.""Inet"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -808,7 +1031,9 @@ public void ValueTuple_cidr_HostMask() .Select(x => EF.Functions.HostMask(x.Cidr)) .ToArray(); - AssertContainsSql(@"hostmask(n.""Cidr"")"); + AssertSql( + @"SELECT hostmask(n.""Cidr"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -819,7 +1044,9 @@ public void IPAddress_inet_MaskLength() .Select(x => EF.Functions.MaskLength(x.Inet)) .ToArray(); - AssertContainsSql(@"masklen(n.""Inet"")"); + AssertSql( + @"SELECT masklen(n.""Inet"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -830,7 +1057,9 @@ public void ValueTuple_cidr_MaskLength() .Select(x => EF.Functions.MaskLength(x.Cidr)) .ToArray(); - AssertContainsSql(@"masklen(n.""Cidr"")"); + AssertSql( + @"SELECT masklen(n.""Cidr"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -841,7 +1070,9 @@ public void IPAddress_inet_Netmask() .Select(x => EF.Functions.Netmask(x.Inet)) .ToArray(); - AssertContainsSql(@"netmask(n.""Inet"")"); + AssertSql( + @"SELECT netmask(n.""Inet"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -852,7 +1083,9 @@ public void ValueTuple_cidr_Netmask() .Select(x => EF.Functions.Netmask(x.Cidr)) .ToArray(); - AssertContainsSql(@"netmask(n.""Cidr"")"); + AssertSql( + @"SELECT netmask(n.""Cidr"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -863,7 +1096,9 @@ public void IPAddress_inet_Network() .Select(x => EF.Functions.Network(x.Inet)) .ToArray(); - AssertContainsSql(@"network(n.""Inet"")"); + AssertSql( + @"SELECT network(n.""Inet"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -874,7 +1109,9 @@ public void ValueTuple_cidr_Network() .Select(x => EF.Functions.Network(x.Cidr)) .ToArray(); - AssertContainsSql(@"network(n.""Cidr"")"); + AssertSql( + @"SELECT network(n.""Cidr"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -885,7 +1122,9 @@ public void IPAddress_inet_SetMaskLength() .Select(x => EF.Functions.SetMaskLength(x.Inet, default)) .ToArray(); - AssertContainsSql(@"set_masklen(n.""Inet"", 0)"); + AssertSql( + @"SELECT set_masklen(n.""Inet"", 0) +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -896,7 +1135,9 @@ public void ValueTuple_cidr_SetMaskLength() .Select(x => EF.Functions.SetMaskLength(x.Cidr, default)) .ToArray(); - AssertContainsSql(@"set_masklen(n.""Cidr"", 0)"); + AssertSql( + @"SELECT set_masklen(n.""Cidr"", 0) +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -907,7 +1148,9 @@ public void IPAddress_inet_Text() .Select(x => EF.Functions.Text(x.Inet)) .ToArray(); - AssertContainsSql(@"text(n.""Inet"")"); + AssertSql( + @"SELECT text(n.""Inet"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -918,7 +1161,9 @@ public void ValueTuple_cidr_Text() .Select(x => EF.Functions.Text(x.Cidr)) .ToArray(); - AssertContainsSql(@"text(n.""Cidr"")"); + AssertSql( + @"SELECT text(n.""Cidr"") +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -930,7 +1175,11 @@ public void IPAddress_inet_SameFamily() .Select(x => EF.Functions.SameFamily(x.Inet, inet)) .ToArray(); - AssertContainsSql(@"inet_same_family(n.""Inet"", @__inet_1)"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT inet_same_family(n.""Inet"", @__inet_1) +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -942,7 +1191,11 @@ public void ValueTuple_cidr_SameFamily() .Select(x => EF.Functions.SameFamily(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"inet_same_family(n.""Cidr"", @__cidr_1)"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT inet_same_family(n.""Cidr"", @__cidr_1) +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -954,7 +1207,11 @@ public void IPAddress_inet_Merge() .Select(x => EF.Functions.Merge(x.Inet, inet)) .ToArray(); - AssertContainsSql(@"inet_merge(n.""Inet"", @__inet_1)"); + AssertSql( + @"@__inet_1='0.0.0.0' (DbType = Object) + +SELECT inet_merge(n.""Inet"", @__inet_1) +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -966,7 +1223,11 @@ public void ValueTuple_cidr_Merge() .Select(x => EF.Functions.Merge(x.Cidr, cidr)) .ToArray(); - AssertContainsSql(@"inet_merge(n.""Cidr"", @__cidr_1)"); + AssertSql( + @"@__cidr_1='(0.0.0.0, 0)' (DbType = Object) + +SELECT inet_merge(n.""Cidr"", @__cidr_1) +FROM ""NetTestEntities"" AS n"); } [Fact] @@ -977,7 +1238,9 @@ public void PhysicalAddress_macaddr_Truncate() .Select(x => EF.Functions.Truncate(x.Macaddr)) .ToArray(); - AssertContainsSql(@"trunc(n.""Macaddr"")"); + AssertSql( + @"SELECT trunc(n.""Macaddr"") +FROM ""NetTestEntities"" AS n"); } [ConditionalFact] @@ -989,7 +1252,9 @@ public void PhysicalAddress_macaddr8_Truncate() .Select(x => EF.Functions.Truncate(x.Macaddr8)) .ToArray(); - AssertContainsSql(@"trunc(n.""Macaddr8"")"); + AssertSql( + @"SELECT trunc(n.""Macaddr8"") +FROM ""NetTestEntities"" AS n"); } [ConditionalFact] @@ -1001,7 +1266,9 @@ public void PhysicalAddress_macaddr8_Set7BitMac8() .Select(x => EF.Functions.Set7BitMac8(x.Macaddr8)) .ToArray(); - AssertContainsSql(@"macaddr8_set7bit(n.""Macaddr8"")"); + AssertSql( + @"SELECT macaddr8_set7bit(n.""Macaddr8"") +FROM ""NetTestEntities"" AS n"); } #endregion @@ -1122,11 +1389,5 @@ public static void Seed(NetContext context) private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); - /// - /// Asserts that the SQL fragment appears in the logs. - /// - /// The SQL statement or fragment to search for in the logs. - private void AssertContainsSql(string sql) => Assert.Contains(sql, Fixture.TestSqlLoggerFactory.Sql); - #endregion -} \ No newline at end of file +} diff --git a/test/EFCore.PG.FunctionalTests/Query/NorthwindAggregateOperatorsQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/NorthwindAggregateOperatorsQueryNpgsqlTest.cs index 8d18aa265bb2341be0961918515148d3d3e36910..139b54bcff34788ef11334e6baf3b1c8ea2a08cf 100644 --- a/test/EFCore.PG.FunctionalTests/Query/NorthwindAggregateOperatorsQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/NorthwindAggregateOperatorsQueryNpgsqlTest.cs @@ -1,3 +1,6 @@ +using Microsoft.EntityFrameworkCore.TestModels.Northwind; +using Npgsql.EntityFrameworkCore.PostgreSQL.Internal; + namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query; public class NorthwindAggregateOperatorsQueryNpgsqlTest : NorthwindAggregateOperatorsQueryRelationalTestBase> @@ -10,6 +13,16 @@ public NorthwindAggregateOperatorsQueryNpgsqlTest(NorthwindQueryNpgsqlFixture AssertAverage( + async, + ss => ss.Set().OrderBy(c => c.CustomerID).Take(3), + selector: c => (decimal)c.Orders.Average(o => 5 + o.OrderDetails.Max(od => od.ProductID)), + asserter: (a, b) => Assert.Equal(a, b, 15)); + public override async Task Contains_with_local_uint_array_closure(bool async) { await base.Contains_with_local_uint_array_closure(async); @@ -49,9 +62,16 @@ public override async Task Contains_with_local_nullable_uint_array_closure(bool WHERE e.""EmployeeID"" = ANY (@__ids_0)"); } + public override async Task Contains_with_local_anonymous_type_array_closure(bool async) + // Aggregates. Issue #15937. + => await AssertTranslationFailed(() => base.Contains_with_local_anonymous_type_array_closure(async)); + + public override async Task Contains_with_local_tuple_array_closure(bool async) + => await AssertTranslationFailed(() => base.Contains_with_local_tuple_array_closure(async)); + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); protected override void ClearLog() => Fixture.TestSqlLoggerFactory.Clear(); -} \ No newline at end of file +} diff --git a/test/EFCore.PG.FunctionalTests/Query/NorthwindFunctionsQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/NorthwindFunctionsQueryNpgsqlTest.cs index a32764f7fa74ec1355f82e3a1a47bf0a5f564ad1..8d104b65d99839f7381b9a386fcfe7eb6dec08fd 100644 --- a/test/EFCore.PG.FunctionalTests/Query/NorthwindFunctionsQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/NorthwindFunctionsQueryNpgsqlTest.cs @@ -21,7 +21,7 @@ public override async Task IsNullOrWhiteSpace_in_predicate(bool async) AssertSql( @"SELECT c.""CustomerID"", c.""Address"", c.""City"", c.""CompanyName"", c.""ContactName"", c.""ContactTitle"", c.""Country"", c.""Fax"", c.""Phone"", c.""PostalCode"", c.""Region"" FROM ""Customers"" AS c -WHERE (c.""Region"" IS NULL) OR (btrim(c.""Region"", E' \t\n\r') = '')"); +WHERE (c.""Region"" IS NULL) OR btrim(c.""Region"", E' \t\n\r') = ''"); } public override Task Where_math_log_new_base(bool async) @@ -294,4 +294,4 @@ protected override void ClearLog() private void AssertContainsSqlFragment(string expectedFragment) => Assert.Contains(Fixture.TestSqlLoggerFactory.SqlStatements, s => s.Contains(expectedFragment)); -} \ No newline at end of file +} diff --git a/test/EFCore.PG.FunctionalTests/Query/NorthwindSelectQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/NorthwindSelectQueryNpgsqlTest.cs index 9dd83b432da96500195dee667a2fd7616edd714b..212d20dd27b7ece533b25a1d61d9d56d21c76215 100644 --- a/test/EFCore.PG.FunctionalTests/Query/NorthwindSelectQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/NorthwindSelectQueryNpgsqlTest.cs @@ -19,6 +19,10 @@ public override async Task Select_datetime_DayOfWeek_component(bool async) FROM ""Orders"" AS o"); } + [ConditionalTheory(Skip = "https://github.com/dotnet/efcore/issues/27152")] + public override Task Reverse_in_subquery_via_pushdown(bool async) + => base.Reverse_in_subquery_via_pushdown(async); + public override Task Member_binding_after_ctor_arguments_fails_with_client_eval(bool async) => AssertTranslationFailed(() => base.Member_binding_after_ctor_arguments_fails_with_client_eval(async)); @@ -27,4 +31,4 @@ private void AssertSql(params string[] expected) protected override void ClearLog() => Fixture.TestSqlLoggerFactory.Clear(); -} \ No newline at end of file +} diff --git a/test/EFCore.PG.FunctionalTests/Query/PostgresOptimizationsQueryTest.cs b/test/EFCore.PG.FunctionalTests/Query/PostgresOptimizationsQueryTest.cs index 615026b4d11fcb751878b815fcfcb7a44f475f80..2ee5178492097c4caa857b9aa3d4ed32b0099e4f 100644 --- a/test/EFCore.PG.FunctionalTests/Query/PostgresOptimizationsQueryTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/PostgresOptimizationsQueryTest.cs @@ -39,7 +39,7 @@ public async Task Row_value_comparison_not_rewritten_with_incompatible_operators AssertSql( @"SELECT e.""Id"", e.""X"", e.""Y"", e.""Z"" FROM ""Entities"" AS e -WHERE (e.""X"" > 5) OR ((e.""X"" = 5) AND (e.""Y"" < 6))"); +WHERE e.""X"" > 5 OR (e.""X"" = 5 AND e.""Y"" < 6)"); } [ConditionalTheory] @@ -54,7 +54,7 @@ public async Task Row_value_comparison_not_rewritten_with_incompatible_operands( AssertSql( @"SELECT e.""Id"", e.""X"", e.""Y"", e.""Z"" FROM ""Entities"" AS e -WHERE (e.""Z"" > 5) OR ((e.""X"" = 5) AND (e.""Y"" > 6))"); +WHERE e.""Z"" > 5 OR (e.""X"" = 5 AND e.""Y"" > 6)"); } [ConditionalTheory] diff --git a/test/EFCore.PG.FunctionalTests/Query/TPTGearsOfWarQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/TPTGearsOfWarQueryNpgsqlTest.cs index 93ed75ded54345ed538dc99ec2f058d9773dcbd1..38e2f547051bc42fbcecd3e4d42a8c9f2d8bda13 100644 --- a/test/EFCore.PG.FunctionalTests/Query/TPTGearsOfWarQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/TPTGearsOfWarQueryNpgsqlTest.cs @@ -50,7 +50,7 @@ public override async Task DateTimeOffset_Contains_Less_than_Greater_than(bool a SELECT m.""Id"", m.""CodeName"", m.""Date"", m.""Duration"", m.""Rating"", m.""Time"", m.""Timeline"" FROM ""Missions"" AS m -WHERE ((@__start_0 <= date_trunc('day', m.""Timeline"")::timestamptz) AND (m.""Timeline"" < @__end_1)) AND m.""Timeline"" = ANY (@__dates_2)"); +WHERE @__start_0 <= date_trunc('day', m.""Timeline"")::timestamptz AND m.""Timeline"" < @__end_1 AND m.""Timeline"" = ANY (@__dates_2)"); } public override async Task DateTimeOffset_Date_returns_datetime(bool async) diff --git a/test/EFCore.PG.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs b/test/EFCore.PG.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs index 4e8e3f04f48728ea4e014c6a5323377c9e34def1..8d9c01ea2e7eac243b97aaae7d5e86c5a279d0f0 100644 --- a/test/EFCore.PG.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs +++ b/test/EFCore.PG.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs @@ -38,7 +38,9 @@ public IRelationalCommandBuilder AddParameter(IRelationalParameter parameter) return this; } - public IRelationalTypeMappingSource TypeMappingSource => Dependencies.TypeMappingSource; + [Obsolete("Code trying to add parameter should add type mapped parameter using TypeMappingSource directly.")] + public IRelationalTypeMappingSource TypeMappingSource + => Dependencies.TypeMappingSource; public IRelationalCommand Build() => new TestRelationalCommand( @@ -216,4 +218,4 @@ private string PreExecution(IRelationalConnection connection) public void PopulateFrom(IRelationalCommandTemplate command) => _realRelationalCommand.PopulateFrom(command); } -} \ No newline at end of file +} diff --git a/test/EFCore.PG.Tests/NpgsqlRelationalConnectionTest.cs b/test/EFCore.PG.Tests/NpgsqlRelationalConnectionTest.cs index 87374d78a3dd8b2ec130fabc90612eca6c3b847b..e00691d122166e86e74dbc9f5285b49f716fb87e 100644 --- a/test/EFCore.PG.Tests/NpgsqlRelationalConnectionTest.cs +++ b/test/EFCore.PG.Tests/NpgsqlRelationalConnectionTest.cs @@ -75,7 +75,8 @@ public static RelationalConnectionDependencies CreateDependencies(DbContextOptio TestServiceFactory.Instance.Create(), TestServiceFactory.Instance.Create(), new NpgsqlSqlGenerationHelper(new RelationalSqlGenerationHelperDependencies()), - new NpgsqlOptions())))); + new NpgsqlOptions()), + new ExceptionDetector()))); } private const string ConnectionString = "Fake Connection String"; @@ -96,4 +97,4 @@ public static RelationalConnectionDependencies CreateDependencies(DbContextOptio private class FakeDbContext : DbContext { } -} \ No newline at end of file +} diff --git a/test/EFCore.PG.Tests/TestUtilities/FakeRelationalCommandDiagnosticsLogger.cs b/test/EFCore.PG.Tests/TestUtilities/FakeRelationalCommandDiagnosticsLogger.cs index f81a5199d0e14e13be395a8643296db73d2e0ab5..00e212610923c7249a6f017b9d04eca5204e420f 100644 --- a/test/EFCore.PG.Tests/TestUtilities/FakeRelationalCommandDiagnosticsLogger.cs +++ b/test/EFCore.PG.Tests/TestUtilities/FakeRelationalCommandDiagnosticsLogger.cs @@ -195,6 +195,32 @@ public class FakeRelationalCommandDiagnosticsLogger CancellationToken cancellationToken = default) => Task.CompletedTask; + public void CommandCanceled( + IRelationalConnection connection, + DbCommand command, + DbContext? context, + DbCommandMethod executeMethod, + Guid commandId, + Guid connectionId, + DateTimeOffset startTime, + TimeSpan duration, + CommandSource commandSource) + { + } + + public Task CommandCanceledAsync( + IRelationalConnection connection, + DbCommand command, + DbContext? context, + DbCommandMethod executeMethod, + Guid commandId, + Guid connectionId, + DateTimeOffset startTime, + TimeSpan duration, + CommandSource commandSource, + CancellationToken cancellationToken = default) + => Task.CompletedTask; + public InterceptionResult DataReaderDisposing( IRelationalConnection connection, DbCommand command, @@ -214,4 +240,4 @@ public bool ShouldLogCommandExecute(DateTimeOffset now) public bool ShouldLogDataReaderDispose(DateTimeOffset now) => true; -} \ No newline at end of file +} diff --git a/test/EFCore.PG.Tests/Update/NpgsqlModificationCommandBatchFactoryTest.cs b/test/EFCore.PG.Tests/Update/NpgsqlModificationCommandBatchFactoryTest.cs index bbbf847c1ad2b7b46c85293a2b97f62f1a9ddc89..a2f4f7222206a3e4c55781e43009ba3e939a0e72 100644 --- a/test/EFCore.PG.Tests/Update/NpgsqlModificationCommandBatchFactoryTest.cs +++ b/test/EFCore.PG.Tests/Update/NpgsqlModificationCommandBatchFactoryTest.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore.Infrastructure.Internal; +using Microsoft.EntityFrameworkCore.Storage.Internal; using Microsoft.EntityFrameworkCore.Update.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal; @@ -27,7 +28,8 @@ public void Uses_MaxBatchSize_specified_in_NpgsqlOptionsExtension() new ModificationCommandBatchFactoryDependencies( new RelationalCommandBuilderFactory( new RelationalCommandBuilderDependencies( - typeMapper)), + typeMapper, + new ExceptionDetector())), new NpgsqlSqlGenerationHelper( new RelationalSqlGenerationHelperDependencies()), new NpgsqlUpdateSqlGenerator( @@ -66,7 +68,8 @@ public void MaxBatchSize_is_optional() new ModificationCommandBatchFactoryDependencies( new RelationalCommandBuilderFactory( new RelationalCommandBuilderDependencies( - typeMapper)), + typeMapper, + new ExceptionDetector())), new NpgsqlSqlGenerationHelper( new RelationalSqlGenerationHelperDependencies()), new NpgsqlUpdateSqlGenerator( @@ -104,4 +107,4 @@ private class FakeDbContext : DbContext return modificationCommand; } -} \ No newline at end of file +} diff --git a/test/EFCore.PG.Tests/Update/NpgsqlModificationCommandBatchTest.cs b/test/EFCore.PG.Tests/Update/NpgsqlModificationCommandBatchTest.cs index 348d680a86ed79e3ff2c3d69b30f26d72db1c0a7..37184c60e110a7f23d580912e616fe021cfec0e5 100644 --- a/test/EFCore.PG.Tests/Update/NpgsqlModificationCommandBatchTest.cs +++ b/test/EFCore.PG.Tests/Update/NpgsqlModificationCommandBatchTest.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore.Infrastructure.Internal; +using Microsoft.EntityFrameworkCore.Storage.Internal; using Microsoft.EntityFrameworkCore.Update.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal; @@ -25,7 +26,8 @@ public void AddCommand_returns_false_when_max_batch_size_is_reached() new ModificationCommandBatchFactoryDependencies( new RelationalCommandBuilderFactory( new RelationalCommandBuilderDependencies( - typeMapper)), + typeMapper, + new ExceptionDetector())), new NpgsqlSqlGenerationHelper( new RelationalSqlGenerationHelperDependencies()), new NpgsqlUpdateSqlGenerator( @@ -65,4 +67,4 @@ private class FakeDbContext : DbContext return modificationCommand; } -} \ No newline at end of file +}