Skip to content

Commit

Permalink
Fix documentation on RDF::Query#initialize and #execuite to note …
Browse files Browse the repository at this point in the history
…that variable graph names do not match the default graph due to SPARQL semantics.

Fixes #442.
  • Loading branch information
gkellogg committed Nov 15, 2023
1 parent a889ba9 commit 656494d
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 11 deletions.
2 changes: 2 additions & 0 deletions lib/rdf/mixin/queryable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ def query_execute(query, **options, &block)
#
# Patterns may also have embedded patterns as either a subject or object, recursively.
#
# Patterns with a variable `graph_name` do not match the default graph.
#
# When matching, match an embedded pattern against embedded statements, recursively. (see {RDF::Query::Pattern#eql?})
#
# @param [RDF::Query::Pattern] pattern
Expand Down
15 changes: 6 additions & 9 deletions lib/rdf/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,9 @@ def self.Solutions(*args)
# @option options [RDF::Query::Solutions] :solutions (Solutions.new)
# @option options [RDF::Resource, RDF::Query::Variable, false] :graph_name (nil)
# Default graph name for matching against queryable.
# Named queries either match against a specifically named
# Queries with a graph name match against a specifically named
# graphs if the name is an {RDF::Resource} or bound {RDF::Query::Variable}.
# Names that are against unbound variables match either default
# or named graphs.
# Queries using an unbound variable as a graph name only match against named graphs, and will not match the default graph.
# The name of `false` will only match against the default graph.
# @option options [RDF::Resource, RDF::Query::Variable, false] :name (nil)
# Alias for `:graph_name`.
Expand All @@ -168,10 +167,9 @@ def self.Solutions(*args)
# @param [RDF::Query::Solutions] solutions (Solutions.new)
# @param [RDF::Resource, RDF::Query::Variable, false] graph_name (false)
# Default graph name for matching against queryable.
# Named queries either match against a specifically named
# Queries with a graph name match against a specifically named
# graphs if the name is an {RDF::Resource} or bound {RDF::Query::Variable}.
# Names that are against unbound variables match either default
# or named graphs.
# Queries using an unbound variable as a graph name only match against named graphs, and will not match the default graph.
# The name of `false` will only match against the default graph.
# @param [RDF::Resource, RDF::Query::Variable, false] name (false)
# Alias for `:graph_name`.
Expand Down Expand Up @@ -285,10 +283,9 @@ def optimize!(**options)
# @param [RDF::Query::Solutions] solutions (Solutions.new)
# @param [RDF::Resource, RDF::Query::Variable, false] graph_name (nil)
# Default graph name for matching against queryable.
# Named queries either match against a specifically named
# Queries with a graph name match against a specifically named
# graphs if the name is an {RDF::Resource} or bound {RDF::Query::Variable}.
# Names that are against unbound variables match either default
# or named graphs.
# Queries using an unbound variable as a graph name only match against named graphs, and will not match the default graph.
# The name of `false` will only match against the default graph.
# @param [RDF::Resource, RDF::Query::Variable, false] name (nil)
# Alias for `:graph_name`.
Expand Down
4 changes: 2 additions & 2 deletions lib/rdf/query/pattern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def self.from(pattern, graph_name: nil, **options)
# @option options [Variable, URI, Symbol, nil] :predicate (nil)
# @option options [Variable, Term, Symbol, nil] :object (nil)
# @option options [Variable, Resource, Symbol, nil, false] :graph_name (nil)
# A graph_name of nil matches any graph, a graph_name of false, matches only the default graph.
# A graph_name of nil matches any graph, a graph_name of false, matches only the default graph. (See {RDF::Query#initialize})
# @option options [Boolean] :optional (false)
#
# @overload initialize(subject, predicate, object, options = {})
Expand All @@ -32,7 +32,7 @@ def self.from(pattern, graph_name: nil, **options)
# @param [Variable, Termm, Symbol, nil] object
# @param [Hash{Symbol => Object}] options
# @option options [Variable, Resource, Symbol, nil, false] :graph_name (nil)
# A graph_name of nil matches any graph, a graph_name of false, matches only the default graph.
# A graph_name of nil matches any graph, a graph_name of false, matches only the default graph. (See {RDF::Query#initialize})
# @option options [Boolean] :optional (false)
#
# @note {Statement} treats symbols as interned {Node} instances, in a {Pattern}, they are treated as {Variable}.
Expand Down
2 changes: 2 additions & 0 deletions lib/rdf/query/variable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ def hash
# Returns `true` if this variable is equivalent to a given `other`
# variable. Or, to another Term if bound, or to any other Term
#
# @note when comparing against the default graph in an {RDF::Dataset}, `other` will be `false` and not be equal to an unbound variable.
#
# @param [Object] other
# @return [Boolean] `true` or `false`
# @since 0.3.0
Expand Down
37 changes: 37 additions & 0 deletions spec/query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,43 @@
end
end

context "Issues" do
it "issue #442" do
repository = RDF::Repository.new do |r|
# Adding a statement in the default graph
r << RDF::Statement.new(
RDF::URI('http://www.example.com#alice'),
RDF::URI('http://www.example.com#knows'),
RDF::URI('http://www.example.com#bob')
)

# Adding a statement in a named graph
r << RDF::Statement.new(
RDF::URI('http://www.example.com#alice'),
RDF::URI('http://www.example.com#knows'),
RDF::URI('http://www.example.com#charlie'),
graph_name: RDF::URI('http://www.example.com#named_graph')
)
end

query = RDF::Query.new(
{
RDF::URI('http://www.example.com#alice') => {
RDF::URI('http://www.example.com#knows') => :friend
}
},
graph_name: RDF::Query::Variable.new(:graph)
)

solutions = query.execute(repository)
expect(solutions.count).to eql(1)
expect(solutions.first).to eql(RDF::Query::Solution.new(
friend: RDF::URI('http://www.example.com#charlie'),
graph: RDF::URI('http://www.example.com#named_graph')
))
end
end

context "Examples" do
let!(:graph) {RDF::Graph.new.insert(RDF::Spec.triples.extend(RDF::Enumerable))}
subject {
Expand Down

0 comments on commit 656494d

Please sign in to comment.