未验证 提交 227a4bcc 编写于 作者: S Shay Rojansky 提交者: GitHub

Switch to using the new EF Core AtTimeZoneExpression (#2409)

Instead of our PG-specific one.
上级 6a1d7a81
......@@ -99,8 +99,6 @@ protected override void Print(ExpressionPrinter expressionPrinter)
PostgresExpressionType.ContainedBy => "<@",
PostgresExpressionType.Overlaps => "&&",
PostgresExpressionType.AtTimeZone => "AT TIME ZONE",
PostgresExpressionType.NetworkContainedByOrEqual => "<<=",
PostgresExpressionType.NetworkContainsOrEqual => ">>=",
PostgresExpressionType.NetworkContainsOrContainedBy => "&&",
......
......@@ -9,8 +9,6 @@ public enum PostgresExpressionType
ContainedBy, // << (inet/cidr), <@
Overlaps, // &&
AtTimeZone, // AT TIME ZONE
NetworkContainedByOrEqual, // <<=
NetworkContainsOrEqual, // >>=
NetworkContainsOrContainedBy, // &&
......
......@@ -270,8 +270,6 @@ protected virtual Expression VisitPostgresBinary(PostgresBinaryExpression binary
PostgresExpressionType.ContainedBy => "<@",
PostgresExpressionType.Overlaps => "&&",
PostgresExpressionType.AtTimeZone => "AT TIME ZONE",
PostgresExpressionType.NetworkContainedByOrEqual => "<<=",
PostgresExpressionType.NetworkContainsOrEqual => ">>=",
PostgresExpressionType.NetworkContainsOrContainedBy => "&&",
......
......@@ -61,44 +61,38 @@ public NpgsqlSqlExpressionFactory(SqlExpressionFactoryDependencies dependencies)
typeMapping);
}
public virtual PostgresBinaryExpression AtUtc(
public virtual AtTimeZoneExpression AtUtc(
SqlExpression timestamp,
RelationalTypeMapping? typeMapping = null)
=> AtTimeZone(timestamp, Constant("UTC"), timestamp.Type);
public virtual PostgresBinaryExpression AtTimeZone(
public virtual AtTimeZoneExpression AtTimeZone(
SqlExpression timestamp,
SqlExpression timeZone,
Type type,
RelationalTypeMapping? typeMapping = null)
{
// PostgreSQL AT TIME ZONE flips the given type from timestamptz to timestamp and vice versa
// See https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT
typeMapping ??= FlipTimestampTypeMapping(
timestamp.TypeMapping ?? _typeMappingSource.FindMapping(timestamp.Type, Dependencies.Model)!);
if (typeMapping is null)
{
// PostgreSQL AT TIME ZONE flips the given type from timestamptz to timestamp and vice versa
// See https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT
typeMapping = timestamp.TypeMapping ?? _typeMappingSource.FindMapping(timestamp.Type, Dependencies.Model)!;
var storeType = typeMapping.StoreType;
typeMapping = storeType.StartsWith("timestamp with time zone", StringComparison.Ordinal)
|| storeType.StartsWith("timestamptz", StringComparison.Ordinal)
? _typeMappingSource.FindMapping("timestamp without time zone")!
: storeType.StartsWith("timestamp without time zone", StringComparison.Ordinal)
|| storeType.StartsWith("timestamp", StringComparison.Ordinal)
? _typeMappingSource.FindMapping("timestamp with time zone")!
: throw new ArgumentException($"timestamp argument to AtTimeZone had unknown store type {storeType}", nameof(timestamp));
}
return new PostgresBinaryExpression(
PostgresExpressionType.AtTimeZone,
return new AtTimeZoneExpression(
ApplyDefaultTypeMapping(timestamp),
ApplyDefaultTypeMapping(timeZone),
type,
typeMapping);
RelationalTypeMapping FlipTimestampTypeMapping(RelationalTypeMapping mapping)
{
var storeType = mapping.StoreType;
if (storeType.StartsWith("timestamp with time zone", StringComparison.Ordinal) || storeType.StartsWith("timestamptz", StringComparison.Ordinal))
{
return _typeMappingSource.FindMapping("timestamp without time zone")!;
}
if (storeType.StartsWith("timestamp without time zone", StringComparison.Ordinal) || storeType.StartsWith("timestamp", StringComparison.Ordinal))
{
return _typeMappingSource.FindMapping("timestamp with time zone")!;
}
throw new ArgumentException($"timestamp argument to AtTimeZone had unknown store type {storeType}", nameof(timestamp));
}
}
public virtual PostgresILikeExpression ILike(
......
......@@ -64,7 +64,7 @@ public virtual async Task Where_datetime_utcnow()
SELECT e.""Id"", e.""TimestampDateTime"", e.""TimestampDateTimeOffset"", e.""TimestamptzDateTime""
FROM ""Entities"" AS e
WHERE now() AT TIME ZONE 'UTC' <> @__myDatetime_0");
WHERE (now() AT TIME ZONE 'UTC') <> @__myDatetime_0");
}
#region Support
......
......@@ -387,7 +387,7 @@ public async Task DateTimeOffset_DateTime(bool async)
AssertSql(
@"SELECT e.""Id"", e.""TimestampDateTime"", e.""TimestampDateTimeArray"", e.""TimestampDateTimeOffset"", e.""TimestampDateTimeOffsetArray"", e.""TimestampDateTimeRange"", e.""TimestamptzDateTime"", e.""TimestamptzDateTimeArray"", e.""TimestamptzDateTimeRange""
FROM ""Entities"" AS e
WHERE e.""TimestampDateTimeOffset"" AT TIME ZONE 'UTC' = TIMESTAMP '1998-04-12 13:26:38'");
WHERE (e.""TimestampDateTimeOffset"" AT TIME ZONE 'UTC') = TIMESTAMP '1998-04-12 13:26:38'");
}
[ConditionalTheory]
......@@ -534,7 +534,7 @@ public async Task DateTime_SpecifyKind_on_timestamp_to_utc(bool async)
AssertSql(
@"SELECT e.""Id"", e.""TimestampDateTime"", e.""TimestampDateTimeArray"", e.""TimestampDateTimeOffset"", e.""TimestampDateTimeOffsetArray"", e.""TimestampDateTimeRange"", e.""TimestamptzDateTime"", e.""TimestamptzDateTimeArray"", e.""TimestamptzDateTimeRange""
FROM ""Entities"" AS e
WHERE e.""TimestampDateTime"" AT TIME ZONE 'UTC' = TIMESTAMPTZ '1998-04-12 15:26:38Z'");
WHERE (e.""TimestampDateTime"" AT TIME ZONE 'UTC') = TIMESTAMPTZ '1998-04-12 15:26:38Z'");
}
[ConditionalTheory]
......@@ -549,7 +549,7 @@ public async Task DateTime_SpecifyKind_on_timestamptz_to_unspecified(bool async)
AssertSql(
@"SELECT e.""Id"", e.""TimestampDateTime"", e.""TimestampDateTimeArray"", e.""TimestampDateTimeOffset"", e.""TimestampDateTimeOffsetArray"", e.""TimestampDateTimeRange"", e.""TimestamptzDateTime"", e.""TimestamptzDateTimeArray"", e.""TimestamptzDateTimeRange""
FROM ""Entities"" AS e
WHERE e.""TimestamptzDateTime"" AT TIME ZONE 'UTC' = TIMESTAMP '1998-04-12 13:26:38'");
WHERE (e.""TimestamptzDateTime"" AT TIME ZONE 'UTC') = TIMESTAMP '1998-04-12 13:26:38'");
}
[ConditionalTheory]
......@@ -564,7 +564,7 @@ public async Task DateTime_SpecifyKind_on_timestamptz_to_local(bool async)
AssertSql(
@"SELECT e.""Id"", e.""TimestampDateTime"", e.""TimestampDateTimeArray"", e.""TimestampDateTimeOffset"", e.""TimestampDateTimeOffsetArray"", e.""TimestampDateTimeRange"", e.""TimestamptzDateTime"", e.""TimestamptzDateTimeArray"", e.""TimestamptzDateTimeRange""
FROM ""Entities"" AS e
WHERE e.""TimestamptzDateTime"" AT TIME ZONE 'UTC' = TIMESTAMP '1998-04-12 13:26:38'");
WHERE (e.""TimestamptzDateTime"" AT TIME ZONE 'UTC') = TIMESTAMP '1998-04-12 13:26:38'");
}
[ConditionalFact]
......@@ -598,7 +598,7 @@ public virtual async Task Where_ConvertTimeBySystemTimeZoneId_on_DateTime_timest
AssertSql(
@"SELECT e.""Id"", e.""TimestampDateTime"", e.""TimestampDateTimeArray"", e.""TimestampDateTimeOffset"", e.""TimestampDateTimeOffsetArray"", e.""TimestampDateTimeRange"", e.""TimestamptzDateTime"", e.""TimestamptzDateTimeArray"", e.""TimestamptzDateTimeRange""
FROM ""Entities"" AS e
WHERE e.""TimestamptzDateTime"" AT TIME ZONE 'Europe/Berlin' = TIMESTAMP '1998-04-12 15:26:38'");
WHERE (e.""TimestamptzDateTime"" AT TIME ZONE 'Europe/Berlin') = TIMESTAMP '1998-04-12 15:26:38'");
}
[ConditionalFact]
......@@ -660,7 +660,7 @@ public virtual async Task DateOnly_FromDateTime_with_timestamptz(bool async)
AssertSql(
@"SELECT e.""Id"", e.""TimestampDateTime"", e.""TimestampDateTimeArray"", e.""TimestampDateTimeOffset"", e.""TimestampDateTimeOffsetArray"", e.""TimestampDateTimeRange"", e.""TimestamptzDateTime"", e.""TimestamptzDateTimeArray"", e.""TimestamptzDateTimeRange""
FROM ""Entities"" AS e
WHERE CAST(e.""TimestamptzDateTime"" AT TIME ZONE 'UTC' AS date) = DATE '1998-04-12'");
WHERE CAST((e.""TimestamptzDateTime"" AT TIME ZONE 'UTC') AS date) = DATE '1998-04-12'");
}
[ConditionalTheory]
......@@ -692,7 +692,7 @@ public virtual async Task DateOnly_ToDateTime_with_timestamptz(bool async)
AssertSql(
@"SELECT e.""Id"", e.""TimestampDateTime"", e.""TimestampDateTimeArray"", e.""TimestampDateTimeOffset"", e.""TimestampDateTimeOffsetArray"", e.""TimestampDateTimeRange"", e.""TimestamptzDateTime"", e.""TimestamptzDateTimeArray"", e.""TimestamptzDateTimeRange""
FROM ""Entities"" AS e
WHERE (CAST(e.""TimestamptzDateTime"" AT TIME ZONE 'UTC' AS date) + TIME '15:26:38') = TIMESTAMP '1998-04-12 15:26:38'");
WHERE (CAST((e.""TimestamptzDateTime"" AT TIME ZONE 'UTC') AS date) + TIME '15:26:38') = TIMESTAMP '1998-04-12 15:26:38'");
}
#endregion DateOnly
......@@ -728,7 +728,7 @@ public virtual async Task TimeOnly_FromDateTime_with_timestamptz(bool async)
AssertSql(
@"SELECT e.""Id"", e.""TimestampDateTime"", e.""TimestampDateTimeArray"", e.""TimestampDateTimeOffset"", e.""TimestampDateTimeOffsetArray"", e.""TimestampDateTimeRange"", e.""TimestamptzDateTime"", e.""TimestamptzDateTimeArray"", e.""TimestamptzDateTimeRange""
FROM ""Entities"" AS e
WHERE CAST(e.""TimestamptzDateTime"" AT TIME ZONE 'UTC' AS time without time zone) = TIME '13:26:38'");
WHERE CAST((e.""TimestamptzDateTime"" AT TIME ZONE 'UTC') AS time without time zone) = TIME '13:26:38'");
}
[ConditionalTheory]
......@@ -744,7 +744,7 @@ public virtual async Task TimeOnly_ToTimeSpan(bool async)
AssertSql(
@"SELECT e.""Id"", e.""TimestampDateTime"", e.""TimestampDateTimeArray"", e.""TimestampDateTimeOffset"", e.""TimestampDateTimeOffsetArray"", e.""TimestampDateTimeRange"", e.""TimestamptzDateTime"", e.""TimestamptzDateTimeArray"", e.""TimestamptzDateTimeRange""
FROM ""Entities"" AS e
WHERE CAST(e.""TimestamptzDateTime"" AT TIME ZONE 'UTC' AS time without time zone) = TIME '13:26:38'");
WHERE CAST((e.""TimestamptzDateTime"" AT TIME ZONE 'UTC') AS time without time zone) = TIME '13:26:38'");
}
#endregion TimeOnly
......
......@@ -311,7 +311,7 @@ public async Task LocalDateTime_InZoneLeniently_ToInstant(bool async)
SELECT n.""Id"", n.""DateInterval"", n.""Duration"", n.""Instant"", n.""InstantRange"", n.""Interval"", n.""LocalDate"", n.""LocalDate2"", n.""LocalDateRange"", n.""LocalDateTime"", n.""LocalTime"", n.""Long"", n.""OffsetTime"", n.""Period"", n.""TimeZoneId"", n.""ZonedDateTime""
FROM ""NodaTimeTypes"" AS n
WHERE n.""LocalDateTime"" AT TIME ZONE 'Europe/Berlin' = @__ToInstant_0");
WHERE (n.""LocalDateTime"" AT TIME ZONE 'Europe/Berlin') = @__ToInstant_0");
}
[ConditionalTheory]
......@@ -330,7 +330,7 @@ public async Task LocalDateTime_InZoneLeniently_ToInstant_with_column_time_zone(
SELECT n.""Id"", n.""DateInterval"", n.""Duration"", n.""Instant"", n.""InstantRange"", n.""Interval"", n.""LocalDate"", n.""LocalDate2"", n.""LocalDateRange"", n.""LocalDateTime"", n.""LocalTime"", n.""Long"", n.""OffsetTime"", n.""Period"", n.""TimeZoneId"", n.""ZonedDateTime""
FROM ""NodaTimeTypes"" AS n
WHERE n.""LocalDateTime"" AT TIME ZONE n.""TimeZoneId"" = @__ToInstant_0");
WHERE (n.""LocalDateTime"" AT TIME ZONE n.""TimeZoneId"") = @__ToInstant_0");
}
#endregion LocalDateTime
......@@ -1176,7 +1176,7 @@ public async Task Instance_InZone_LocalDateTime(bool async)
AssertSql(
@"SELECT n.""Id"", n.""DateInterval"", n.""Duration"", n.""Instant"", n.""InstantRange"", n.""Interval"", n.""LocalDate"", n.""LocalDate2"", n.""LocalDateRange"", n.""LocalDateTime"", n.""LocalTime"", n.""Long"", n.""OffsetTime"", n.""Period"", n.""TimeZoneId"", n.""ZonedDateTime""
FROM ""NodaTimeTypes"" AS n
WHERE n.""Instant"" AT TIME ZONE 'Europe/Berlin' = TIMESTAMP '2018-04-20T12:31:33.666'");
WHERE (n.""Instant"" AT TIME ZONE 'Europe/Berlin') = TIMESTAMP '2018-04-20T12:31:33.666'");
}
[ConditionalFact]
......@@ -1342,7 +1342,7 @@ public async Task ZonedDateTime_Date(bool async)
AssertSql(
@"SELECT n.""Id"", n.""DateInterval"", n.""Duration"", n.""Instant"", n.""InstantRange"", n.""Interval"", n.""LocalDate"", n.""LocalDate2"", n.""LocalDateRange"", n.""LocalDateTime"", n.""LocalTime"", n.""Long"", n.""OffsetTime"", n.""Period"", n.""TimeZoneId"", n.""ZonedDateTime""
FROM ""NodaTimeTypes"" AS n
WHERE CAST(n.""ZonedDateTime"" AT TIME ZONE 'UTC' AS date) = DATE '2018-04-20'");
WHERE CAST((n.""ZonedDateTime"" AT TIME ZONE 'UTC') AS date) = DATE '2018-04-20'");
}
[ConditionalTheory]
......@@ -1375,7 +1375,7 @@ public async Task ZonedDateTime_LocalDateTime(bool async)
AssertSql(
@"SELECT n.""Id"", n.""DateInterval"", n.""Duration"", n.""Instant"", n.""InstantRange"", n.""Interval"", n.""LocalDate"", n.""LocalDate2"", n.""LocalDateRange"", n.""LocalDateTime"", n.""LocalTime"", n.""Long"", n.""OffsetTime"", n.""Period"", n.""TimeZoneId"", n.""ZonedDateTime""
FROM ""NodaTimeTypes"" AS n
WHERE n.""Instant"" AT TIME ZONE 'UTC' = TIMESTAMP '2018-04-20T10:31:33.666'");
WHERE (n.""Instant"" AT TIME ZONE 'UTC') = TIMESTAMP '2018-04-20T10:31:33.666'");
}
[ConditionalTheory]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册