sparql 3.0.0 → 3.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +184 -70
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/bin/sparql +28 -17
- data/lib/rack/sparql.rb +1 -1
- data/lib/rack/sparql/conneg.rb +3 -3
- data/lib/sinatra/sparql.rb +5 -5
- data/lib/sparql.rb +14 -10
- data/lib/sparql/algebra.rb +15 -23
- data/lib/sparql/algebra/aggregate.rb +4 -4
- data/lib/sparql/algebra/evaluatable.rb +2 -2
- data/lib/sparql/algebra/expression.rb +28 -21
- data/lib/sparql/algebra/extensions.rb +142 -16
- data/lib/sparql/algebra/operator.rb +37 -16
- data/lib/sparql/algebra/operator/abs.rb +2 -2
- data/lib/sparql/algebra/operator/add.rb +3 -3
- data/lib/sparql/algebra/operator/alt.rb +4 -4
- data/lib/sparql/algebra/operator/and.rb +7 -7
- data/lib/sparql/algebra/operator/asc.rb +3 -3
- data/lib/sparql/algebra/operator/ask.rb +4 -14
- data/lib/sparql/algebra/operator/avg.rb +6 -4
- data/lib/sparql/algebra/operator/base.rb +10 -10
- data/lib/sparql/algebra/operator/bgp.rb +1 -1
- data/lib/sparql/algebra/operator/bnode.rb +5 -5
- data/lib/sparql/algebra/operator/bound.rb +3 -3
- data/lib/sparql/algebra/operator/ceil.rb +2 -2
- data/lib/sparql/algebra/operator/clear.rb +3 -3
- data/lib/sparql/algebra/operator/coalesce.rb +3 -13
- data/lib/sparql/algebra/operator/compare.rb +8 -8
- data/lib/sparql/algebra/operator/concat.rb +4 -4
- data/lib/sparql/algebra/operator/construct.rb +4 -14
- data/lib/sparql/algebra/operator/contains.rb +2 -2
- data/lib/sparql/algebra/operator/copy.rb +3 -3
- data/lib/sparql/algebra/operator/count.rb +3 -3
- data/lib/sparql/algebra/operator/create.rb +3 -3
- data/lib/sparql/algebra/operator/dataset.rb +5 -16
- data/lib/sparql/algebra/operator/datatype.rb +1 -1
- data/lib/sparql/algebra/operator/day.rb +1 -1
- data/lib/sparql/algebra/operator/delete.rb +7 -5
- data/lib/sparql/algebra/operator/delete_data.rb +3 -3
- data/lib/sparql/algebra/operator/delete_where.rb +5 -5
- data/lib/sparql/algebra/operator/desc.rb +1 -1
- data/lib/sparql/algebra/operator/describe.rb +3 -13
- data/lib/sparql/algebra/operator/distinct.rb +4 -14
- data/lib/sparql/algebra/operator/divide.rb +1 -1
- data/lib/sparql/algebra/operator/drop.rb +3 -3
- data/lib/sparql/algebra/operator/encode_for_uri.rb +3 -3
- data/lib/sparql/algebra/operator/equal.rb +3 -3
- data/lib/sparql/algebra/operator/exists.rb +5 -5
- data/lib/sparql/algebra/operator/exprlist.rb +3 -13
- data/lib/sparql/algebra/operator/extend.rb +21 -20
- data/lib/sparql/algebra/operator/filter.rb +6 -16
- data/lib/sparql/algebra/operator/floor.rb +2 -2
- data/lib/sparql/algebra/operator/graph.rb +5 -16
- data/lib/sparql/algebra/operator/greater_than.rb +5 -5
- data/lib/sparql/algebra/operator/greater_than_or_equal.rb +5 -5
- data/lib/sparql/algebra/operator/group.rb +25 -25
- data/lib/sparql/algebra/operator/group_concat.rb +6 -6
- data/lib/sparql/algebra/operator/hours.rb +1 -1
- data/lib/sparql/algebra/operator/if.rb +5 -15
- data/lib/sparql/algebra/operator/in.rb +4 -14
- data/lib/sparql/algebra/operator/insert.rb +6 -4
- data/lib/sparql/algebra/operator/insert_data.rb +3 -3
- data/lib/sparql/algebra/operator/iri.rb +1 -1
- data/lib/sparql/algebra/operator/is_blank.rb +1 -1
- data/lib/sparql/algebra/operator/is_iri.rb +1 -1
- data/lib/sparql/algebra/operator/is_literal.rb +1 -1
- data/lib/sparql/algebra/operator/is_numeric.rb +1 -1
- data/lib/sparql/algebra/operator/join.rb +12 -10
- data/lib/sparql/algebra/operator/lang.rb +1 -1
- data/lib/sparql/algebra/operator/lang_matches.rb +3 -3
- data/lib/sparql/algebra/operator/lcase.rb +2 -2
- data/lib/sparql/algebra/operator/left_join.rb +15 -12
- data/lib/sparql/algebra/operator/less_than.rb +5 -5
- data/lib/sparql/algebra/operator/less_than_or_equal.rb +5 -5
- data/lib/sparql/algebra/operator/load.rb +3 -3
- data/lib/sparql/algebra/operator/max.rb +6 -4
- data/lib/sparql/algebra/operator/md5.rb +1 -1
- data/lib/sparql/algebra/operator/min.rb +6 -4
- data/lib/sparql/algebra/operator/minus.rb +12 -11
- data/lib/sparql/algebra/operator/minutes.rb +1 -1
- data/lib/sparql/algebra/operator/modify.rb +4 -4
- data/lib/sparql/algebra/operator/month.rb +1 -1
- data/lib/sparql/algebra/operator/move.rb +3 -3
- data/lib/sparql/algebra/operator/multiply.rb +1 -1
- data/lib/sparql/algebra/operator/negate.rb +1 -1
- data/lib/sparql/algebra/operator/not.rb +1 -1
- data/lib/sparql/algebra/operator/not_equal.rb +2 -2
- data/lib/sparql/algebra/operator/notexists.rb +4 -4
- data/lib/sparql/algebra/operator/notin.rb +4 -14
- data/lib/sparql/algebra/operator/notoneof.rb +5 -6
- data/lib/sparql/algebra/operator/now.rb +1 -1
- data/lib/sparql/algebra/operator/or.rb +7 -7
- data/lib/sparql/algebra/operator/order.rb +6 -16
- data/lib/sparql/algebra/operator/path.rb +6 -5
- data/lib/sparql/algebra/operator/path_opt.rb +16 -16
- data/lib/sparql/algebra/operator/path_plus.rb +8 -8
- data/lib/sparql/algebra/operator/path_star.rb +4 -4
- data/lib/sparql/algebra/operator/plus.rb +3 -3
- data/lib/sparql/algebra/operator/prefix.rb +10 -10
- data/lib/sparql/algebra/operator/project.rb +4 -14
- data/lib/sparql/algebra/operator/rand.rb +1 -1
- data/lib/sparql/algebra/operator/reduced.rb +4 -14
- data/lib/sparql/algebra/operator/regex.rb +6 -6
- data/lib/sparql/algebra/operator/replace.rb +4 -4
- data/lib/sparql/algebra/operator/reverse.rb +4 -4
- data/lib/sparql/algebra/operator/round.rb +2 -2
- data/lib/sparql/algebra/operator/same_term.rb +8 -5
- data/lib/sparql/algebra/operator/sample.rb +3 -3
- data/lib/sparql/algebra/operator/seconds.rb +1 -1
- data/lib/sparql/algebra/operator/seq.rb +5 -6
- data/lib/sparql/algebra/operator/sequence.rb +4 -4
- data/lib/sparql/algebra/operator/sha1.rb +1 -1
- data/lib/sparql/algebra/operator/sha256.rb +1 -1
- data/lib/sparql/algebra/operator/sha384.rb +1 -1
- data/lib/sparql/algebra/operator/sha512.rb +1 -1
- data/lib/sparql/algebra/operator/slice.rb +4 -14
- data/lib/sparql/algebra/operator/str.rb +1 -1
- data/lib/sparql/algebra/operator/strafter.rb +2 -2
- data/lib/sparql/algebra/operator/strbefore.rb +2 -2
- data/lib/sparql/algebra/operator/strdt.rb +2 -2
- data/lib/sparql/algebra/operator/strends.rb +2 -2
- data/lib/sparql/algebra/operator/strlang.rb +2 -2
- data/lib/sparql/algebra/operator/strlen.rb +2 -2
- data/lib/sparql/algebra/operator/strstarts.rb +2 -2
- data/lib/sparql/algebra/operator/struuid.rb +1 -1
- data/lib/sparql/algebra/operator/substr.rb +4 -4
- data/lib/sparql/algebra/operator/subtract.rb +1 -1
- data/lib/sparql/algebra/operator/sum.rb +6 -4
- data/lib/sparql/algebra/operator/table.rb +6 -4
- data/lib/sparql/algebra/operator/timezone.rb +1 -1
- data/lib/sparql/algebra/operator/tz.rb +1 -1
- data/lib/sparql/algebra/operator/ucase.rb +2 -2
- data/lib/sparql/algebra/operator/union.rb +10 -9
- data/lib/sparql/algebra/operator/update.rb +4 -4
- data/lib/sparql/algebra/operator/using.rb +4 -4
- data/lib/sparql/algebra/operator/uuid.rb +1 -1
- data/lib/sparql/algebra/operator/with.rb +6 -6
- data/lib/sparql/algebra/operator/year.rb +1 -1
- data/lib/sparql/algebra/query.rb +2 -2
- data/lib/sparql/algebra/update.rb +2 -2
- data/lib/sparql/algebra/version.rb +1 -1
- data/lib/sparql/extensions.rb +5 -5
- data/lib/sparql/grammar.rb +111 -11
- data/lib/sparql/grammar/meta.rb +1372 -333
- data/lib/sparql/grammar/parser11.rb +56 -42
- data/lib/sparql/grammar/terminals11.rb +1 -0
- data/lib/sparql/results.rb +63 -44
- data/lib/sparql/version.rb +1 -1
- metadata +40 -47
@@ -11,7 +11,7 @@ module SPARQL; module Algebra
|
|
11
11
|
# @example
|
12
12
|
# (drop default)
|
13
13
|
#
|
14
|
-
# @see
|
14
|
+
# @see https://www.w3.org/TR/sparql11-update/#drop
|
15
15
|
class Drop < Operator
|
16
16
|
include SPARQL::Algebra::Update
|
17
17
|
|
@@ -30,8 +30,8 @@ module SPARQL; module Algebra
|
|
30
30
|
# Returns queryable.
|
31
31
|
# @raise [IOError]
|
32
32
|
# If `from` does not exist, unless the `silent` operator is present
|
33
|
-
# @see
|
34
|
-
def execute(queryable, options
|
33
|
+
# @see https://www.w3.org/TR/sparql11-update/
|
34
|
+
def execute(queryable, **options)
|
35
35
|
debug(options) {"Drop"}
|
36
36
|
silent = operands.first == :silent
|
37
37
|
silent = operands.first == :silent
|
@@ -8,8 +8,8 @@ module SPARQL; module Algebra
|
|
8
8
|
# @example
|
9
9
|
# (encode_for_uri ?x)
|
10
10
|
#
|
11
|
-
# @see
|
12
|
-
# @see
|
11
|
+
# @see https://www.w3.org/TR/sparql11-query/#func-encode
|
12
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-abs
|
13
13
|
class EncodeForURI < Operator::Unary
|
14
14
|
include Evaluatable
|
15
15
|
|
@@ -29,7 +29,7 @@ module SPARQL; module Algebra
|
|
29
29
|
# @raise [TypeError] if the operand is not a literal value
|
30
30
|
def apply(operand)
|
31
31
|
case operand
|
32
|
-
when RDF::Literal then RDF::Literal(
|
32
|
+
when RDF::Literal then RDF::Literal(CGI.escape(operand.to_s))
|
33
33
|
else raise TypeError, "expected an RDF::Literal, but got #{operand.inspect}"
|
34
34
|
end
|
35
35
|
end
|
@@ -6,8 +6,8 @@ module SPARQL; module Algebra
|
|
6
6
|
# @example
|
7
7
|
# (= ?x ?y)
|
8
8
|
#
|
9
|
-
# @see
|
10
|
-
# @see
|
9
|
+
# @see https://www.w3.org/TR/sparql11-query/#OperatorMapping
|
10
|
+
# @see https://www.w3.org/TR/sparql11-query/#func-RDFterm-equal
|
11
11
|
class Equal < Compare
|
12
12
|
NAME = :'='
|
13
13
|
|
@@ -25,7 +25,7 @@ module SPARQL; module Algebra
|
|
25
25
|
# @return [RDF::Literal::Boolean] `true` or `false`
|
26
26
|
# @raise [TypeError] if either operand is not an RDF term or operands are not comperable
|
27
27
|
#
|
28
|
-
# @see
|
28
|
+
# @see RDF::Term#==
|
29
29
|
def apply(term1, term2)
|
30
30
|
term1 = term1.dup.extend(RDF::TypeCheck)
|
31
31
|
term2 = term2.dup.extend(RDF::TypeCheck)
|
@@ -10,7 +10,7 @@ module SPARQL; module Algebra
|
|
10
10
|
# (filter (exists (bgp (triple ?s ?p ex:o)))
|
11
11
|
# (bgp (triple ?s ?p ?o))))
|
12
12
|
#
|
13
|
-
# @see
|
13
|
+
# @see https://www.w3.org/TR/sparql11-query/#func-filter-exists
|
14
14
|
class Exists < Operator::Unary
|
15
15
|
include Evaluatable
|
16
16
|
|
@@ -26,11 +26,11 @@ module SPARQL; module Algebra
|
|
26
26
|
# @option options[RDF::Queryable] queryable
|
27
27
|
# queryable to execute, using bindings as an initial solution.
|
28
28
|
# @return [RDF::Literal::Boolean] `true` or `false`
|
29
|
-
def evaluate(bindings, options
|
29
|
+
def evaluate(bindings, **options)
|
30
30
|
queryable = options[:queryable]
|
31
|
-
!operand(0).execute(queryable,
|
32
|
-
|
33
|
-
|
31
|
+
!operand(0).execute(queryable, solutions: RDF::Query::Solutions(bindings),
|
32
|
+
depth: options[:depth].to_i + 1,
|
33
|
+
**options).empty?
|
34
34
|
end
|
35
35
|
end # Exists
|
36
36
|
end # Operator
|
@@ -14,7 +14,7 @@ module SPARQL; module Algebra
|
|
14
14
|
# (triple ?s :q ?w)
|
15
15
|
# ))))
|
16
16
|
#
|
17
|
-
# @see
|
17
|
+
# @see https://www.w3.org/TR/sparql11-query/#evaluation
|
18
18
|
class Exprlist < Operator
|
19
19
|
include Evaluatable
|
20
20
|
|
@@ -36,20 +36,10 @@ module SPARQL; module Algebra
|
|
36
36
|
# options passed from query
|
37
37
|
# @return [RDF::Literal::Boolean] `true` or `false`
|
38
38
|
# @raise [TypeError] if the operands could not be coerced to a boolean literal
|
39
|
-
def evaluate(bindings, options
|
40
|
-
res = operands.all? {|op| boolean(op.evaluate(bindings,
|
39
|
+
def evaluate(bindings, **options)
|
40
|
+
res = operands.all? {|op| boolean(op.evaluate(bindings, depth: options[:depth].to_i + 1, **options)).true? }
|
41
41
|
RDF::Literal(res) # FIXME: error handling
|
42
42
|
end
|
43
|
-
|
44
|
-
##
|
45
|
-
# Returns an optimized version of this query.
|
46
|
-
#
|
47
|
-
# Return optimized query
|
48
|
-
#
|
49
|
-
# @return [Union, RDF::Query] `self`
|
50
|
-
def optimize
|
51
|
-
operands = operands.map(&:optimize)
|
52
|
-
end
|
53
43
|
end # Exprlist
|
54
44
|
end # Operator
|
55
45
|
end; end # SPARQL::Algebra
|
@@ -11,7 +11,7 @@ module SPARQL; module Algebra
|
|
11
11
|
# (extend ((?z (+ ?o 10)))
|
12
12
|
# (bgp (triple ?s <http://example/p> ?o)))))
|
13
13
|
#
|
14
|
-
# @see
|
14
|
+
# @see https://www.w3.org/TR/sparql11-query/#evaluation
|
15
15
|
class Extend < Operator::Binary
|
16
16
|
include Query
|
17
17
|
|
@@ -28,6 +28,12 @@ module SPARQL; module Algebra
|
|
28
28
|
#
|
29
29
|
# Extend(Ω, var, expr) = { Extend(μ, var, expr) | μ in Ω }
|
30
30
|
#
|
31
|
+
# For SPARQL*, expr may be an embedded tiple pattern
|
32
|
+
#
|
33
|
+
# (extend
|
34
|
+
# ((?t (triple ?bob foaf:age ?age)))
|
35
|
+
# (bgp (triple ?t dct:source ?src)))
|
36
|
+
#
|
31
37
|
# @param [RDF::Queryable] queryable
|
32
38
|
# the graph or repository to query
|
33
39
|
# @param [Hash{Symbol => Object}] options
|
@@ -38,19 +44,24 @@ module SPARQL; module Algebra
|
|
38
44
|
# @yieldreturn [void] ignored
|
39
45
|
# @return [RDF::Query::Solutions]
|
40
46
|
# the resulting solution sequence
|
41
|
-
# @see
|
42
|
-
def execute(queryable, options
|
47
|
+
# @see https://www.w3.org/TR/sparql11-query/#evaluation
|
48
|
+
def execute(queryable, **options, &block)
|
43
49
|
debug(options) {"Extend"}
|
44
|
-
@solutions = operand(1).execute(queryable,
|
50
|
+
@solutions = operand(1).execute(queryable, depth: options[:depth].to_i + 1, **options)
|
45
51
|
@solutions.each do |solution|
|
46
52
|
debug(options) {"===> soln #{solution.to_h.inspect}"}
|
47
53
|
operand(0).each do |(var, expr)|
|
48
54
|
begin
|
49
|
-
val = expr.evaluate(solution,
|
50
|
-
|
51
|
-
|
55
|
+
val = expr.evaluate(solution, queryable: queryable,
|
56
|
+
depth: options[:depth].to_i + 1,
|
57
|
+
**options)
|
52
58
|
debug(options) {"===> + #{var} => #{val.inspect}"}
|
53
|
-
solution.bindings[var.to_sym] = val
|
59
|
+
solution.bindings[var.to_sym] = if val.is_a?(RDF::Query::Pattern)
|
60
|
+
# Variable is bound to the solution
|
61
|
+
val.bind(solution)
|
62
|
+
else
|
63
|
+
val
|
64
|
+
end
|
54
65
|
rescue TypeError => e
|
55
66
|
# Evaluates to error, ignore
|
56
67
|
debug(options) {"===> #{var} error: #{e.message}"}
|
@@ -63,8 +74,8 @@ module SPARQL; module Algebra
|
|
63
74
|
|
64
75
|
# The variable introduced by the BIND clause must not have been used in the group graph pattern up to the point of use in BIND
|
65
76
|
def validate!
|
66
|
-
bind_vars = operand(0).map(&:first)
|
67
|
-
query_vars = operand(1).vars
|
77
|
+
bind_vars = operand(0).map(&:first).map(&:name)
|
78
|
+
query_vars = operand(1).vars.map(&:name)
|
68
79
|
|
69
80
|
unless (bind_vars.compact & query_vars.compact).empty?
|
70
81
|
raise ArgumentError,
|
@@ -72,16 +83,6 @@ module SPARQL; module Algebra
|
|
72
83
|
end
|
73
84
|
super
|
74
85
|
end
|
75
|
-
|
76
|
-
##
|
77
|
-
# Returns an optimized version of this query.
|
78
|
-
#
|
79
|
-
# Return optimized query
|
80
|
-
#
|
81
|
-
# @return FIXME
|
82
|
-
def optimize
|
83
|
-
operands = operands.map(&:optimize)
|
84
|
-
end
|
85
86
|
end # Filter
|
86
87
|
end # Operator
|
87
88
|
end; end # SPARQL::Algebra
|
@@ -9,7 +9,7 @@ module SPARQL; module Algebra
|
|
9
9
|
# (filter (= ?v 2)
|
10
10
|
# (bgp (triple ?s <http://example/p> ?v)))))
|
11
11
|
#
|
12
|
-
# @see
|
12
|
+
# @see https://www.w3.org/TR/sparql11-query/#evaluation
|
13
13
|
class Filter < Operator::Binary
|
14
14
|
include Query
|
15
15
|
|
@@ -34,15 +34,15 @@ module SPARQL; module Algebra
|
|
34
34
|
# @yieldreturn [void] ignored
|
35
35
|
# @return [RDF::Query::Solutions]
|
36
36
|
# the resulting solution sequence
|
37
|
-
# @see
|
38
|
-
# @see
|
39
|
-
def execute(queryable, options
|
37
|
+
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
38
|
+
# @see https://www.w3.org/TR/sparql11-query/#ebv
|
39
|
+
def execute(queryable, **options, &block)
|
40
40
|
debug(options) {"Filter #{operands.first.to_sxp}"}
|
41
41
|
opts = options.merge(queryable: queryable, depth: options[:depth].to_i + 1)
|
42
42
|
@solutions = RDF::Query::Solutions()
|
43
|
-
queryable.query(operands.last,
|
43
|
+
queryable.query(operands.last, depth: options[:depth].to_i + 1, **options) do |solution|
|
44
44
|
begin
|
45
|
-
pass = boolean(operands.first.evaluate(solution, opts)).true?
|
45
|
+
pass = boolean(operands.first.evaluate(solution, **opts)).true?
|
46
46
|
debug(options) {"(filter) #{pass.inspect} #{solution.to_h.inspect}"}
|
47
47
|
@solutions << solution if pass
|
48
48
|
rescue
|
@@ -69,16 +69,6 @@ module SPARQL; module Algebra
|
|
69
69
|
end
|
70
70
|
self
|
71
71
|
end
|
72
|
-
|
73
|
-
##
|
74
|
-
# Returns an optimized version of this query.
|
75
|
-
#
|
76
|
-
# Return optimized query
|
77
|
-
#
|
78
|
-
# @return [Union, RDF::Query] `self`
|
79
|
-
def optimize
|
80
|
-
operands = operands.map(&:optimize)
|
81
|
-
end
|
82
72
|
end # Filter
|
83
73
|
end # Operator
|
84
74
|
end; end # SPARQL::Algebra
|
@@ -6,8 +6,8 @@ module SPARQL; module Algebra
|
|
6
6
|
# @example
|
7
7
|
# (floor ?x)
|
8
8
|
#
|
9
|
-
# @see
|
10
|
-
# @see
|
9
|
+
# @see https://www.w3.org/TR/sparql11-query/#func-floor
|
10
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-floor
|
11
11
|
class Floor < Operator::Unary
|
12
12
|
include Evaluatable
|
13
13
|
|
@@ -15,7 +15,7 @@ module SPARQL; module Algebra
|
|
15
15
|
# (graph :g
|
16
16
|
# ((triple :s :p :o))))
|
17
17
|
#
|
18
|
-
# @see
|
18
|
+
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
19
19
|
class Graph < Operator::Binary
|
20
20
|
include Query
|
21
21
|
|
@@ -63,26 +63,15 @@ module SPARQL; module Algebra
|
|
63
63
|
# @yieldreturn [void] ignored
|
64
64
|
# @return [RDF::Query::Solutions]
|
65
65
|
# the resulting solution sequence
|
66
|
-
# @see
|
67
|
-
def execute(queryable, options
|
66
|
+
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
67
|
+
def execute(queryable, **options, &block)
|
68
68
|
debug(options) {"Graph #{operands.first}"}
|
69
69
|
graph_name, query = operands.first, operands.last
|
70
|
-
@solutions = queryable.query(query,
|
70
|
+
@solutions = queryable.query(query, graph_name: graph_name, **options, &block)
|
71
71
|
end
|
72
|
-
|
73
|
-
##
|
74
|
-
# Returns an optimized version of this query.
|
75
|
-
#
|
76
|
-
# Return optimized query
|
77
|
-
#
|
78
|
-
# @return [Union, RDF::Query] `self`
|
79
|
-
def optimize
|
80
|
-
operands = operands.map(&:optimize)
|
81
|
-
end
|
82
|
-
|
72
|
+
|
83
73
|
##
|
84
74
|
# Don't do any more rewriting
|
85
|
-
# FIXME: if ooperator is JOIN, and rewritten sub-operators are queries, can do simple merge of sub-graphs
|
86
75
|
# @return [SPARQL::Algebra::Expression] `self`
|
87
76
|
def rewrite(&block)
|
88
77
|
self
|
@@ -6,11 +6,11 @@ module SPARQL; module Algebra
|
|
6
6
|
# @example
|
7
7
|
# (> ?x ?y)
|
8
8
|
#
|
9
|
-
# @see
|
10
|
-
# @see
|
11
|
-
# @see
|
12
|
-
# @see
|
13
|
-
# @see
|
9
|
+
# @see https://www.w3.org/TR/sparql11-query/#OperatorMapping
|
10
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-compare
|
11
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-numeric-greater-than
|
12
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-boolean-greater-than
|
13
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-dateTime-greater-than
|
14
14
|
class GreaterThan < Compare
|
15
15
|
NAME = :>
|
16
16
|
|
@@ -7,11 +7,11 @@ module SPARQL; module Algebra
|
|
7
7
|
# @example
|
8
8
|
# (>= ?x ?y)
|
9
9
|
#
|
10
|
-
# @see
|
11
|
-
# @see
|
12
|
-
# @see
|
13
|
-
# @see
|
14
|
-
# @see
|
10
|
+
# @see https://www.w3.org/TR/sparql11-query/#OperatorMapping
|
11
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-compare
|
12
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-numeric-greater-than
|
13
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-boolean-greater-than
|
14
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-dateTime-greater-than
|
15
15
|
class GreaterThanOrEqual < Compare
|
16
16
|
NAME = :>=
|
17
17
|
|
@@ -11,13 +11,13 @@ module SPARQL; module Algebra
|
|
11
11
|
# @example
|
12
12
|
# (prefix ((: <http://example/>))
|
13
13
|
# (project (?w ?S)
|
14
|
-
# (extend ((?S
|
15
|
-
# (group (?w) ((
|
14
|
+
# (extend ((?S ??.0))
|
15
|
+
# (group (?w) ((??.0 (sample ?v)))
|
16
16
|
# (leftjoin
|
17
17
|
# (bgp (triple ?s :p ?v))
|
18
18
|
# (bgp (triple ?s :q ?w)))))))
|
19
19
|
#
|
20
|
-
# @see
|
20
|
+
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
21
21
|
class Group < Operator
|
22
22
|
include Query
|
23
23
|
|
@@ -37,13 +37,13 @@ module SPARQL; module Algebra
|
|
37
37
|
# @yieldreturn [void] ignored
|
38
38
|
# @return [RDF::Query::Solutions]
|
39
39
|
# the resulting solution sequence
|
40
|
-
# @see
|
41
|
-
def execute(queryable, options
|
40
|
+
# @see https://www.w3.org/TR/sparql11-query/#sparqlGroupAggregate
|
41
|
+
def execute(queryable, **options, &block)
|
42
42
|
debug(options) {"Group"}
|
43
43
|
exprlist = operands.first
|
44
44
|
query = operands.last
|
45
45
|
aggregates = operands.length == 3 ? operand(1) : []
|
46
|
-
solutions = queryable.query(query,
|
46
|
+
solutions = queryable.query(query, depth: options[:depth].to_i + 1, **options)
|
47
47
|
|
48
48
|
groups = solutions.group_by do |solution|
|
49
49
|
# Evaluate each exprlist operand to get groups where each key is a new solution
|
@@ -54,14 +54,14 @@ module SPARQL; module Algebra
|
|
54
54
|
if operand.is_a?(Array)
|
55
55
|
# Form is [variable, expression]
|
56
56
|
soln[operand.first] = operand.last.evaluate(solution,
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
queryable: queryable,
|
58
|
+
depth: options[:depth].to_i + 1,
|
59
|
+
**options)
|
60
60
|
else
|
61
61
|
# Form is variable
|
62
|
-
soln[operand] = operand.evaluate(solution,
|
63
|
-
|
64
|
-
|
62
|
+
soln[operand] = operand.evaluate(solution, queryable: queryable,
|
63
|
+
depth: options[:depth].to_i + 1,
|
64
|
+
**options)
|
65
65
|
end
|
66
66
|
rescue TypeError
|
67
67
|
# Ignore expression
|
@@ -76,7 +76,7 @@ module SPARQL; module Algebra
|
|
76
76
|
@solutions = RDF::Query::Solutions(groups.map do |group_soln, solns|
|
77
77
|
aggregates.each do |(var, aggregate)|
|
78
78
|
begin
|
79
|
-
group_soln[var] = aggregate.aggregate(solns, options)
|
79
|
+
group_soln[var] = aggregate.aggregate(solns, **options)
|
80
80
|
rescue TypeError
|
81
81
|
# Ignored in output
|
82
82
|
end
|
@@ -84,8 +84,18 @@ module SPARQL; module Algebra
|
|
84
84
|
group_soln
|
85
85
|
end)
|
86
86
|
|
87
|
-
#
|
88
|
-
@solutions
|
87
|
+
# If there exprlist is empty, make sure that's at least an empty solution
|
88
|
+
if @solutions.empty? && exprlist.empty?
|
89
|
+
soln = RDF::Query::Solution.new
|
90
|
+
aggregates.each do |(var, aggregate)|
|
91
|
+
begin
|
92
|
+
soln[var] = aggregate.aggregate([], **options)
|
93
|
+
rescue TypeError
|
94
|
+
# Ignored in output
|
95
|
+
end
|
96
|
+
end
|
97
|
+
@solutions << soln
|
98
|
+
end
|
89
99
|
|
90
100
|
debug(options) {"=>(solutions) #{@solutions.inspect}"}
|
91
101
|
@solutions.each(&block) if block_given?
|
@@ -112,16 +122,6 @@ module SPARQL; module Algebra
|
|
112
122
|
end
|
113
123
|
super
|
114
124
|
end
|
115
|
-
|
116
|
-
##
|
117
|
-
# Returns an optimized version of this query.
|
118
|
-
#
|
119
|
-
# TODO
|
120
|
-
#
|
121
|
-
# @return [Group] `self`
|
122
|
-
def optimize
|
123
|
-
self
|
124
|
-
end
|
125
125
|
end # Group
|
126
126
|
end # Operator
|
127
127
|
end; end # SPARQL::Algebra
|
@@ -9,11 +9,11 @@ module SPARQL; module Algebra
|
|
9
9
|
# (prefix ((: <http://www.example.org/>))
|
10
10
|
# (filter (|| (= ?g "1 22") (= ?g "22 1"))
|
11
11
|
# (project (?g)
|
12
|
-
# (extend ((?g
|
13
|
-
# (group () ((
|
14
|
-
# (bgp (triple
|
12
|
+
# (extend ((?g ??.0))
|
13
|
+
# (group () ((??.0 (group_concat ?o)))
|
14
|
+
# (bgp (triple ??.0 :p1 ?o)))))))
|
15
15
|
#
|
16
|
-
# @see
|
16
|
+
# @see https://www.w3.org/TR/sparql11-query/#defn_aggGroupConcat
|
17
17
|
class GroupConcat < Operator
|
18
18
|
include Aggregate
|
19
19
|
|
@@ -29,12 +29,12 @@ module SPARQL; module Algebra
|
|
29
29
|
# @return [RDF::Term]
|
30
30
|
# @raise [TypeError]
|
31
31
|
# @abstract
|
32
|
-
def aggregate(solutions = [], options
|
32
|
+
def aggregate(solutions = [], **options)
|
33
33
|
operands.shift if distinct = (operands.first == :distinct)
|
34
34
|
sep = operands.length == 2 ? operand(0).last : RDF::Literal(' ')
|
35
35
|
args_enum = solutions.map do |solution|
|
36
36
|
begin
|
37
|
-
operands.last.evaluate(solution,
|
37
|
+
operands.last.evaluate(solution, depth: options[:depth].to_i + 1, **options)
|
38
38
|
rescue TypeError
|
39
39
|
# Ignore errors
|
40
40
|
nil
|