openlink / virtuoso-opensource

Virtuoso is a high-performance and scalable Multi-Model RDBMS, Data Integration Middleware, Linked Data Deployment, and HTTP Application Server Platform
https://vos.openlinksw.com
Other
856 stars 210 forks source link

ADO.NET provider: problem with DateTime #610

Open drassokhin opened 7 years ago

drassokhin commented 7 years ago

It seems that the ADO.NET provider fails to deserialize values of the xsd:dateTime type when reading SPARQL query results.

Client code was tested under .net 4 on Windows 7, referencing virtado4.dll (virtado4, Version=4.0.0.0, Culture=neutral, PublicKeyToken=391bf132017ae989, File version: 7.20.3216.2). Server version: Version 07.20.3217-threads for Win64 as of Apr 25 2016.

The attached code snippet produces an ArgumentOutOfRange exception ("Hour, Minute, and Second parameters describe an un-representable DateTime.") with the following stack trace:

at System.DateTime.TimeToTicks(Int32 hour, Int32 minute, Int32 second)
   at OpenLink.Data.Virtuoso.VirtuosoDateTimeOffset..ctor(Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second, Int64 microsecond, TimeSpan offset)
   at OpenLink.Data.Virtuoso.DateTimeMarshaler.BytesToObject()
   at OpenLink.Data.Virtuoso.ManagedCommand.GetColumnData(Int32 i, ColumnData[] columns)
   at OpenLink.Data.Virtuoso.VirtuosoDataReader.GetColumnData(Int32 i)
   at OpenLink.Data.Virtuoso.VirtuosoDataReader.GetValues(Object[] values)
   at UserQuery.Main()

C# code to reproduce (this snippet can be run in LINQPad http://www.linqpad.net/ or converted to a C#/.NET project in Microsoft Visual Studio 2012 or 2015). The code snippet or VS project should reference virtado4.dll.

void Main()
{
    string host = "<replace with Virtuoso host>";
    string user = "<replace with login>";
    string pwd = "<replace with password>";
    string connString = string.Format(@"Server={0};Database=DB;uid={1};pwd={2};Charset=utf-8;Pooling=false;Connection Timeout=200", host, user, pwd);
    using (VirtuosoConnection conn = new VirtuosoConnection(connString))
    {   
        conn.Open();
        const string cmdText = 
        @"
SPARQL 
PREFIX xsd:<http://www.w3.org/2001/XMLSchema#> 
select ?s ?p ?o
where 
{
values (?s ?p ?o)
{
(<foo> <bar> ""2006-06-30T15:01:21""^^xsd:dateTime)
} 
}";
        try
        {
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = cmdText;
                cmd.CommandType = CommandType.Text;

                using (var r = cmd.ExecuteReader())
                {
                    while (true)
                    {
                        object[] rowData = new object[3];
                        if (!r.Read()) break;
                        r.GetValues(rowData);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            ex.Dump();
        }
    }
}
HughWilliams commented 7 years ago

@drassokhin: When I try to run the program in LINQPad it fails with a compilation error:

} expected

even though the brackets seem to match, so I don't see why it is failing ?

drassokhin commented 7 years ago

@HughWilliams I think LinqPad complained because the language option was not set to "C# Program". Please open the attached zip file, extract VirtuosoDateTimeBug.linq, open it in LinqPad, edit the host, user and password strings to match your test server settings, right-click inside the code editor pane, select Query Properties from the popup menu, edit the "additional references" option to point to your local copy of virtado4.dll and run the code. VirtuosoDateTimeBug.zip

smalinin commented 7 years ago

I have recreated the issue above, but I sent the fix for issues with DateTime in SPARQL queries some hours ago, so fix will be in Git soon. p.s. The last update fix the issue above, I have rechecked it.

drassokhin commented 7 years ago

@smalinin Cool! Thanks! Will you be able to build and publish the latest version of the ADO.NET provider as a NuGet package?

drassokhin commented 7 years ago

The latest version, which I have built from the source code in Visual Studio 2015, seems to read DateTime-type data correctly. For now, I can use the binary built from source in our projects, but I am sure most developers would rather reference the "official" built via NuGet. Also, perhaps, DateTime handling should be added to the test suite. I noticed there are .net-based tests in binsrc\tests\dotnet, but I did not have time to build and run them. BTW, I noticed that they are not based upon commonly used testing frameworks, such as, for example, nunit.

jomivar commented 7 years ago

Any news on whether this fix will be available in the NuGet package? As it stands, I can't properly retrieve DateTime objects with the latest pre-built version.

HughWilliams commented 7 years ago

It is not available for NuGet yet ... a prebuilt version is available from:

https://opldownload.s3.amazonaws.com/uda/virtuoso/ado.net/mono/OpenLink.Data.Virtuoso.dll

and also includes fix for git issue #419 ...