-
Notifications
You must be signed in to change notification settings - Fork 11
Description
I found a bug in query parsing, which occurs with version 3.3.2 but not 3.3.1.
Here is a simplified code. In the code, two SPARQL queries SPARQL_QUERY_1 and SPARQL_QUERY_2 are defined; the difference between them are just the place of filter.
require 'rdf/raptor'
require 'sparql/client'
require 'linkeddata'
SPARQL_QUERY_1 = <<SPARQL
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX movieinfo: <https://api.hhiro.net/rdf/movieinfo.rdf#>
SELECT * WHERE {
?m rdf:type movieinfo:Movie;
movieinfo:MovieName ?mn;
movieinfo:DirectedBy ?d.
?d rdf:type movieinfo:Director;
movieinfo:PersonName ?pn.
filter(?mn = "Foo").
}
SPARQL
SPARQL_QUERY_2 = <<SPARQL
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX movieinfo: <https://api.hhiro.net/rdf/movieinfo.rdf#>
SELECT * WHERE {
?m rdf:type movieinfo:Movie;
movieinfo:MovieName ?mn;
movieinfo:DirectedBy ?d.
filter(?mn = "Foo").
?d rdf:type movieinfo:Director;
movieinfo:PersonName ?pn.
}
SPARQL
RDF_SOURCE = <<RDF
<!DOCTYPE rdf:RDF [
<!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>
<!ENTITY movieinfo 'https://api.hhiro.net/rdf/movieinfo.rdf#'>
]>
<rdf:RDF
xmlns:rdf="&rdf;"
xmlns:rdfs="&rdfs;"
xmlns:movieinfo="&movieinfo;"
>
<!-- Casting -->
<rdfs:Class rdf:ID="Movie" />
<rdfs:Class rdf:ID="Director" />
<rdf:Property rdf:about="&movieinfo;MovieName" />
<rdf:Property rdf:about="&movieinfo;DirectedBy" />
<rdf:Property rdf:about="&movieinfo;PersonName" />
<movieinfo:Movie>
<movieinfo:MovieName>Foo</movieinfo:MovieName>
<movieinfo:DirectedBy rdf:nodeID="Bar" />
</movieinfo:Movie>
<movieinfo:Movie>
<movieinfo:MovieName>Buz</movieinfo:MovieName>
<movieinfo:DirectedBy rdf:nodeID="Qux" />
</movieinfo:Movie>
<movieinfo:Director rdf:nodeID="Bar">
<movieinfo:PersonName>Bob Arnold</movieinfo:PersonName>
</movieinfo:Director>
<movieinfo:Director rdf:nodeID="Qux">
<movieinfo:PersonName>Quin Max</movieinfo:PersonName>
</movieinfo:Director>
</rdf:RDF>
RDF
def main
cli = SPARQL::Client.new(RDF::Repository.load("test.rdf.cgi"))
puts "---------- SPARQL_QUERY_1"
result1 = cli.query(SPARQL_QUERY_1)
result1.each do |r|
p r
end
puts "---------- SPARQL_QUERY_2"
result2 = cli.query(SPARQL_QUERY_2)
result2.each do |r|
p r
end
end
main
With version 3.3.1, it works properly with the following output:
---------- SPARQL_QUERY_1
#<RDF::Query::Solution:0x1cd4({:m=>#<RDF::Node:0x1c34(_:g7220)>, :d=>#<RDF::Node:0x1ce8(_:Bar)>, :mn=>#<RDF::Literal:0x1cfc("Foo")>, :pn=>#<RDF::Literal:0x1d10("Bob Arnold")>})>
---------- SPARQL_QUERY_2
#<RDF::Query::Solution:0x1cd4({:m=>#<RDF::Node:0x1c34(_:g7220)>, :d=>#<RDF::Node:0x1ce8(_:Bar)>, :mn=>#<RDF::Literal:0x1cfc("Foo")>, :pn=>#<RDF::Literal:0x1d10("Bob Arnold")>})>
But with version 3.3.2, SPARQL_QUERY_1 works properly but SPARQL_QUERY_2 raises an error.
---------- SPARQL_QUERY_1
#<RDF::Query::Solution:0x1c70({:m=>#<RDF::Node:0x1c34(_:g7220)>, :d=>#<RDF::Node:0x1c84(_:Bar)>, :mn=>#<RDF::Literal:0x1c98("Foo")>, :pn=>#<RDF::Literal:0x1cac("Bob Arnold")>})>
---------- SPARQL_QUERY_2
/home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql/algebra/operator.rb:948:in `initialize': wrong number of arguments (given 1, expected 2) (ArgumentError)
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql/algebra/operator/join.rb:113:in `new'
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql/algebra/operator/join.rb:113:in `optimize'
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql/algebra/operator.rb:671:in `block in optimize!'
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql/algebra/operator.rb:670:in `map!'
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql/algebra/operator.rb:670:in `optimize!'
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql/algebra/expression.rb:367:in `optimize'
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql/algebra/operator.rb:659:in `optimize'
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql/algebra/operator/prefix.rb:51:in `optimize'
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql.rb:40:in `parse'
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-3.3.2/lib/sparql.rb:82:in `execute'
from /home/sparql/sparql-testcase/vendor/bundle/ruby/3.1.0/gems/sparql-client-3.3.0/lib/sparql/client.rb:332:in `query'
from test.rb.cgi:79:in `main'
from test.rb.cgi:85:in `<main>'
As far as my understanding, in sparql/algebra/operator/join.rb line 113, it looks that self.class.new(ops) should be replaced with self.class.new(*ops). With this fix, The code above properly works. (Note: this code is for the class Join, and Join is a subclass of Operator::Binary. As defined in sparql/algebra/operator.rb, the constructor of Operator::Binary requires at least two arguments.)
But I am not confident with including this fix in the repository. This fix may cause errors for other SPARQL queries, and there may be similar fixes to be needed. Is anyone confident with this issue?