Skip to content

Commit

Permalink
Sync to 6.0.0-preview6 (#1936)
Browse files Browse the repository at this point in the history
Includes support for MathF translations.

Closes #1833
  • Loading branch information
roji authored Jul 31, 2021
1 parent b38de76 commit 36994f9
Show file tree
Hide file tree
Showing 25 changed files with 93 additions and 133 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
pull_request:

env:
dotnet_sdk_version: '6.0.100-preview.4.21255.9'
dotnet_sdk_version: '6.0.100-preview.6.21355.2'
postgis_version: 3
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true

Expand Down
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>9.0</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AnalysisLevel>latest</AnalysisLevel>
Expand Down
6 changes: 3 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<EFCoreVersion>6.0.0-preview.5.21301.9</EFCoreVersion>
<MicrosoftExtensionsVersion>6.0.0-preview.5.21301.5</MicrosoftExtensionsVersion>
<NpgsqlVersion>6.0.0-preview5</NpgsqlVersion>
<EFCoreVersion>6.0.0-preview.6.21352.1</EFCoreVersion>
<MicrosoftExtensionsVersion>6.0.0-preview.6.21352.12</MicrosoftExtensionsVersion>
<NpgsqlVersion>6.0.0-preview6</NpgsqlVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.100-preview.5.21302.13",
"version": "6.0.100-preview.6.21355.2",
"rollForward": "latestMajor",
"allowPrerelease": "false"
}
Expand Down
3 changes: 0 additions & 3 deletions src/EFCore.PG.NTS/EFCore.PG.NTS.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework Condition="'$(DeveloperBuild)' == 'True'">net6.0</TargetFramework>

<AssemblyName>Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite</AssemblyName>
<RootNamespace>Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite</RootNamespace>

Expand Down
3 changes: 0 additions & 3 deletions src/EFCore.PG.NodaTime/EFCore.PG.NodaTime.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework Condition="'$(DeveloperBuild)' == 'True'">net6.0</TargetFramework>

<AssemblyName>Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime</AssemblyName>
<RootNamespace>Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime</RootNamespace>

Expand Down
3 changes: 0 additions & 3 deletions src/EFCore.PG/EFCore.PG.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
<TargetFrameworks Condition="'$(DeveloperBuild)' == 'True'">net6.0</TargetFrameworks>

<AssemblyName>Npgsql.EntityFrameworkCore.PostgreSQL</AssemblyName>
<RootNamespace>Npgsql.EntityFrameworkCore.PostgreSQL</RootNamespace>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ public NpgsqlDateTimeMemberTranslator(NpgsqlSqlExpressionFactory sqlExpressionFa
{
var type = member.DeclaringType;
if (type != typeof(DateTime) && type != typeof(NpgsqlDateTime) && type != typeof(NpgsqlDate)
#if NET6_0_OR_GREATER
&& type != typeof(DateOnly) && type != typeof(TimeOnly)
#endif
)
return null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,18 @@ public class NpgsqlDateTimeMethodTranslator : IMethodCallTranslator
{ typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddSeconds), new[] { typeof(double) })!, "secs" },
//{ typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddMilliseconds), new[] { typeof(double) })!, "milliseconds" }

#if NET6_0_OR_GREATER
{ typeof(DateOnly).GetRuntimeMethod(nameof(DateOnly.AddYears), new[] { typeof(int) })!, "years" },
{ typeof(DateOnly).GetRuntimeMethod(nameof(DateOnly.AddMonths), new[] { typeof(int) })!, "months" },
{ typeof(DateOnly).GetRuntimeMethod(nameof(DateOnly.AddDays), new[] { typeof(int) })!, "days" },

{ typeof(TimeOnly).GetRuntimeMethod(nameof(TimeOnly.AddHours), new[] { typeof(int) })!, "hours" },
{ typeof(TimeOnly).GetRuntimeMethod(nameof(TimeOnly.AddMinutes), new[] { typeof(int) })!, "mins" },
#endif
};

#if NET6_0_OR_GREATER
private static readonly MethodInfo TimeOnlyIsBetweenMethod
= typeof(TimeOnly).GetRuntimeMethod(nameof(TimeOnly.IsBetween), new[] { typeof(TimeOnly), typeof(TimeOnly) })!;
private static readonly MethodInfo TimeOnlyAddTimeSpanMethod
= typeof(TimeOnly).GetRuntimeMethod(nameof(TimeOnly.Add), new[] { typeof(TimeSpan) })!;
#endif

private readonly ISqlExpressionFactory _sqlExpressionFactory;
private readonly RelationalTypeMapping _intervalMapping;
Expand Down Expand Up @@ -75,7 +71,6 @@ public NpgsqlDateTimeMethodTranslator(
return translated;
}

#if NET6_0_OR_GREATER
if (method.DeclaringType == typeof(TimeOnly))
{
if (method == TimeOnlyIsBetweenMethod)
Expand All @@ -90,7 +85,6 @@ public NpgsqlDateTimeMethodTranslator(
return _sqlExpressionFactory.Add(instance, arguments[0]);
}
}
#endif

return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,60 @@ public class NpgsqlMathTranslator : IMethodCallTranslator
{ typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(int) })!, "abs" },
{ typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(long) })!, "abs" },
{ typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(short) })!, "abs" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Abs), new[] { typeof(float) })!, "abs" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Ceiling), new[] { typeof(decimal) })!, "ceiling" },
{ typeof(Math).GetRuntimeMethod(nameof(Math.Ceiling), new[] { typeof(double) })!, "ceiling" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Ceiling), new[] { typeof(float) })!, "ceiling" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Floor), new[] { typeof(decimal) })!, "floor" },
{ typeof(Math).GetRuntimeMethod(nameof(Math.Floor), new[] { typeof(double) })!, "floor" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Floor), new[] { typeof(float) })!, "floor" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Pow), new[] { typeof(double), typeof(double) })!, "power" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Pow), new[] { typeof(float), typeof(float) })!, "power" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Exp), new[] { typeof(double) })!, "exp" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Exp), new[] { typeof(float) })!, "exp" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Log10), new[] { typeof(double) })!, "log" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Log10), new[] { typeof(float) })!, "log" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Log), new[] { typeof(double) })!, "ln" },
// Note: PostgreSQL has log(x,y) but only for decimal, whereas .NET has it only for double
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Log), new[] { typeof(float) })!, "ln" },
// Note: PostgreSQL has log(x,y) but only for decimal, whereas .NET has it only for double/float

{ typeof(Math).GetRuntimeMethod(nameof(Math.Sqrt), new[] { typeof(double) })!, "sqrt" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Sqrt), new[] { typeof(float) })!, "sqrt" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Acos), new[] { typeof(double) })!, "acos" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Acos), new[] { typeof(float) })!, "acos" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Asin), new[] { typeof(double) })!, "asin" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Asin), new[] { typeof(float) })!, "asin" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Atan), new[] { typeof(double) })!, "atan" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Atan), new[] { typeof(float) })!, "atan" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Atan2), new[] { typeof(double), typeof(double) })!, "atan2" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Atan2), new[] { typeof(float), typeof(float) })!, "atan2" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Cos), new[] { typeof(double) })!, "cos" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Cos), new[] { typeof(float) })!, "cos" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Sin), new[] { typeof(double) })!, "sin" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Sin), new[] { typeof(float) })!, "sin" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Tan), new[] { typeof(double) })!, "tan" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Tan), new[] { typeof(float) })!, "tan" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Round), new[] { typeof(double) })!, "round" },
{ typeof(Math).GetRuntimeMethod(nameof(Math.Round), new[] { typeof(decimal) })!, "round" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Round), new[] { typeof(float) })!, "round" },

{ typeof(Math).GetRuntimeMethod(nameof(Math.Truncate), new[] { typeof(double) })!, "trunc" },
{ typeof(Math).GetRuntimeMethod(nameof(Math.Truncate), new[] { typeof(decimal) })!, "trunc" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Truncate), new[] { typeof(float) })!, "trunc" },

// https://www.postgresql.org/docs/current/functions-conditional.html#FUNCTIONS-GREATEST-LEAST
{ typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(decimal), typeof(decimal) })!, "greatest" },
Expand All @@ -59,6 +91,7 @@ public class NpgsqlMathTranslator : IMethodCallTranslator
{ typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(int), typeof(int) })!, "greatest" },
{ typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(long), typeof(long) })!, "greatest" },
{ typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(short), typeof(short) })!, "greatest" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Max), new[] { typeof(float), typeof(float) })!, "greatest" },

// https://www.postgresql.org/docs/current/functions-conditional.html#FUNCTIONS-GREATEST-LEAST
{ typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(decimal), typeof(decimal) })!, "least" },
Expand All @@ -67,6 +100,7 @@ public class NpgsqlMathTranslator : IMethodCallTranslator
{ typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(int), typeof(int) })!, "least" },
{ typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(long), typeof(long) })!, "least" },
{ typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(short), typeof(short) })!, "least" },
{ typeof(MathF).GetRuntimeMethod(nameof(MathF.Min), new[] { typeof(float), typeof(float) })!, "least" },
};

private static readonly IEnumerable<MethodInfo> SignMethodInfos = new[]
Expand All @@ -77,7 +111,8 @@ public class NpgsqlMathTranslator : IMethodCallTranslator
typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(int) })!,
typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(long) })!,
typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(sbyte) })!,
typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(short) })!
typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(short) })!,
typeof(MathF).GetRuntimeMethod(nameof(MathF.Sign), new[] { typeof(float) })!,
};

private static readonly MethodInfo RoundDecimalTwoParams
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ public class NpgsqlSqlTranslatingExpressionVisitor : RelationalSqlTranslatingExp
private static readonly ConstructorInfo DateTimeCtor2 =
typeof(DateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) })!;

#if NET6_0_OR_GREATER
private static readonly ConstructorInfo DateOnlyCtor =
typeof(DateOnly).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) })!;
#endif

private static readonly MethodInfo Like2MethodInfo =
typeof(DbFunctionsExtensions).GetRuntimeMethod(
Expand Down Expand Up @@ -437,15 +435,13 @@ protected override Expression VisitNew(NewExpression newExpression)
"make_timestamp", sqlArguments, nullable: true, TrueArrays[6], typeof(DateTime));
}

#if NET6_0_OR_GREATER
if (newExpression.Constructor == DateOnlyCtor)
{
return TryTranslateArguments(out var sqlArguments)
? _sqlExpressionFactory.Function(
"make_date", sqlArguments, nullable: true, TrueArrays[3], typeof(DateOnly))
: QueryCompilationContext.NotTranslatedExpression;
}
#endif

return QueryCompilationContext.NotTranslatedExpression;

Expand Down
7 changes: 2 additions & 5 deletions src/EFCore.PG/Query/NpgsqlSqlExpressionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ public virtual PostgresNewArrayExpression NewArray(
if (operatorType == ExpressionType.Subtract)
{
if (left.Type == typeof(DateTime) && right.Type == typeof(DateTime) ||
left.Type == typeof(DateTimeOffset) && right.Type == typeof(DateTimeOffset))
left.Type == typeof(DateTimeOffset) && right.Type == typeof(DateTimeOffset) ||
left.Type == typeof(TimeOnly) && right.Type == typeof(TimeOnly))
{
return (SqlBinaryExpression)ApplyTypeMapping(
new SqlBinaryExpression(operatorType, left, right, typeof(TimeSpan), null), typeMapping);
Expand Down Expand Up @@ -299,9 +300,7 @@ private SqlExpression ApplyTypeMappingOnSqlBinary(SqlBinaryExpression binary, Re
&& (
leftType == typeof(DateTime)
|| leftType == typeof(DateTimeOffset)
#if NET6_0_OR_GREATER
|| leftType == typeof(TimeOnly)
#endif
)
|| rightType.FullName == "NodaTime.Period"
&& (
Expand All @@ -328,10 +327,8 @@ private SqlExpression ApplyTypeMappingOnSqlBinary(SqlBinaryExpression binary, Re
// LocalDateTime - LocalDateTime => Period
if (leftType == typeof(DateTime) && rightType == typeof(DateTime)
|| leftType == typeof(DateTimeOffset) && rightType == typeof(DateTimeOffset)
#if NET6_0_OR_GREATER
|| leftType == typeof(DateOnly) && rightType == typeof(DateOnly)
|| leftType == typeof(TimeOnly) && rightType == typeof(TimeOnly)
#endif
|| leftType.FullName == "NodaTime.Instant" && rightType.FullName == "NodaTime.Instant"
|| leftType.FullName == "NodaTime.LocalDateTime" && rightType.FullName == "NodaTime.LocalDateTime"
|| leftType.FullName == "NodaTime.ZonedDateTime" && rightType.FullName == "NodaTime.ZonedDateTime"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ protected override string GenerateNonNullSqlLiteral(object value)
=> value switch
{
DateTime d => FormattableString.Invariant($"DATE '{d:yyyy-MM-dd}'"),
#if NET6_0_OR_GREATER
DateOnly d => FormattableString.Invariant($"DATE '{d:yyyy-MM-dd}'"),
#endif
_ => throw new InvalidCastException($"Can't generate a date SQL literal for CLR type {value.GetType()}")
};
}
Expand All @@ -94,11 +92,9 @@ protected override string GenerateNonNullSqlLiteral(object value)
TimeSpan ts => ts.Ticks % 10000000 == 0
? FormattableString.Invariant($@"TIME '{value:hh\:mm\:ss}'")
: FormattableString.Invariant($@"TIME '{value:hh\:mm\:ss\.FFFFFF}'"),
#if NET6_0_OR_GREATER
TimeOnly t => t.Ticks % 10000000 == 0
? FormattableString.Invariant($@"TIME '{value:HH\:mm\:ss}'")
: FormattableString.Invariant($@"TIME '{value:HH\:mm\:ss\.FFFFFF}'"),
#endif
_ => throw new InvalidCastException($"Can't generate a time SQL literal for CLR type {value.GetType()}")
};
}
Expand Down
37 changes: 5 additions & 32 deletions src/EFCore.PG/Storage/Internal/NpgsqlTypeMappingSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,8 @@ public class NpgsqlTypeMappingSource : RelationalTypeMappingSource
private readonly NpgsqlTimeTypeMapping _timeTimeSpan = new(typeof(TimeSpan));
private readonly NpgsqlTimeTzTypeMapping _timetz = new();

#if NET6_0_OR_GREATER
private readonly NpgsqlDateTypeMapping _dateDateOnly = new(typeof(DateOnly));
private readonly NpgsqlTimeTypeMapping _timeTimeOnly = new(typeof(TimeOnly));
#endif

// Network address types
private readonly NpgsqlMacaddrTypeMapping _macaddr = new();
Expand Down Expand Up @@ -192,31 +190,9 @@ public NpgsqlTypeMappingSource(TypeMappingSourceDependencies dependencies,
{ "timestamp with time zone", new[] { _timestamptz, _timestamptzDto } },
{ "timestamptz", new[] { _timestamptz, _timestamptzDto } },
{ "interval", new[] { _interval } },

{ "date", new RelationalTypeMapping[]
#if NET6_0_OR_GREATER
{ _dateDateOnly, _dateDateTime }
#else
{ _dateDateTime }
#endif
},

{ "time without time zone", new RelationalTypeMapping[]
#if NET6_0_OR_GREATER
{ _timeTimeOnly, _timeTimeSpan }
#else
{ _timeTimeSpan }
#endif
},

{ "time", new RelationalTypeMapping[]
#if NET6_0_OR_GREATER
{ _timeTimeOnly, _timeTimeSpan }
#else
{ _timeTimeSpan }
#endif
},

{ "date", new RelationalTypeMapping[] { _dateDateOnly, _dateDateTime } },
{ "time without time zone", new RelationalTypeMapping[] { _timeTimeOnly, _timeTimeSpan } },
{ "time", new RelationalTypeMapping[] { _timeTimeOnly, _timeTimeSpan } },
{ "time with time zone", new[] { _timetz } },
{ "timetz", new[] { _timetz } },
{ "macaddr", new[] { _macaddr } },
Expand Down Expand Up @@ -277,6 +253,8 @@ public NpgsqlTypeMappingSource(TypeMappingSourceDependencies dependencies,
{ typeof(JsonElement), _jsonbElement },
{ typeof(char), _singleChar },
{ typeof(DateTime), _timestamp },
{ typeof(DateOnly), _dateDateOnly },
{ typeof(TimeOnly), _timeTimeOnly },
{ typeof(TimeSpan), _interval },
{ typeof(DateTimeOffset), _timestamptzDto },
{ typeof(PhysicalAddress), _macaddr },
Expand All @@ -287,11 +265,6 @@ public NpgsqlTypeMappingSource(TypeMappingSourceDependencies dependencies,
{ typeof(Dictionary<string, string>), _hstore },
{ typeof(NpgsqlTid), _tid },

#if NET6_0_OR_GREATER
{ typeof(DateOnly), _dateDateOnly },
{ typeof(TimeOnly), _timeTimeOnly },
#endif

{ typeof(NpgsqlPoint), _point },
{ typeof(NpgsqlBox), _box },
{ typeof(NpgsqlLine), _line },
Expand Down
4 changes: 0 additions & 4 deletions test/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

<Import Project="..\Directory.Build.props" />

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<PropertyGroup>
<!-- There's lots of use of internal EF Core APIs from the tests, suppress the analyzer warnings for those -->
<NoWarn>$(NoWarn);xUnit1003;xUnit1004;xUnit1013;EF1001</NoWarn>
Expand Down
Loading

0 comments on commit 36994f9

Please sign in to comment.