Skip to content

Commit b567c37

Browse files
fix datetime null error (#6627)
* fix datetime null error * clean up * enable test only on x64/x86 machines
1 parent d974a21 commit b567c37

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/Microsoft.ML.Data/DataLoadSave/Database/DatabaseLoaderCursor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ private ValueGetter<byte> CreateByteGetterDelegate(ColInfo colInfo)
307307
private ValueGetter<DateTime> CreateDateTimeGetterDelegate(ColInfo colInfo)
308308
{
309309
int columnIndex = GetColumnIndex(colInfo);
310-
return (ref DateTime value) => value = DataReader.GetDateTime(columnIndex);
310+
return (ref DateTime value) => value = DataReader.IsDBNull(columnIndex) ? default : DataReader.GetDateTime(columnIndex);
311311
}
312312

313313
private ValueGetter<double> CreateDoubleGetterDelegate(ColInfo colInfo)

test/Microsoft.ML.Tests/DatabaseLoaderTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
using System.Data.SqlClient;
88
using System.Data.SQLite;
99
using System.IO;
10+
using System.Linq;
1011
using System.Runtime.InteropServices;
12+
using FluentAssertions;
1113
using Microsoft.ML.Data;
1214
using Microsoft.ML.RunTests;
1315
using Microsoft.ML.TestFramework;
@@ -222,6 +224,38 @@ public void IrisSdcaMaximumEntropy()
222224
}).PredictedLabel);
223225
}
224226

227+
[X86X64FactAttribute("The SQLite un-managed code, SQLite.interop, only supports x86/x64 architectures.")]
228+
public void TestLoadDatetimeColumnWithNullValue()
229+
{
230+
var connectionString = "DataSource=Dummy;Mode=Memory;Version=3;Timeout=120;Cache=Shared";
231+
using (var connection = new SQLiteConnection(connectionString))
232+
{
233+
connection.Open();
234+
using (var command = new SQLiteCommand(connection))
235+
{
236+
command.CommandText = """
237+
BEGIN;
238+
CREATE TABLE IF NOT EXISTS Datetime (datetime Datetime NULL);
239+
INSERT INTO Datetime VALUES (NULL);
240+
INSERT INTO Datetime VALUES ('2018-01-01 00:00:00');
241+
COMMIT;
242+
""";
243+
command.ExecuteNonQuery();
244+
}
245+
}
246+
var mlContext = new MLContext(seed: 1);
247+
var loader = mlContext.Data.CreateDatabaseLoader(new DatabaseLoader.Column("datetime", DbType.DateTime, 0));
248+
var source = new DatabaseSource(SQLiteFactory.Instance, connectionString, "SELECT datetime FROM Datetime");
249+
var data = loader.Load(source);
250+
var datetimes = data.GetColumn<DateTime>("datetime").ToArray();
251+
datetimes.Count().Should().Be(2);
252+
253+
// Convert null value to DateTime.MinValue, aka 0001-01-01 00:00:00
254+
// This is the default behavior of TextLoader as well.
255+
datetimes[0].Should().Be(DateTime.MinValue);
256+
datetimes[1].Should().Be(new DateTime(2018, 1, 1, 0, 0, 0));
257+
}
258+
225259
/// <summary>
226260
/// Non-Windows builds do not support SqlClientFactory/MSSQL databases. Hence, an equivalent
227261
/// SQLite database is used on Linux and MacOS builds.

0 commit comments

Comments
 (0)