Skip to content

Commit 2519969

Browse files
committed
Postgresql TypeMapper changes
- TimeSpan reading assumes some values as MinValue/MaxValue, otherwise writing and then reading of MinValue/MaxValue will not be the same because of different number of fractional points in Postgre and .NET. We loose 18 particular values for comfort of comparison (we loose them anyway because of PG resolution). The odds of having MaxValue - 1-to-7 ticks or MinValue + 1-to-8 ticks as true values are extremely low. - some comments improved
1 parent 4d349c3 commit 2519969

File tree

1 file changed

+21
-9
lines changed
  • Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v8_0

1 file changed

+21
-9
lines changed

Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v8_0/TypeMapper.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ namespace Xtensive.Sql.Drivers.PostgreSql.v8_0
2020
internal class TypeMapper : Sql.TypeMapper
2121
{
2222
// 6 fractions instead of .NET's 7
23-
private const long DateTimeMaxValueAdjustedTicks = 3155378975999999990;
23+
private const long DateTimeMaxValueAdjustedTicks = 3155378975999999990;
24+
25+
// 6 fractions instead of .NET's 7
26+
private const long TimeSpanMinValueAdjustedTicks = -9223372036854775800;
27+
private const long TimeSpanMaxValueAdjustedTicks = 9223372036854775800;
2428

2529
protected readonly bool legacyTimestampBehaviorEnabled;
2630
protected readonly TimeSpan? defaultTimeZone;
@@ -236,9 +240,17 @@ public override object ReadTimeSpan(DbDataReader reader, int index)
236240
var nativeReader = (NpgsqlDataReader) reader;
237241
var nativeInterval = nativeReader.GetFieldValue<NpgsqlInterval>(index);
238242

239-
// support for full-range of Timespans required us to use raw type
243+
// support for full-range of TimeSpans requires us to use raw type
240244
// and construct timespan from its' values.
241-
return PostgreSqlHelper.ResurrectTimeSpanFromNpgsqlInterval(nativeInterval);
245+
var result = PostgreSqlHelper.ResurrectTimeSpanFromNpgsqlInterval(nativeInterval);
246+
247+
// for confinience of comparison in .NET we lose 7th fractional point and treat several
248+
// .Net values as one, Min or Max value.
249+
if (result == TimeSpan.MinValue || result.Ticks == TimeSpanMinValueAdjustedTicks)
250+
return TimeSpan.MinValue;
251+
if (result == TimeSpan.MaxValue || result.Ticks == TimeSpanMaxValueAdjustedTicks)
252+
return TimeSpan.MaxValue;
253+
return result;
242254
}
243255

244256
[SecuritySafeCritical]
@@ -259,10 +271,10 @@ public override object ReadDateTime(DbDataReader reader, int index)
259271
if (value == DateTime.MinValue || value == DateTime.MaxValue)
260272
return value;
261273
if (value.Ticks == DateTimeMaxValueAdjustedTicks) {
262-
// When Infinity aliases are disabled.
274+
// Applied when Infinity aliases are disabled.
263275
// To not ruin possible comparisons with defined value,
264276
// it is better to return definded value,
265-
// not the 6-digit version from PostgreSQL
277+
// not the 6-digit version from PostgreSQL.
266278
return DateTime.MaxValue;
267279
}
268280
return value;
@@ -273,11 +285,11 @@ public override object ReadDateTimeOffset(DbDataReader reader, int index)
273285
{
274286
var nativeReader = (NpgsqlDataReader) reader;
275287
var value = nativeReader.GetFieldValue<DateTimeOffset>(index);
276-
if (value.Ticks == DateTimeMaxValueAdjustedTicks ) {
277-
// When Infinity aliases are disabled.
288+
if (value.Ticks == DateTimeMaxValueAdjustedTicks) {
289+
// Applied when Infinity aliases are disabled.
278290
// To not ruin possible comparisons with defined values,
279291
// it is better to return definded value,
280-
// not the 6-fractions version from PostgreSQL
292+
// not the 6-fractions version from PostgreSQL.
281293
return DateTimeOffset.MaxValue;
282294
}
283295
if (value == DateTimeOffset.MaxValue || value == DateTimeOffset.MaxValue)
@@ -288,7 +300,7 @@ public override object ReadDateTimeOffset(DbDataReader reader, int index)
288300
return value;
289301
}
290302
else {
291-
// Here we try to apply connection timezone.
303+
// Here, we try to apply connection timezone to the values we read.
292304
// To not get it from internal connection of DbDataReader
293305
// we assume that time zone switch happens (if happens)
294306
// in DomainConfiguration.ConnectionInitializationSql and

0 commit comments

Comments
 (0)