From: Penny, C. <Chr...@ds...> - 2015-02-19 23:39:12
|
UNCLASSIFIED Hi all, I'm working off the following example, but using BIND instead of a triple pattern to give a value to ?service (actually BIND + CONCAT, but the problem can be shown with just BIND). http://www.w3.org/TR/sparql11-federated-query/#variableService The BIND call works, as illustrated by this query: SELECT ?service ?project ?projectName WHERE { BIND ("http://projects1.example.org/sparql" as ?service) . } This results in one value for ?service - http://projects1.example.org/sparql However, if I then add a SERVICE statement the query returns zero results: PREFIX doap: <http://usefulinc.com/ns/doap#<http://usefulinc.com/ns/doap>> SELECT ?service ?project ?projectName WHERE { BIND ("http://projects1.example.org/sparql" as ?service) . SERVICE ?service { ?project doap:name ?projectName . } } I am confident that the SERVICE call is never made as: Options.HttpDebugging = true; + no output to console. No traffic is seen in Wireshark. So then I spent some time debugging. Line 113 of Service.cs checks the type of node generated by BIND. This is always a NodeType.Literal, and NodeType.Uri is required. I believe this is because nodes generated by BIND are always given NodeType.Literal? I fixed this (for my purposes) by modifying SparqlExpressionParser.cs line 468, in the case Token.LITERAL I added a check to see if the string was actually a valid URI, which for me was just a string starting with "http://", then invoked the Token.URI code: if (next.Value.StartsWith("http://")) { return this.TryParseIriRefOrFunction(tokens); } This caused the expected service call. I don't know what best fix would be, but it would be nice to pass the results of BIND to a SERVICE statement. I had a second issue when putting SERVICE in an OPTIONAL block like this: PREFIX doap: <http://usefulinc.com/ns/doap#<http://usefulinc.com/ns/doap>> SELECT ?service ?project ?projectName WHERE { BIND ("http://projects1.example.org/sparql" as ?service) . OPTIONAL { SERVICE ?service { ?project doap:name ?projectName . } } } The following exception is thrown: VDS.RDF.Query.RdfQueryException was unhandled by user code HResult=-2146233088 Message=Query execution failed because evaluating a SERVICE clause failed - this may be due to an error with the remote service Source=dotNetRDF StackTrace: at VDS.RDF.Query.Algebra.Service.Evaluate(SparqlEvaluationContext context) in c:\projects\vsprojects\lib\dotnetrdf_library_source_107_stable\Libraries\core\net40\Query\Algebra\Service.cs:line 235 at VDS.RDF.Query.SparqlEvaluationContext.Evaluate(ISparqlAlgebra algebra) in c:\projects\vsprojects\lib\dotnetrdf_library_source_107_stable\Libraries\core\net40\Query\SparqlEvaluationContext.cs:line 399 at VDS.RDF.Query.Algebra.LeftJoin.Evaluate(SparqlEvaluationContext context) in c:\projects\vsprojects\lib\dotnetrdf_library_source_107_stable\Libraries\core\net40\Query\Algebra\AlgebraJoinClasses.cs:line 286 at VDS.RDF.Query.SparqlEvaluationContext.Evaluate(ISparqlAlgebra algebra) in c:\projects\vsprojects\lib\dotnetrdf_library_source_107_stable\Libraries\core\net40\Query\SparqlEvaluationContext.cs:line 399 at VDS.RDF.Query.Algebra.Select.Evaluate(SparqlEvaluationContext context) in c:\projects\vsprojects\lib\dotnetrdf_library_source_107_stable\Libraries\core\net40\Query\Algebra\Project.cs:line 85 at VDS.RDF.Query.SparqlEvaluationContext.Evaluate(ISparqlAlgebra algebra) in c:\projects\vsprojects\lib\dotnetrdf_library_source_107_stable\Libraries\core\net40\Query\SparqlEvaluationContext.cs:line 399 at VDS.RDF.Query.LeviathanQueryProcessor.ProcessQuery(IRdfHandler rdfHandler, ISparqlResultsHandler resultsHandler, SparqlQuery query) in c:\projects\vsprojects\lib\dotnetrdf_library_source_107_stable\Libraries\core\net40\Query\LeviathanQueryProcessor.cs:line 280 at VDS.RDF.Query.LeviathanQueryProcessor.ProcessQuery(SparqlQuery query) in c:\projects\vsprojects\lib\dotnetrdf_library_source_107_stable\Libraries\core\net40\Query\LeviathanQueryProcessor.cs:line 102 at VDS.RDF.Storage.InMemoryManager.Query(String sparqlQuery) in c:\projects\vsprojects\lib\dotnetrdf_library_source_107_stable\Libraries\core\net40\Storage\InMemoryManager.cs:line 325 at ABC.RDF.RdfAdaptor.executeQuery(String query) in c:\projects\vsprojects\RDF_Tester\RdfHandler.cs:line 90 at ABC.RDF. RDFTesterForm.<executeQueryButton_Click>b__1(Object o, DoWorkEventArgs args) in c:\projects\vsprojects\RDF_Tester\RdfManagerForm.cs:line 279 at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e) at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument) InnerException: VDS.RDF.Query.RdfQueryException HResult=-2146233088 Message=Cannot evaluate a SERVICE clause which uses a Variable as the Service specifier when the Variable is unbound Source=dotNetRDF StackTrace: at VDS.RDF.Query.Algebra.Service.Evaluate(SparqlEvaluationContext context) in c:\projects\vsprojects\lib\dotnetrdf_library_source_107_stable\Libraries\core\net40\Query\Algebra\Service.cs:line 108 InnerException: After reading a little on how dotNetRdf does SPARQL Optimisation (https://bitbucket.org/dotnetrdf/dotnetrdf/wiki/DeveloperGuide/SPARQL/SPARQL%20Optimization) I suspect that the SERVICE block is being executed before the BIND statement. This is supported by the fact a query containing only the BIND statement returns the URI as expected. However, I have not spent enough time with the debugger to confirm this. I am using version 1.0.7. Thanks in advance. Regards, Chris. IMPORTANT: This email remains the property of the Department of Defence and is subject to the jurisdiction of section 70 of the Crimes Act 1914. If you have received this email in error, you are requested to contact the sender and delete the email. |