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
868 stars 210 forks source link

Wrong literal types in federated queries #868

Open galgonek opened 5 years ago

galgonek commented 5 years ago

Hi,

I have performed some experiments with federated queries, and I have found out that Virtuoso sends no type information of numeric literals to a remote query service, so types of numeric literals depend on their lexical forms.

For example, the following query ...

SELECT (datatype(?val) as ?type) WHERE {
  SERVICE <https://sparql.rhea-db.org/sparql> {
     values ?val { "8"^^xsd:float "0.8"^^xsd:float "8e-1"^^xsd:float
               "8"^^xsd:double "0.8"^^xsd:double "8e-1"^^xsd:double }
  }
}

... returns this wrong result:

http://www.w3.org/2001/XMLSchema#integer
http://www.w3.org/2001/XMLSchema#decimal
http://www.w3.org/2001/XMLSchema#double
http://www.w3.org/2001/XMLSchema#integer
http://www.w3.org/2001/XMLSchema#decimal
http://www.w3.org/2001/XMLSchema#double

This is due to the fact that Virtuoso sends the following incorrectly modified query to a remote query service:

 SELECT ?val
 WHERE { 
     VALUES ( ?val) {
       ( 8 )
       ( 0.8 )
       ( 8e-1 )
       ( 8 )
       ( 0.8 )
       ( 8e-1 ) }
     }
galgonek commented 5 years ago

I think that the following quick and probably dirty patch of ssg_sdprin_literal could solve the issue:

--- virtuoso-opensource-develop-7.old/libsrc/Wi/sparqld.c       2019-07-17 22:32:05.000000000 +0200
+++ virtuoso-opensource-develop-7.new/libsrc/Wi/sparqld.c       2019-09-05 20:04:13.188929980 +0200
@@ -61,6 +61,14 @@
             ssg_puts (temp);
             ssg_putchar ('"');
           }
+        else if (NULL != tree->_.lit.original_text && NULL != tree->_.lit.datatype)
+          {
+            ssg_putchar ('"');
+            ssg_puts (tree->_.lit.original_text);
+            ssg_puts ("\"^^");
+            ssg_sdprin_qname (ssg, (SPART *)(tree->_.lit.datatype));
+            return;
+          }
         else if (NULL != tree->_.lit.original_text)
           ssg_puts (tree->_.lit.original_text);
         else
HughWilliams commented 5 years ago

We shall review your proposed patch ...