Skip to content

Commit ef00d08

Browse files
committed
Fix tests
1 parent 314f385 commit ef00d08

File tree

7 files changed

+44
-78
lines changed

7 files changed

+44
-78
lines changed

Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderIT.cs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -533,9 +533,13 @@ public void TestGetTimestampLTZ()
533533
{
534534
using (var conn = CreateAndOpenConnection())
535535
{
536+
IDbCommand setTimezoneCmd = conn.CreateCommand();
537+
setTimezoneCmd.CommandText = "ALTER SESSION SET TIMEZONE = 'America/Los_Angeles'";
538+
setTimezoneCmd.ExecuteNonQuery();
539+
536540
CreateOrReplaceTable(conn, TableName, new[] { "cola TIMESTAMP_LTZ" });
537541

538-
DateTimeOffset now = DateTimeOffset.Now;
542+
DateTimeOffset insertValue = new DateTimeOffset(2024, 1, 15, 18, 30, 45, 123, TimeSpan.Zero);
539543

540544
IDbCommand cmd = conn.CreateCommand();
541545

@@ -544,7 +548,7 @@ public void TestGetTimestampLTZ()
544548

545549
var p1 = (SnowflakeDbParameter)cmd.CreateParameter();
546550
p1.ParameterName = "1";
547-
p1.Value = now;
551+
p1.Value = insertValue;
548552
p1.DbType = DbType.DateTimeOffset;
549553
p1.SFDataType = Core.SFDataType.TIMESTAMP_LTZ;
550554
cmd.Parameters.Add(p1);
@@ -561,8 +565,8 @@ public void TestGetTimestampLTZ()
561565
DateTimeOffset dtOffset = (DateTimeOffset)reader.GetValue(0);
562566
reader.Close();
563567

564-
Assert.AreEqual(now, dtOffset);
565-
Assert.AreEqual(now.Offset, dtOffset.Offset);
568+
Assert.AreEqual(insertValue.UtcDateTime, dtOffset.UtcDateTime);
569+
Assert.AreEqual(TimeSpan.FromHours(-8), dtOffset.Offset);
566570

567571
CloseConnection(conn);
568572
}
@@ -1583,26 +1587,30 @@ public void TestTimestampTz(string testValue, int scale)
15831587
}
15841588

15851589
[Test]
1586-
[TestCase("2019-01-01 12:12:12.1234567 +0500", 7)]
1587-
[TestCase("2019-01-01 12:12:12.1234567 +1400", 7)]
1588-
[TestCase("0001-01-01 00:00:00.0000000 +0000", 9)]
1589-
[TestCase("9999-12-31 23:59:59.9999999 +0000", 9)]
1590-
public void TestTimestampLtz(string testValue, int scale)
1590+
[TestCase("2019-01-01 12:12:12.1234567 +0200", 7, "2019-01-01 02:12:12.1234567 -08:00")]
1591+
[TestCase("2019-01-01 12:12:12.1234567 +1400", 7, "2018-12-31 14:12:12.1234567 -08:00")]
1592+
[TestCase("1883-11-19 00:00:00.0000000 +0000", 9, "1883-11-18 16:00:00.0000000 -08:00")] // date when time zones were standardized
1593+
[TestCase("9999-12-31 23:59:59.9999999 +0000", 9, "9999-12-31 15:59:59.9999999 -08:00")]
1594+
[TestCase("2019-01-01 12:12:12.1234567", 7, "2019-01-01 12:12:12.1234567 -08:00")]
1595+
public void TestTimestampLtz(string testValue, int scale, string expectedValue)
15911596
{
15921597
using (var conn = CreateAndOpenConnection())
15931598
{
15941599
DbCommand cmd = conn.CreateCommand();
15951600

1601+
cmd.CommandText = "ALTER SESSION SET TIMEZONE = 'America/Los_Angeles'";
1602+
cmd.ExecuteNonQuery();
1603+
15961604
cmd.CommandText = $"select '{testValue}'::TIMESTAMP_LTZ({scale})";
15971605
using (SnowflakeDbDataReader reader = (SnowflakeDbDataReader)cmd.ExecuteReader())
15981606
{
15991607
ValidateResultFormat(reader);
16001608

16011609
reader.Read();
16021610

1603-
var expectedValue = DateTimeOffset.Parse(testValue).ToLocalTime();
1611+
var expected = DateTimeOffset.Parse(expectedValue);
16041612

1605-
Assert.AreEqual(expectedValue, reader.GetValue(0));
1613+
Assert.AreEqual(expected, reader.GetValue(0));
16061614
}
16071615

16081616
CloseConnection(conn);

Snowflake.Data.Tests/IntegrationTests/StructuredTypesWithEmbeddedUnstructuredIT.cs

Lines changed: 15 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ public void TestSelectDateTime(string dbValue, string dbType, DateTime? expected
288288
connection.Open();
289289
using (var command = connection.CreateCommand())
290290
{
291+
command.CommandText = "ALTER SESSION SET TIMEZONE = 'America/Los_Angeles'";
292+
command.ExecuteNonQuery();
293+
291294
EnableStructuredTypes(connection);
292295
SetTimePrecision(connection, 9);
293296
var rawValueString = $"'{dbValue}'::{dbType}";
@@ -328,10 +331,10 @@ internal static IEnumerable<object[]> DateTimeConversionCases()
328331
};
329332
yield return new object[]
330333
{
331-
"2024-07-11 14:20:05 -7:00",
334+
"2024-07-11 14:20:05",
332335
SFDataType.TIMESTAMP_LTZ.ToString(),
333336
null,
334-
DateTime.Parse("2024-07-11 21:20:05").ToLocalTime()
337+
DateTime.SpecifyKind(DateTime.Parse("2024-07-11 14:20:05"), DateTimeKind.Local)
335338
};
336339
yield return new object[]
337340
{
@@ -356,10 +359,10 @@ internal static IEnumerable<object[]> DateTimeConversionCases()
356359
};
357360
yield return new object[]
358361
{
359-
"2024-07-11 14:20:05.123456789 -7:00",
362+
"2024-07-11 14:20:05.123456789 -2:00",
360363
SFDataType.TIMESTAMP_LTZ.ToString(),
361364
null,
362-
DateTime.Parse("2024-07-11 21:20:05.1234568").ToLocalTime()
365+
DateTime.SpecifyKind(DateTime.Parse("2024-07-11 09:20:05.1234568"), DateTimeKind.Local)
363366
};
364367
yield return new object[]
365368
{
@@ -377,10 +380,10 @@ internal static IEnumerable<object[]> DateTimeConversionCases()
377380
};
378381
yield return new object[]
379382
{
380-
"9999-12-31 23:59:59.999999 +13:00",
383+
"1883-11-19 00:00:00.000000 -5:00",
381384
SFDataType.TIMESTAMP_LTZ.ToString(),
382385
null,
383-
DateTime.Parse("9999-12-31 10:59:59.999999").ToLocalTime()
386+
DateTime.Parse("1883-11-18 21:00:00.000000").ToLocalTime()
384387
};
385388
yield return new object[]
386389
{
@@ -408,6 +411,9 @@ public void TestSelectDateTimeOffset(string dbValue, string dbType, DateTime? ex
408411
connection.Open();
409412
using (var command = connection.CreateCommand())
410413
{
414+
command.CommandText = "ALTER SESSION SET TIMEZONE = 'America/Los_Angeles'";
415+
command.ExecuteNonQuery();
416+
411417
EnableStructuredTypes(connection);
412418
SetTimePrecision(connection, 9);
413419
var rawValueString = $"'{dbValue}'::{dbType}";
@@ -450,7 +456,7 @@ internal static IEnumerable<object[]> DateTimeOffsetConversionCases()
450456
"2024-07-11 14:20:05 -7:00",
451457
SFDataType.TIMESTAMP_LTZ.ToString(),
452458
null,
453-
DateTimeOffset.Parse("2024-07-11 14:20:05 -7:00").ToLocalTime()
459+
DateTimeOffset.Parse("2024-07-11 14:20:05 -7:00")
454460
};
455461
yield return new object[]
456462
{
@@ -475,10 +481,10 @@ internal static IEnumerable<object[]> DateTimeOffsetConversionCases()
475481
};
476482
yield return new object[]
477483
{
478-
"2024-07-11 14:20:05.123456789 -7:00",
484+
"2024-07-11 14:20:05.123456789 -2:00",
479485
SFDataType.TIMESTAMP_LTZ.ToString(),
480486
null,
481-
DateTimeOffset.Parse("2024-07-11 14:20:05.1234568 -7:00")
487+
DateTimeOffset.Parse("2024-07-11 09:20:05.1234568 -7:00")
482488
};
483489
yield return new object[]
484490
{
@@ -549,55 +555,5 @@ private void SetTimePrecision(SnowflakeDbConnection connection, int precision)
549555
command.ExecuteNonQuery();
550556
}
551557
}
552-
553-
[Test]
554-
public void TestStructuredTypeWithTimestampLtzHonorsSessionTimezone()
555-
{
556-
using (var connection = new SnowflakeDbConnection(ConnectionString))
557-
{
558-
connection.Open();
559-
560-
using (var command = connection.CreateCommand())
561-
{
562-
command.CommandText = "ALTER SESSION SET TIMEZONE = 'Europe/Warsaw'";
563-
command.ExecuteNonQuery();
564-
}
565-
566-
CreateOrReplaceTable(connection, "test_struct_ltz", new[]
567-
{
568-
"id INT",
569-
"data OBJECT(timestamp_value TIMESTAMP_LTZ)"
570-
});
571-
572-
using (var command = connection.CreateCommand())
573-
{
574-
command.CommandText = "INSERT INTO test_struct_ltz SELECT 1, {'timestamp_value': '2024-03-20 15:45:30'::TIMESTAMP_LTZ}";
575-
command.ExecuteNonQuery();
576-
577-
command.CommandText = "SELECT data FROM test_struct_ltz";
578-
using (var reader = (SnowflakeDbDataReader)command.ExecuteReader())
579-
{
580-
Assert.IsTrue(reader.Read());
581-
582-
var obj = reader.GetObject<TestObjectWithTimestampLtz>(0);
583-
584-
var warsawTz = TimeZoneConverter.TZConvert.GetTimeZoneInfo("Europe/Warsaw");
585-
var inputTime = new DateTime(2024, 3, 20, 15, 45, 30, DateTimeKind.Unspecified);
586-
var utcTime = TimeZoneInfo.ConvertTimeToUtc(inputTime, warsawTz);
587-
var expectedInWarsaw = TimeZoneInfo.ConvertTimeFromUtc(utcTime, warsawTz);
588-
589-
Assert.AreEqual(expectedInWarsaw, obj.TimestampValue,
590-
"Structured type TIMESTAMP_LTZ should honor session timezone");
591-
}
592-
}
593-
}
594-
}
595-
596-
[SnowflakeObject(ConstructionMethod = SnowflakeObjectConstructionMethod.PROPERTIES_NAMES)]
597-
private class TestObjectWithTimestampLtz
598-
{
599-
[SnowflakeColumn(Name = "timestamp_value")]
600-
public DateTime TimestampValue { get; set; }
601-
}
602558
}
603559
}

Snowflake.Data.Tests/UnitTests/ArrowResultChunkTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public void TestExtractCellReturnsNull()
182182
var chunk = pair.Key;
183183
var type = pair.Value;
184184
chunk.Next();
185-
Assert.AreEqual(DBNull.Value, chunk.ExtractCell(0, type, 0), $"Expected DBNull.Value for SFDataType: {type}");
185+
Assert.AreEqual(DBNull.Value, chunk.ExtractCell(0, type, 0, TimeZoneInfo.Utc), $"Expected DBNull.Value for SFDataType: {type}");
186186
}
187187
}
188188

@@ -192,7 +192,7 @@ public void TestExtractCellThrowsExceptionForNoneType()
192192
var chunk = new ArrowResultChunk(_recordBatchOne);
193193
chunk.Next();
194194

195-
Assert.Throws<NotSupportedException>(() => chunk.ExtractCell(0, SFDataType.None, 0));
195+
Assert.Throws<NotSupportedException>(() => chunk.ExtractCell(0, SFDataType.None, 0, TimeZoneInfo.Utc));
196196
}
197197

198198
[Test]
@@ -417,7 +417,7 @@ void TestExtractCell(IEnumerable testValues, SFDataType sfType, long scale, long
417417
chunk.Next();
418418

419419
var expectedValue = (divider == 0) ? testValue : Convert.ToDecimal(testValue) / divider;
420-
Assert.AreEqual(expectedValue, chunk.ExtractCell(0, sfType, scale));
420+
Assert.AreEqual(expectedValue, chunk.ExtractCell(0, sfType, scale, TimeZoneInfo.Utc));
421421
}
422422
}
423423
public static RecordBatch PrepareRecordBatch(SFDataType sfType, long scale, object values)

Snowflake.Data.Tests/UnitTests/StructuredTypesTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public void TestTimeConversions(string value, string sfTypeString, object expect
1919
var csharpType = expected.GetType();
2020

2121
// act
22-
var result = timeConverter.Convert(value, sfType, csharpType);
22+
var result = timeConverter.Convert(value, sfType, csharpType, TimeZoneInfo.Local);
2323

2424
// assert
2525
Assert.AreEqual(expected, result);

Snowflake.Data/Core/ArrowResultChunk.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,8 @@ public object ExtractCell(int columnIndex, SFDataType srcType, long scale, TimeZ
329329
var epoch = _long[columnIndex][_currentRecordIndex];
330330
var fraction = _fraction[columnIndex][_currentRecordIndex];
331331
var utcDateTime = s_epochDate.AddSeconds(epoch).AddTicks(fraction / 100);
332-
return TimeZoneInfo.ConvertTimeFromUtc(utcDateTime.UtcDateTime, sessionTimezone);
332+
var localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime.UtcDateTime, sessionTimezone);
333+
return new DateTimeOffset(localDateTime, sessionTimezone.GetUtcOffset(localDateTime));
333334
}
334335
else
335336
{
@@ -340,7 +341,8 @@ public object ExtractCell(int columnIndex, SFDataType srcType, long scale, TimeZ
340341
var epoch = ExtractEpoch(value, scale);
341342
var fraction = ExtractFraction(value, scale);
342343
var utcDateTime = s_epochDate.AddSeconds(epoch).AddTicks(fraction / 100);
343-
return TimeZoneInfo.ConvertTimeFromUtc(utcDateTime.UtcDateTime, sessionTimezone);
344+
var localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime.UtcDateTime, sessionTimezone);
345+
return new DateTimeOffset(localDateTime, sessionTimezone.GetUtcOffset(localDateTime));
344346
}
345347

346348
case SFDataType.TIMESTAMP_NTZ:

Snowflake.Data/Core/Converter/TimeConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public object Convert(string value, SFDataType timestampType, Type fieldType, Ti
5757
}
5858
if (fieldType == typeof(DateTime) || fieldType == typeof(DateTime?))
5959
{
60-
return dateTimeOffsetInSessionTz.DateTime;
60+
return DateTime.SpecifyKind(localDateTime, DateTimeKind.Local);
6161
}
6262
throw new StructuredTypesReadingException($"Cannot read TIMESTAMP_LTZ into {fieldType} type");
6363
}

Snowflake.Data/Core/SFBindUploader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ internal string GetCSVData(string sType, string sValue)
265265
: (long)(decimal.Parse(sValue) / 100);
266266

267267
DateTime utcDateTime = DateTime.SpecifyKind(epoch.AddTicks(ticksFromEpochLtz), DateTimeKind.Utc);
268-
var sessionTimezone = session.GetSessionTimezone();
268+
var sessionTimezone = session?.GetSessionTimezone() ?? TimeZoneInfo.Local;
269269
DateTime ltz = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, sessionTimezone);
270270
return new DateTimeOffset(ltz, sessionTimezone.GetUtcOffset(ltz)).ToString("O"); // ISO 8601 format
271271
case "TIMESTAMP_NTZ":

0 commit comments

Comments
 (0)