Class: SPARQL::Algebra::Operator::Join
- Inherits:
-
Binary
- Object
- SPARQL::Algebra::Operator
- Binary
- SPARQL::Algebra::Operator::Join
- Includes:
- Query
- Defined in:
- lib/sparql/algebra/operator/join.rb
Overview
The SPARQL GraphPattern join
operator.
[54] GroupGraphPatternSub ::= TriplesBlock? (GraphPatternNotTriples “.”? TriplesBlock? )*
Constant Summary collapse
- NAME =
[:join]
Constants inherited from Binary
Constants inherited from SPARQL::Algebra::Operator
Constants included from Expression
Instance Attribute Summary
Attributes included from Query
Attributes inherited from SPARQL::Algebra::Operator
Instance Method Summary collapse
-
#execute(queryable, **options) {|solution| ... } ⇒ RDF::Query::Solutions
Executes each operand with
queryable
and performs thejoin
operation by creating a new solution set containing themerge
of all solutions from each set that arecompatible
with each other. -
#optimize!(**options) ⇒ Join, ...
Optimizes this query.
-
#to_sparql(top_level: true, filter_ops: [], extensions: {}, **options) ⇒ String
Returns a partial SPARQL grammar for this operator.
-
#validate! ⇒ Object
The same blank node label cannot be used in two different basic graph patterns in the same query.
Methods included from Query
#each_solution, #empty?, #failed?, #graph_name=, #matched?, #query_yields_boolean?, #query_yields_solutions?, #query_yields_statements?, #unshift, #variables
Methods inherited from Binary
Methods inherited from SPARQL::Algebra::Operator
#aggregate?, arity, #base_uri, base_uri, base_uri=, #bind, #boolean, #constant?, #deep_dup, #each_descendant, #eql?, #evaluatable?, evaluate, #executable?, #first_ancestor, for, #initialize, #inspect, #ndvars, #node?, #operand, #optimize, #parent, #parent=, #prefixes, prefixes, prefixes=, #rewrite, #to_binary, to_sparql, #to_sxp, #to_sxp_bin, #variable?, #variables, #vars
Methods included from Expression
cast, #constant?, #evaluate, extension, extension?, extensions, for, #invalid?, new, #node?, open, #optimize, parse, register_extension, #to_sxp_bin, #valid?, #variable?
Constructor Details
This class inherits a constructor from SPARQL::Algebra::Operator::Binary
Instance Method Details
#execute(queryable, **options) {|solution| ... } ⇒ RDF::Query::Solutions
Executes each operand with queryable
and performs the join
operation by creating a new solution set containing the merge
of all solutions from each set that are compatible
with each other.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/sparql/algebra/operator/join.rb', line 62 def execute(queryable, **, &block) # Join(Ω1, Ω2) = { merge(μ1, μ2) | μ1 in Ω1 and μ2 in Ω2, and μ1 and μ2 are compatible } # eval(D(G), Join(P1, P2)) = Join(eval(D(G), P1), eval(D(G), P2)) # # Generate solutions independently, merge based on solution compatibility debug() {"Join #{operands.to_sse}"} left = queryable.query(operand(0), **.merge(depth: [:depth].to_i + 1)) debug() {"(join)=>(left) #{left.map(&:to_h).to_sse}"} right = queryable.query(operand(1), **.merge(depth: [:depth].to_i + 1)) debug() {"(join)=>(right) #{right.map(&:to_h).to_sse}"} @solutions = RDF::Query::Solutions(left.map do |s1| right.map { |s2| s2.merge(s1) if s2.compatible?(s1) } end.flatten.compact) debug() {"(join)=> #{@solutions.map(&:to_h).to_sse}"} @solutions.each(&block) if block_given? @solutions end |
#optimize!(**options) ⇒ Join, ...
Optimizes this query.
Groups of one graph pattern (not a filter) become join(Z, A) and can be replaced by A. The empty graph pattern Z is the identity for join: Replace join(Z, A) by A Replace join(A, Z) by A
105 106 107 108 109 |
# File 'lib/sparql/algebra/operator/join.rb', line 105 def optimize!(**) ops = operands.map {|o| o.optimize(**) }.select {|o| o.respond_to?(:empty?) && !o.empty?} @operands = ops self end |
#to_sparql(top_level: true, filter_ops: [], extensions: {}, **options) ⇒ String
Returns a partial SPARQL grammar for this operator.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/sparql/algebra/operator/join.rb', line 122 def to_sparql(top_level: true, filter_ops: [], extensions: {}, **) # If this is top-level, and the last operand is a Table (values), put the values at the outer-level str = "{\n" + operands.first.to_sparql(top_level: false, extensions: {}, **) # Any accrued filters go here. filter_ops.each do |op| str << "\nFILTER (#{op.to_sparql(**)}) ." end if top_level && operands.last.is_a?(Table) str << "\n}" = .merge(values_clause: operands.last) else str << "\n{\n" + operands.last.to_sparql(top_level: false, extensions: {}, **) + "\n}\n}" end top_level ? Operator.to_sparql(str, extensions: extensions, **) : str end |
#validate! ⇒ Object
The same blank node label cannot be used in two different basic graph patterns in the same query
84 85 86 87 88 89 90 91 92 |
# File 'lib/sparql/algebra/operator/join.rb', line 84 def validate! left_nodes, right_nodes = operand(0).ndvars, operand(1).ndvars unless (left_nodes.compact & right_nodes.compact).empty? raise ArgumentError, "sub-operands share non-distinguished variables: #{(left_nodes.compact & right_nodes.compact).to_sse}" end super end |