Skip to content

Commit

Permalink
Sync to EF 10.0.0-alpha.1.24620.1 (#3416)
Browse files Browse the repository at this point in the history
Implement the new translation tests
roji authored Dec 22, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 6068de4 commit 174a0e3
Showing 24 changed files with 5,346 additions and 984 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ on:
pull_request:

env:
dotnet_sdk_version: '9.0.100'
dotnet_sdk_version: '10.0.100-alpha.1.24620.13'
postgis_version: 3
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true

2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ on:
- cron: '30 22 * * 6'

env:
dotnet_sdk_version: '9.0.100'
dotnet_sdk_version: '10.0.100-alpha.1.24620.13'

jobs:
analyze:
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project>
<PropertyGroup>
<VersionPrefix>10.0.0</VersionPrefix>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AnalysisLevel>latest</AnalysisLevel>
4 changes: 2 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<EFCoreVersion>10.0.0-alpha.1.24610.3</EFCoreVersion>
<MicrosoftExtensionsVersion>10.0.0-alpha.1.24609.1</MicrosoftExtensionsVersion>
<EFCoreVersion>10.0.0-alpha.1.24620.1</EFCoreVersion>
<MicrosoftExtensionsVersion>10.0.0-alpha.1.24616.1</MicrosoftExtensionsVersion>
<NpgsqlVersion>9.0.2</NpgsqlVersion>
</PropertyGroup>

4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"sdk": {
"version": "9.0.100",
"version": "10.0.100-alpha.1.24620.13",
"rollForward": "latestMajor",
"allowPrerelease": false
"allowPrerelease": true
}
}
2 changes: 0 additions & 2 deletions src/EFCore.PG.NTS/EFCore.PG.NTS.csproj
Original file line number Diff line number Diff line change
@@ -2,8 +2,6 @@
<PropertyGroup>
<AssemblyName>Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite</AssemblyName>
<RootNamespace>Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite</RootNamespace>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework Condition="'$(DeveloperBuild)' == 'True'">net8.0</TargetFramework>

<Authors>Shay Rojansky</Authors>
<Description>NetTopologySuite PostGIS spatial support plugin for PostgreSQL/Npgsql Entity Framework Core provider.</Description>
2 changes: 0 additions & 2 deletions src/EFCore.PG.NodaTime/EFCore.PG.NodaTime.csproj
Original file line number Diff line number Diff line change
@@ -2,8 +2,6 @@
<PropertyGroup>
<AssemblyName>Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime</AssemblyName>
<RootNamespace>Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime</RootNamespace>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework Condition="'$(DeveloperBuild)' == 'True'">net8.0</TargetFramework>

<Authors>Shay Rojansky</Authors>
<Description>NodaTime support plugin for PostgreSQL/Npgsql Entity Framework Core provider.</Description>
1 change: 0 additions & 1 deletion src/EFCore.PG/EFCore.PG.csproj
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
<PropertyGroup>
<AssemblyName>Npgsql.EntityFrameworkCore.PostgreSQL</AssemblyName>
<RootNamespace>Npgsql.EntityFrameworkCore.PostgreSQL</RootNamespace>
<TargetFramework>net8.0</TargetFramework>

<Authors>Shay Rojansky;Austin Drenski;Yoh Deadfall;</Authors>
<Description>PostgreSQL/Npgsql provider for Entity Framework Core.</Description>
1 change: 0 additions & 1 deletion test/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
<Import Project="..\Directory.Build.props" />

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<IsPackable>false</IsPackable>
<GenerateDocumentationFile>false</GenerateDocumentationFile>

Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

<PropertyGroup>
<AssemblyName>Npgsql.EntityFrameworkCore.PostgreSQL.FunctionalTests</AssemblyName>
<RootNamespace>Npgsql.EntityFrameworkCore.PostgreSQL</RootNamespace>
<RootNamespace>Microsoft.EntityFrameworkCore</RootNamespace>
<PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>

509 changes: 0 additions & 509 deletions test/EFCore.PG.FunctionalTests/Query/GearsOfWarQueryNpgsqlTest.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -17,50 +17,6 @@ public NorthwindFunctionsQueryNpgsqlTest(
Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}

public override async Task IsNullOrWhiteSpace_in_predicate(bool async)
{
await base.IsNullOrWhiteSpace_in_predicate(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') = ''
""");
}

// PostgreSQL only has log(x, base) over numeric, may be possible to cast back and forth though
public override Task Where_math_log_new_base(bool async)
=> AssertTranslationFailed(() => base.Where_math_log_new_base(async));

// PostgreSQL only has log(x, base) over numeric, may be possible to cast back and forth though
public override Task Where_mathf_log_new_base(bool async)
=> AssertTranslationFailed(() => base.Where_mathf_log_new_base(async));

// PostgreSQL only has round(v, s) over numeric, may be possible to cast back and forth though
public override Task Where_mathf_round2(bool async)
=> AssertTranslationFailed(() => base.Where_mathf_round2(async));

// Convert on DateTime not yet supported
public override Task Convert_ToString(bool async)
=> AssertTranslationFailed(() => base.Convert_ToString(async));

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public override async Task String_Join_non_aggregate(bool async)
{
await base.String_Join_non_aggregate(async);

AssertSql(
"""
@foo='foo'
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 concat_ws('|', c."CompanyName", @foo, '', 'bar') = 'Around the Horn|foo||bar'
""");
}

#region Substring

[ConditionalTheory]
@@ -570,42 +526,6 @@ public void Regex_Count_with_unsupported_option()

#endregion Regex

#region Guid

private static string UuidGenerationFunction { get; } = TestEnvironment.PostgresVersion.AtLeast(13)
? "gen_random_uuid"
: "uuid_generate_v4";

public override async Task Where_guid_newguid(bool async)
{
await base.Where_guid_newguid(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 {UuidGenerationFunction}() <> '00000000-0000-0000-0000-000000000000'
""");
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual async Task OrderBy_Guid_NewGuid(bool async)
{
await AssertQuery(
async,
ods => ods.Set<OrderDetail>().OrderBy(od => Guid.NewGuid()).Select(x => x));

AssertSql(
$"""
SELECT o."OrderID", o."ProductID", o."Discount", o."Quantity", o."UnitPrice"
FROM "Order Details" AS o
ORDER BY {UuidGenerationFunction}() NULLS FIRST
""");
}

#endregion

#region PadLeft, PadRight

[ConditionalTheory]
@@ -684,66 +604,6 @@ public Task PadRight_char_with_parameter(bool async)

#region Aggregate functions

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

AssertSql(
"""
SELECT c."City", COALESCE(string_agg(c."CustomerID", '|'), '') AS "Customers"
FROM "Customers" AS c
GROUP BY c."City"
""");
}

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

AssertSql(
"""
SELECT c."City", COALESCE(string_agg(COALESCE(c."Region", ''), '|'), '') AS "Regions"
FROM "Customers" AS c
GROUP BY c."City"
""");
}

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

AssertSql(
"""
SELECT c."City", COALESCE(string_agg(c."CustomerID", '|') FILTER (WHERE length(c."ContactName")::int > 10), '') AS "Customers"
FROM "Customers" AS c
GROUP BY c."City"
""");
}

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

AssertSql(
"""
SELECT c."City", COALESCE(string_agg(c."CustomerID", '|' ORDER BY c."CustomerID" DESC NULLS LAST), '') AS "Customers"
FROM "Customers" AS c
GROUP BY c."City"
""");
}

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

AssertSql(
"""
SELECT c."City", COALESCE(string_agg(c."CustomerID", ''), '') AS "Customers"
FROM "Customers" AS c
GROUP BY c."City"
""");
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual async Task GroupBy_ArrayAgg(bool async)
@@ -1193,38 +1053,6 @@ SELECT NULLIF(o."OrderID", 1)

#endregion

#region Unsupported

// PostgreSQL does not have strpos with starting position
public override Task Indexof_with_constant_starting_position(bool async)
=> AssertTranslationFailed(() => base.Indexof_with_constant_starting_position(async));

// PostgreSQL does not have strpos with starting position
public override Task Indexof_with_parameter_starting_position(bool async)
=> AssertTranslationFailed(() => base.Indexof_with_parameter_starting_position(async));

// These tests convert (among other things) to and from boolean, which PostgreSQL
// does not support (https://github.com/dotnet/efcore/issues/19606)
public override Task Convert_ToBoolean(bool async)
=> Task.CompletedTask;

public override Task Convert_ToByte(bool async)
=> Task.CompletedTask;

public override Task Convert_ToDecimal(bool async)
=> Task.CompletedTask;

public override Task Convert_ToDouble(bool async)
=> Task.CompletedTask;

public override Task Convert_ToInt16(bool async)
=> Task.CompletedTask;

public override Task Convert_ToInt64(bool async)
=> Task.CompletedTask;

#endregion Unsupported

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

Original file line number Diff line number Diff line change
@@ -199,18 +199,6 @@ ORDER BY o0."CustomerID" NULLS FIRST
""");
}

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

AssertSql(
"""
SELECT o."OrderID", o."CustomerID", o."EmployeeID", o."OrderDate"
FROM "Orders" AS o
WHERE (o."OrderID" # 1) = 10249
""");
}

// TODO: #3406
public override Task Where_nanosecond_and_microsecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_nanosecond_and_microsecond_component(async));
156 changes: 0 additions & 156 deletions test/EFCore.PG.FunctionalTests/Query/NorthwindWhereQueryNpgsqlTest.cs
Original file line number Diff line number Diff line change
@@ -13,162 +13,6 @@ public NorthwindWhereQueryNpgsqlTest(NorthwindQueryNpgsqlFixture<NoopModelCustom
Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}

#region Date and time

public override Task Where_datetime_now(bool async)
=> Task.CompletedTask; // See TimestampQueryTest

public override Task Where_datetime_utcnow(bool async)
=> Task.CompletedTask; // See TimestampQueryTest

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

AssertSql(
"""
SELECT e."EmployeeID", e."City", e."Country", e."FirstName", e."ReportsTo", e."Title"
FROM "Employees" AS e
""");
}

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

AssertSql(
"""
SELECT o."OrderDate"::time
FROM "Orders" AS o
""");
}

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

AssertSql(
"""
@myDatetime='1998-05-04T00:00:00.0000000'
SELECT o."OrderID", o."CustomerID", o."EmployeeID", o."OrderDate"
FROM "Orders" AS o
WHERE date_trunc('day', o."OrderDate") = @myDatetime
""");
}

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

AssertSql(
"""
SELECT o."OrderID", o."CustomerID", o."EmployeeID", o."OrderDate"
FROM "Orders" AS o
WHERE date_part('year', o."OrderDate" + INTERVAL '-1 years')::int = 1997
""");
}

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

AssertSql(
"""
SELECT o."OrderID", o."CustomerID", o."EmployeeID", o."OrderDate"
FROM "Orders" AS o
WHERE date_part('year', o."OrderDate")::int = 1998
""");
}

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

AssertSql(
"""
SELECT o."OrderID", o."CustomerID", o."EmployeeID", o."OrderDate"
FROM "Orders" AS o
WHERE date_part('month', o."OrderDate")::int = 4
""");
}

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

AssertSql(
"""
SELECT o."OrderID", o."CustomerID", o."EmployeeID", o."OrderDate"
FROM "Orders" AS o
WHERE date_part('doy', o."OrderDate")::int = 68
""");
}

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

AssertSql(
"""
SELECT o."OrderID", o."CustomerID", o."EmployeeID", o."OrderDate"
FROM "Orders" AS o
WHERE date_part('day', o."OrderDate")::int = 4
""");
}

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

AssertSql(
"""
SELECT o."OrderID", o."CustomerID", o."EmployeeID", o."OrderDate"
FROM "Orders" AS o
WHERE date_part('hour', o."OrderDate")::int = 0
""");
}

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

AssertSql(
"""
SELECT o."OrderID", o."CustomerID", o."EmployeeID", o."OrderDate"
FROM "Orders" AS o
WHERE date_part('minute', o."OrderDate")::int = 0
""");
}

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

AssertSql(
"""
SELECT o."OrderID", o."CustomerID", o."EmployeeID", o."OrderDate"
FROM "Orders" AS o
WHERE date_part('second', o."OrderDate")::int = 0
""");
}

public override Task Where_datetime_millisecond_component(bool async)
=> Task.CompletedTask; // SQL translation not implemented, too annoying

public override Task Where_datetimeoffset_now_component(bool async)
=> Task.CompletedTask; // https://github.com/npgsql/efcore.pg/issues/873

public override Task Where_datetimeoffset_utcnow_component(bool async)
=> Task.CompletedTask; // https://github.com/npgsql/efcore.pg/issues/873

#endregion Date and time

// Test uses DateTimeOffset with non-zero offset, which we don't support.
// See supported DateTimeOffset scenarios in TimestampQueryTest
public override Task Where_datetimeoffset_utcnow(bool async)
=> Task.CompletedTask;

public override async Task Where_bitwise_xor(bool async)
{
await base.Where_bitwise_xor(async);
Original file line number Diff line number Diff line change
@@ -11,10 +11,6 @@ public TPCGearsOfWarQueryNpgsqlTest(TPCGearsOfWarQueryNpgsqlFixture fixture, ITe
Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}

[ConditionalTheory(Skip = "https://github.com/npgsql/efcore.pg/issues/2039")]
public override Task Where_DateOnly_Year(bool async)
=> base.Where_DateOnly_Year(async);

// Base implementation uses DateTimeOffset.Now, which we don't translate by design. Use DateTimeOffset.UtcNow instead.
public override async Task Select_datetimeoffset_comparison_in_projection(bool async)
{
@@ -72,68 +68,11 @@ WHERE date_trunc('day', m."Timeline" AT TIME ZONE 'UTC')::timestamp >= @dateTime
""");
}

public override async Task Where_datetimeoffset_date_component(bool async)
{
await AssertQuery(
async,
ss => from m in ss.Set<Mission>()
where m.Timeline.Date > new DateTime(1)
select m);

AssertSql(
"""
SELECT m."Id", m."CodeName", m."Date", m."Difficulty", m."Duration", m."Rating", m."Time", m."Timeline"
FROM "Missions" AS m
WHERE date_trunc('day', m."Timeline" AT TIME ZONE 'UTC') > TIMESTAMP '0001-01-01T00:00:00'
""");
}

// Not supported by design: we support getting a local DateTime via DateTime.Now (based on PG TimeZone), but there's no way to get a
// non-UTC DateTimeOffset.
public override Task Where_datetimeoffset_now(bool async)
=> Assert.ThrowsAsync<InvalidOperationException>(() => base.Where_datetimeoffset_now(async));

// Not supported by design: we support getting a local DateTime via DateTime.Now (based on PG TimeZone), but there's no way to get a
// non-UTC DateTimeOffset.
public override Task DateTimeOffsetNow_minus_timespan(bool async)
=> Assert.ThrowsAsync<InvalidOperationException>(() => base.DateTimeOffsetNow_minus_timespan(async));

// SQL translation not implemented, too annoying
public override Task Where_datetimeoffset_millisecond_component(bool async)
=> Assert.ThrowsAsync<InvalidOperationException>(() => base.Where_datetimeoffset_millisecond_component(async));

public override Task DateTimeOffset_to_unix_time_milliseconds(bool async)
=> AssertTranslationFailed(() => base.DateTimeOffset_to_unix_time_milliseconds(async));

public override Task DateTimeOffset_to_unix_time_seconds(bool async)
=> AssertTranslationFailed(() => base.DateTimeOffset_to_unix_time_seconds(async));

// Test runs successfully, but some time difference and precision issues and fail the assertion
public override Task Where_TimeSpan_Hours(bool async)
=> Task.CompletedTask;

public override Task Where_TimeOnly_Millisecond(bool async)
=> Task.CompletedTask; // Translation not implemented

// TODO: #3406
public override Task Where_datetimeoffset_microsecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_datetimeoffset_microsecond_component(async));

public override Task Where_datetimeoffset_nanosecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_datetimeoffset_nanosecond_component(async));

public override Task Where_timespan_microsecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_timespan_microsecond_component(async));

public override Task Where_timespan_nanosecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_timespan_nanosecond_component(async));

public override Task Where_timeonly_microsecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_timeonly_microsecond_component(async));

public override Task Where_timeonly_nanosecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_timeonly_nanosecond_component(async));

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Original file line number Diff line number Diff line change
@@ -15,10 +15,6 @@ public TPTGearsOfWarQueryNpgsqlTest(TPTGearsOfWarQueryNpgsqlFixture fixture, ITe
// TODO: #1232
// protected override bool CanExecuteQueryString => true;

[ConditionalTheory(Skip = "https://github.com/npgsql/efcore.pg/issues/2039")]
public override Task Where_DateOnly_Year(bool async)
=> base.Where_DateOnly_Year(async);

// Base implementation uses DateTimeOffset.Now, which we don't translate by design. Use DateTimeOffset.UtcNow instead.
public override async Task Select_datetimeoffset_comparison_in_projection(bool async)
{
@@ -76,68 +72,11 @@ WHERE date_trunc('day', m."Timeline" AT TIME ZONE 'UTC')::timestamp >= @dateTime
""");
}

public override async Task Where_datetimeoffset_date_component(bool async)
{
await AssertQuery(
async,
ss => from m in ss.Set<Mission>()
where m.Timeline.Date > new DateTime(1)
select m);

AssertSql(
"""
SELECT m."Id", m."CodeName", m."Date", m."Difficulty", m."Duration", m."Rating", m."Time", m."Timeline"
FROM "Missions" AS m
WHERE date_trunc('day', m."Timeline" AT TIME ZONE 'UTC') > TIMESTAMP '0001-01-01T00:00:00'
""");
}

// Not supported by design: we support getting a local DateTime via DateTime.Now (based on PG TimeZone), but there's no way to get a
// non-UTC DateTimeOffset.
public override Task Where_datetimeoffset_now(bool async)
=> Assert.ThrowsAsync<InvalidOperationException>(() => base.Where_datetimeoffset_now(async));

// Not supported by design: we support getting a local DateTime via DateTime.Now (based on PG TimeZone), but there's no way to get a
// non-UTC DateTimeOffset.
public override Task DateTimeOffsetNow_minus_timespan(bool async)
=> Assert.ThrowsAsync<InvalidOperationException>(() => base.DateTimeOffsetNow_minus_timespan(async));

// SQL translation not implemented, too annoying
public override Task Where_datetimeoffset_millisecond_component(bool async)
=> Assert.ThrowsAsync<InvalidOperationException>(() => base.Where_datetimeoffset_millisecond_component(async));

public override Task DateTimeOffset_to_unix_time_milliseconds(bool async)
=> AssertTranslationFailed(() => base.DateTimeOffset_to_unix_time_milliseconds(async));

public override Task DateTimeOffset_to_unix_time_seconds(bool async)
=> AssertTranslationFailed(() => base.DateTimeOffset_to_unix_time_seconds(async));

// Test runs successfully, but some time difference and precision issues and fail the assertion
public override Task Where_TimeSpan_Hours(bool async)
=> Task.CompletedTask;

public override Task Where_TimeOnly_Millisecond(bool async)
=> Task.CompletedTask; // Translation not implemented

// TODO: #3406
public override Task Where_datetimeoffset_microsecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_datetimeoffset_microsecond_component(async));

public override Task Where_datetimeoffset_nanosecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_datetimeoffset_nanosecond_component(async));

public override Task Where_timespan_microsecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_timespan_microsecond_component(async));

public override Task Where_timespan_nanosecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_timespan_nanosecond_component(async));

public override Task Where_timeonly_microsecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_timeonly_microsecond_component(async));

public override Task Where_timeonly_nanosecond_component(bool async)
=> AssertTranslationFailed(() => base.Where_timeonly_nanosecond_component(async));

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

#nullable enable

namespace Microsoft.EntityFrameworkCore.Query.Translations;

public class BasicTypesQueryNpgsqlFixture : BasicTypesQueryFixtureBase, ITestSqlLoggerFactory
{
private BasicTypesData? _expectedData;

protected override ITestStoreFactory TestStoreFactory
=> NpgsqlTestStoreFactory.Instance;

public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
{
new NpgsqlDbContextOptionsBuilder(base.AddOptions(builder)).SetPostgresVersion(TestEnvironment.PostgresVersion);
return builder;
}

protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
=> modelBuilder.HasPostgresExtension("uuid-ossp");

protected override Task SeedAsync(BasicTypesContext context)
{
_expectedData ??= LoadAndTweakData();
context.AddRange(_expectedData.BasicTypesEntities);
context.AddRange(_expectedData.NullableBasicTypesEntities);
return context.SaveChangesAsync();
}

public override ISetSource GetExpectedData()
=> _expectedData ??= LoadAndTweakData();

private BasicTypesData LoadAndTweakData()
{
var data = (BasicTypesData)base.GetExpectedData();

foreach (var item in data.BasicTypesEntities)
{
// For all relevant temporal types, chop sub-microsecond precision which PostgreSQL does not support.
// Temporal types which aren't set (default) get mapped to -infinity on PostgreSQL; this value causes many tests to fail.

if (item.DateTime == default)
{
item.DateTime += TimeSpan.FromSeconds(1);
}

// PostgreSQL maps DateTime to timestamptz by default, but that represents UTC timestamps which require DateTimeKind.Utc.
item.DateTime = DateTime.SpecifyKind(new DateTime(StripSubMicrosecond(item.DateTime.Ticks)), DateTimeKind.Utc);

if (item.DateOnly == default)
{
item.DateOnly = item.DateOnly.AddDays(1);
}

item.TimeOnly = new TimeOnly(StripSubMicrosecond(item.TimeOnly.Ticks));
item.TimeSpan = new TimeSpan(StripSubMicrosecond(item.TimeSpan.Ticks));

if (item.DateTimeOffset == default)
{
item.DateTimeOffset += TimeSpan.FromSeconds(1);
}

// PostgreSQL doesn't have a real DateTimeOffset type; we map .NET DateTimeOffset to timestamptz, which represents a UTC
// timestamp, and so we only support offset=0.
// Also chop sub-microsecond precision which PostgreSQL does not support.
item.DateTimeOffset = new DateTimeOffset(StripSubMicrosecond(item.DateTimeOffset.Ticks), TimeSpan.Zero);
}

// Do the same for the nullable counterparts
foreach (var item in data.NullableBasicTypesEntities)
{
if (item.DateTime.HasValue)
{
item.DateTime = DateTime.SpecifyKind(new DateTime(StripSubMicrosecond(item.DateTime.Value.Ticks)), DateTimeKind.Utc);
}

if (item.TimeOnly.HasValue)
{
item.TimeOnly = new TimeOnly(StripSubMicrosecond(item.TimeOnly.Value.Ticks));
}

if (item.TimeSpan.HasValue)
{
item.TimeSpan = new TimeSpan(StripSubMicrosecond(item.TimeSpan.Value.Ticks));
}

if (item.DateTimeOffset.HasValue)
{
item.DateTimeOffset = new DateTimeOffset(StripSubMicrosecond(item.DateTimeOffset.Value.Ticks), TimeSpan.Zero);
}
}

return data;

static long StripSubMicrosecond(long ticks) => ticks - (ticks % (TimeSpan.TicksPerMillisecond / 1000));
}

public TestSqlLoggerFactory TestSqlLoggerFactory
=> (TestSqlLoggerFactory)ListLoggerFactory;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
namespace Microsoft.EntityFrameworkCore.Query.Translations;

#nullable enable

public class EnumTranslationsNpgsqlTest : EnumTranslationsTestBase<BasicTypesQueryNpgsqlFixture>
{
public EnumTranslationsNpgsqlTest(BasicTypesQueryNpgsqlFixture fixture, ITestOutputHelper testOutputHelper)
: base(fixture)
{
Fixture.TestSqlLoggerFactory.Clear();
Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}

#region Equality

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."Enum" = 0
""");
}

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

AssertSql(
"""
@basicEnum='0'
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."Enum" = @basicEnum
""");
}

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

AssertSql(
"""
SELECT n."Id", n."Bool", n."Byte", n."ByteArray", n."DateOnly", n."DateTime", n."DateTimeOffset", n."Decimal", n."Double", n."Enum", n."FlagsEnum", n."Float", n."Guid", n."Int", n."Long", n."Short", n."String", n."TimeOnly", n."TimeSpan"
FROM "NullableBasicTypesEntities" AS n
WHERE n."Enum" = 0
""");
}

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

AssertSql(
"""
@basicEnum='0'
SELECT n."Id", n."Bool", n."Byte", n."ByteArray", n."DateOnly", n."DateTime", n."DateTimeOffset", n."Decimal", n."Double", n."Enum", n."FlagsEnum", n."Float", n."Guid", n."Int", n."Long", n."Short", n."String", n."TimeOnly", n."TimeSpan"
FROM "NullableBasicTypesEntities" AS n
WHERE n."Enum" = @basicEnum
""");
}

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

AssertSql(
"""
SELECT n."Id", n."Bool", n."Byte", n."ByteArray", n."DateOnly", n."DateTime", n."DateTimeOffset", n."Decimal", n."Double", n."Enum", n."FlagsEnum", n."Float", n."Guid", n."Int", n."Long", n."Short", n."String", n."TimeOnly", n."TimeSpan"
FROM "NullableBasicTypesEntities" AS n
WHERE n."Enum" IS NULL
""");
}

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

AssertSql(
"""
SELECT n."Id", n."Bool", n."Byte", n."ByteArray", n."DateOnly", n."DateTime", n."DateTimeOffset", n."Decimal", n."Double", n."Enum", n."FlagsEnum", n."Float", n."Guid", n."Int", n."Long", n."Short", n."String", n."TimeOnly", n."TimeSpan"
FROM "NullableBasicTypesEntities" AS n
WHERE n."Enum" IS NULL
""");
}

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

AssertSql(
"""
@basicEnum='0' (Nullable = true)
SELECT n."Id", n."Bool", n."Byte", n."ByteArray", n."DateOnly", n."DateTime", n."DateTimeOffset", n."Decimal", n."Double", n."Enum", n."FlagsEnum", n."Float", n."Guid", n."Int", n."Long", n."Short", n."String", n."TimeOnly", n."TimeSpan"
FROM "NullableBasicTypesEntities" AS n
WHERE n."Enum" = @basicEnum
""");
}

#endregion Equality

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & 1 > 0
""",
//
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & 1 = 1
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & 8 = 8
""",
//
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum"::bigint & 8 = 8
""",
//
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum"::smallint & 8 = 8
""");
}

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

AssertSql(
"""
SELECT n."Id", n."Bool", n."Byte", n."ByteArray", n."DateOnly", n."DateTime", n."DateTimeOffset", n."Decimal", n."Double", n."Enum", n."FlagsEnum", n."Float", n."Guid", n."Int", n."Long", n."Short", n."String", n."TimeOnly", n."TimeSpan"
FROM "NullableBasicTypesEntities" AS n
WHERE n."FlagsEnum" & 8 > 0
""");
}

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

AssertSql(
"""
SELECT n."Id", n."Bool", n."Byte", n."ByteArray", n."DateOnly", n."DateTime", n."DateTimeOffset", n."Decimal", n."Double", n."Enum", n."FlagsEnum", n."Float", n."Guid", n."Int", n."Long", n."Short", n."String", n."TimeOnly", n."TimeSpan"
FROM "NullableBasicTypesEntities" AS n
WHERE n."FlagsEnum" & NULL > 0
""");
}

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

AssertSql(
"""
@flagsEnum='8'
SELECT n."Id", n."Bool", n."Byte", n."ByteArray", n."DateOnly", n."DateTime", n."DateTimeOffset", n."Decimal", n."Double", n."Enum", n."FlagsEnum", n."Float", n."Guid", n."Int", n."Long", n."Short", n."String", n."TimeOnly", n."TimeSpan"
FROM "NullableBasicTypesEntities" AS n
WHERE n."FlagsEnum" & @flagsEnum > 0
""");
}

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

AssertSql(
"""
@flagsEnum='8' (Nullable = true)
SELECT n."Id", n."Bool", n."Byte", n."ByteArray", n."DateOnly", n."DateTime", n."DateTimeOffset", n."Decimal", n."Double", n."Enum", n."FlagsEnum", n."Float", n."Guid", n."Int", n."Long", n."Short", n."String", n."TimeOnly", n."TimeSpan"
FROM "NullableBasicTypesEntities" AS n
WHERE n."FlagsEnum" & @flagsEnum > 0
""",
//
"""
SELECT n."Id", n."Bool", n."Byte", n."ByteArray", n."DateOnly", n."DateTime", n."DateTimeOffset", n."Decimal", n."Double", n."Enum", n."FlagsEnum", n."Float", n."Guid", n."Int", n."Long", n."Short", n."String", n."TimeOnly", n."TimeSpan"
FROM "NullableBasicTypesEntities" AS n
WHERE n."FlagsEnum" & NULL > 0
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" | 8 > 0
""");
}

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

AssertSql(
"""
SELECT b."FlagsEnum" & 8 = 8 AS "BitwiseTrue", b."FlagsEnum" & 8 = 4 AS "BitwiseFalse", b."FlagsEnum" & 8 AS "BitwiseValue"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & 8 = 8
LIMIT 1
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & 8 = 8
""",
//
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & 12 = 12
""",
//
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & 8 = 8
""",
//
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & 8 = 8
""",
//
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE 8 & b."FlagsEnum" = b."FlagsEnum"
""",
//
"""
SELECT b."FlagsEnum" & 8 = 8 AS "hasFlagTrue", b."FlagsEnum" & 4 = 4 AS "hasFlagFalse"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & 8 = 8
LIMIT 1
""");
}

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

AssertSql(
"""
@flagsEnum='8'
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & @flagsEnum = @flagsEnum
""");
}

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

AssertSql(
"""
@flagsEnum='8' (Nullable = true)
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."FlagsEnum" & @flagsEnum = @flagsEnum
""");
}

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

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

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
namespace Microsoft.EntityFrameworkCore.Query.Translations;

public class OperatorTranslationsNpgsqlTest : OperatorTranslationsTestBase<BasicTypesQueryNpgsqlFixture>
{
public OperatorTranslationsNpgsqlTest(BasicTypesQueryNpgsqlFixture fixture, ITestOutputHelper testOutputHelper)
: base(fixture)
{
Fixture.TestSqlLoggerFactory.Clear();
Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}

#region Bitwise

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."Int"::bigint | b."Long" = 7
""",
//
"""
SELECT b."Int"::bigint | b."Long"
FROM "BasicTypesEntities" AS b
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."Int" = 12 OR b."String" = 'Seattle'
""",
//
"""
SELECT b."Int" = 12 OR b."String" = 'Seattle'
FROM "BasicTypesEntities" AS b
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE CAST(b."Int" | b."Short" AS bigint) | b."Long" = 7
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."Int" & b."Short" = 2
""",
//
"""
SELECT b."Int" & b."Short"
FROM "BasicTypesEntities" AS b
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."Int" = 8 AND b."String" = 'Seattle'
""",
//
"""
SELECT b."Int" = 8 AND b."String" = 'Seattle'
FROM "BasicTypesEntities" AS b
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE (b."Int" # b."Short") = 1
""",
//
"""
SELECT b."Int" # b."Short"
FROM "BasicTypesEntities" AS b
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE (b."Int" = b."Short") <> (b."String" = 'Seattle')
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE ~b."Int" = -9
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE (b."Int" = 12 AND b."Short" = 12) OR b."String" = 'Seattle'
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."Int" = 12 OR b."Short" = 12 OR b."String" = 'Seattle'
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE b."Int" = 8 AND b."Short" = 8 AND b."String" = 'Seattle'
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE (b."Int" = 8 OR b."Short" = 9) AND b."String" = 'Seattle'
""");
}

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

AssertSql(
"""
SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan"
FROM "BasicTypesEntities" AS b
WHERE (b."Int" = 12 AND b."Short" = 12) OR b."String" = 'Seattle'
""");
}

#endregion Bitwise

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

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

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

0 comments on commit 174a0e3

Please sign in to comment.