sparql 3.1.6 → 3.2.1
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 +4 -4
- data/README.md +31 -22
- data/VERSION +1 -1
- data/bin/sparql +14 -4
- data/lib/sparql/algebra/aggregate.rb +1 -1
- data/lib/sparql/algebra/evaluatable.rb +4 -4
- data/lib/sparql/algebra/expression.rb +28 -3
- data/lib/sparql/algebra/extensions.rb +109 -45
- data/lib/sparql/algebra/operator/abs.rb +23 -3
- data/lib/sparql/algebra/operator/add.rb +21 -2
- data/lib/sparql/algebra/operator/alt.rb +26 -2
- data/lib/sparql/algebra/operator/and.rb +25 -3
- data/lib/sparql/algebra/operator/asc.rb +20 -1
- data/lib/sparql/algebra/operator/ask.rb +17 -1
- data/lib/sparql/algebra/operator/avg.rb +20 -2
- data/lib/sparql/algebra/operator/base.rb +18 -1
- data/lib/sparql/algebra/operator/bgp.rb +13 -1
- data/lib/sparql/algebra/operator/bnode.rb +34 -11
- data/lib/sparql/algebra/operator/bound.rb +22 -1
- data/lib/sparql/algebra/operator/ceil.rb +26 -3
- data/lib/sparql/algebra/operator/clear.rb +26 -2
- data/lib/sparql/algebra/operator/coalesce.rb +33 -11
- data/lib/sparql/algebra/operator/compare.rb +48 -40
- data/lib/sparql/algebra/operator/concat.rb +26 -2
- data/lib/sparql/algebra/operator/construct.rb +29 -6
- data/lib/sparql/algebra/operator/contains.rb +25 -3
- data/lib/sparql/algebra/operator/copy.rb +19 -2
- data/lib/sparql/algebra/operator/count.rb +53 -7
- data/lib/sparql/algebra/operator/create.rb +20 -2
- data/lib/sparql/algebra/operator/dataset.rb +27 -2
- data/lib/sparql/algebra/operator/datatype.rb +26 -7
- data/lib/sparql/algebra/operator/day.rb +24 -6
- data/lib/sparql/algebra/operator/delete.rb +29 -2
- data/lib/sparql/algebra/operator/delete_data.rb +23 -2
- data/lib/sparql/algebra/operator/delete_where.rb +24 -2
- data/lib/sparql/algebra/operator/desc.rb +20 -1
- data/lib/sparql/algebra/operator/describe.rb +27 -4
- data/lib/sparql/algebra/operator/distinct.rb +20 -3
- data/lib/sparql/algebra/operator/divide.rb +27 -3
- data/lib/sparql/algebra/operator/drop.rb +27 -3
- data/lib/sparql/algebra/operator/encode_for_uri.rb +23 -3
- data/lib/sparql/algebra/operator/equal.rb +13 -3
- data/lib/sparql/algebra/operator/exists.rb +28 -4
- data/lib/sparql/algebra/operator/exprlist.rb +15 -2
- data/lib/sparql/algebra/operator/extend.rb +64 -6
- data/lib/sparql/algebra/operator/filter.rb +27 -5
- data/lib/sparql/algebra/operator/floor.rb +26 -3
- data/lib/sparql/algebra/operator/function_call.rb +64 -0
- data/lib/sparql/algebra/operator/graph.rb +69 -6
- data/lib/sparql/algebra/operator/greater_than.rb +14 -4
- data/lib/sparql/algebra/operator/greater_than_or_equal.rb +14 -4
- data/lib/sparql/algebra/operator/group.rb +105 -8
- data/lib/sparql/algebra/operator/group_concat.rb +44 -8
- data/lib/sparql/algebra/operator/hours.rb +24 -6
- data/lib/sparql/algebra/operator/if.rb +20 -3
- data/lib/sparql/algebra/operator/in.rb +18 -1
- data/lib/sparql/algebra/operator/insert.rb +24 -2
- data/lib/sparql/algebra/operator/insert_data.rb +23 -2
- data/lib/sparql/algebra/operator/iri.rb +22 -5
- data/lib/sparql/algebra/operator/is_blank.rb +21 -4
- data/lib/sparql/algebra/operator/is_iri.rb +21 -4
- data/lib/sparql/algebra/operator/is_literal.rb +21 -4
- data/lib/sparql/algebra/operator/is_numeric.rb +23 -6
- data/lib/sparql/algebra/operator/is_triple.rb +33 -1
- data/lib/sparql/algebra/operator/join.rb +56 -1
- data/lib/sparql/algebra/operator/lang.rb +26 -1
- data/lib/sparql/algebra/operator/lang_matches.rb +23 -2
- data/lib/sparql/algebra/operator/lcase.rb +23 -3
- data/lib/sparql/algebra/operator/left_join.rb +42 -1
- data/lib/sparql/algebra/operator/less_than.rb +14 -4
- data/lib/sparql/algebra/operator/less_than_or_equal.rb +14 -4
- data/lib/sparql/algebra/operator/load.rb +25 -2
- data/lib/sparql/algebra/operator/max.rb +20 -2
- data/lib/sparql/algebra/operator/md5.rb +23 -6
- data/lib/sparql/algebra/operator/min.rb +22 -4
- data/lib/sparql/algebra/operator/minus.rb +65 -7
- data/lib/sparql/algebra/operator/minutes.rb +24 -6
- data/lib/sparql/algebra/operator/modify.rb +41 -5
- data/lib/sparql/algebra/operator/month.rb +24 -6
- data/lib/sparql/algebra/operator/move.rb +20 -2
- data/lib/sparql/algebra/operator/multiply.rb +27 -4
- data/lib/sparql/algebra/operator/negate.rb +24 -4
- data/lib/sparql/algebra/operator/not.rb +25 -4
- data/lib/sparql/algebra/operator/not_equal.rb +16 -1
- data/lib/sparql/algebra/operator/notexists.rb +30 -6
- data/lib/sparql/algebra/operator/notin.rb +20 -3
- data/lib/sparql/algebra/operator/notoneof.rb +21 -2
- data/lib/sparql/algebra/operator/now.rb +25 -6
- data/lib/sparql/algebra/operator/object.rb +33 -1
- data/lib/sparql/algebra/operator/or.rb +26 -3
- data/lib/sparql/algebra/operator/order.rb +71 -2
- data/lib/sparql/algebra/operator/path.rb +29 -2
- data/lib/sparql/algebra/operator/path_opt.rb +21 -2
- data/lib/sparql/algebra/operator/path_plus.rb +21 -2
- data/lib/sparql/algebra/operator/path_star.rb +20 -2
- data/lib/sparql/algebra/operator/plus.rb +43 -4
- data/lib/sparql/algebra/operator/predicate.rb +33 -1
- data/lib/sparql/algebra/operator/prefix.rb +24 -3
- data/lib/sparql/algebra/operator/project.rb +69 -5
- data/lib/sparql/algebra/operator/rand.rb +31 -3
- data/lib/sparql/algebra/operator/reduced.rb +20 -3
- data/lib/sparql/algebra/operator/regex.rb +27 -19
- data/lib/sparql/algebra/operator/replace.rb +27 -7
- data/lib/sparql/algebra/operator/reverse.rb +31 -2
- data/lib/sparql/algebra/operator/round.rb +26 -3
- data/lib/sparql/algebra/operator/same_term.rb +25 -7
- data/lib/sparql/algebra/operator/sample.rb +33 -9
- data/lib/sparql/algebra/operator/seconds.rb +24 -6
- data/lib/sparql/algebra/operator/seq.rb +20 -2
- data/lib/sparql/algebra/operator/sequence.rb +4 -11
- data/lib/sparql/algebra/operator/sha1.rb +19 -2
- data/lib/sparql/algebra/operator/sha256.rb +19 -2
- data/lib/sparql/algebra/operator/sha384.rb +19 -2
- data/lib/sparql/algebra/operator/sha512.rb +19 -2
- data/lib/sparql/algebra/operator/slice.rb +27 -5
- data/lib/sparql/algebra/operator/str.rb +22 -2
- data/lib/sparql/algebra/operator/strafter.rb +26 -3
- data/lib/sparql/algebra/operator/strbefore.rb +26 -3
- data/lib/sparql/algebra/operator/strdt.rb +23 -2
- data/lib/sparql/algebra/operator/strends.rb +26 -4
- data/lib/sparql/algebra/operator/strlang.rb +25 -7
- data/lib/sparql/algebra/operator/strlen.rb +24 -3
- data/lib/sparql/algebra/operator/strstarts.rb +26 -3
- data/lib/sparql/algebra/operator/struuid.rb +30 -10
- data/lib/sparql/algebra/operator/subject.rb +33 -1
- data/lib/sparql/algebra/operator/substr.rb +24 -3
- data/lib/sparql/algebra/operator/subtract.rb +29 -3
- data/lib/sparql/algebra/operator/sum.rb +25 -7
- data/lib/sparql/algebra/operator/table.rb +76 -4
- data/lib/sparql/algebra/operator/timezone.rb +24 -6
- data/lib/sparql/algebra/operator/tz.rb +23 -6
- data/lib/sparql/algebra/operator/ucase.rb +24 -3
- data/lib/sparql/algebra/operator/union.rb +29 -6
- data/lib/sparql/algebra/operator/update.rb +46 -4
- data/lib/sparql/algebra/operator/using.rb +49 -2
- data/lib/sparql/algebra/operator/uuid.rb +28 -9
- data/lib/sparql/algebra/operator/with.rb +38 -4
- data/lib/sparql/algebra/operator/year.rb +24 -6
- data/lib/sparql/algebra/operator.rb +135 -14
- data/lib/sparql/algebra/sxp_extensions.rb +3 -3
- data/lib/sparql/algebra.rb +20 -3
- data/lib/sparql/grammar/meta.rb +1103 -907
- data/lib/sparql/grammar/parser11.rb +63 -56
- metadata +43 -29
- data/lib/sparql/algebra/operator/triple.rb +0 -27
@@ -3,8 +3,18 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL relational `=` (equal) comparison operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# [114] RelationalExpression ::= NumericExpression ('=' NumericExpression)?
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
10
|
+
# PREFIX : <http://example.org/things#>
|
11
|
+
# SELECT ?x
|
12
|
+
# WHERE { ?x :p ?v . FILTER ( ?v = 1 ) }
|
13
|
+
#
|
14
|
+
# @example SSE
|
15
|
+
# (prefix
|
16
|
+
# ((xsd: <http://www.w3.org/2001/XMLSchema#>) (: <http://example.org/things#>))
|
17
|
+
# (project (?x) (filter (= ?v 1) (bgp (triple ?x :p ?v)))))
|
8
18
|
#
|
9
19
|
# @see https://www.w3.org/TR/sparql11-query/#OperatorMapping
|
10
20
|
# @see https://www.w3.org/TR/sparql11-query/#func-RDFterm-equal
|
@@ -26,7 +36,7 @@ module SPARQL; module Algebra
|
|
26
36
|
# @raise [TypeError] if either operand is not an RDF term or operands are not comperable
|
27
37
|
#
|
28
38
|
# @see RDF::Term#==
|
29
|
-
def apply(term1, term2)
|
39
|
+
def apply(term1, term2, **options)
|
30
40
|
term1 = term1.dup.extend(RDF::TypeCheck)
|
31
41
|
term2 = term2.dup.extend(RDF::TypeCheck)
|
32
42
|
RDF::Literal(term1 == term2)
|
@@ -5,10 +5,21 @@ module SPARQL; module Algebra
|
|
5
5
|
#
|
6
6
|
# There is a filter operator EXISTS that takes a graph pattern. EXISTS returns `true`/`false` depending on whether the pattern matches the dataset given the bindings in the current group graph pattern, the dataset and the active graph at this point in the query evaluation. No additional binding of variables occurs. The `NOT EXISTS` form translates into `fn:not(EXISTS{...})`.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
8
|
+
# [125] ExistsFunc ::= 'EXISTS' GroupGraphPattern
|
9
|
+
#
|
10
|
+
# @example SPARQL Grammar
|
11
|
+
# PREFIX : <http://example/>
|
12
|
+
# SELECT *
|
13
|
+
# WHERE {
|
14
|
+
# ?set a :Set .
|
15
|
+
# FILTER EXISTS { ?set :member 9 }
|
16
|
+
# }
|
17
|
+
#
|
18
|
+
# @example SSE
|
19
|
+
# (prefix ((: <http://example/>))
|
20
|
+
# (filter
|
21
|
+
# (exists (bgp (triple ?set :member 9)))
|
22
|
+
# (bgp (triple ?set a :Set))))
|
12
23
|
#
|
13
24
|
# @see https://www.w3.org/TR/sparql11-query/#func-filter-exists
|
14
25
|
class Exists < Operator::Unary
|
@@ -32,6 +43,19 @@ module SPARQL; module Algebra
|
|
32
43
|
depth: options[:depth].to_i + 1,
|
33
44
|
**options).empty?
|
34
45
|
end
|
46
|
+
|
47
|
+
##
|
48
|
+
#
|
49
|
+
# Returns a partial SPARQL grammar for this operator.
|
50
|
+
#
|
51
|
+
# @param [Boolean] top_level (true)
|
52
|
+
# Treat this as a top-level, generating SELECT ... WHERE {}
|
53
|
+
# @return [String]
|
54
|
+
def to_sparql(top_level: true, **options)
|
55
|
+
"EXISTS {\n" +
|
56
|
+
operands.last.to_sparql(top_level: false, **options) +
|
57
|
+
"\n}"
|
58
|
+
end
|
35
59
|
end # Exists
|
36
60
|
end # Operator
|
37
61
|
end; end # SPARQL::Algebra
|
@@ -5,8 +5,21 @@ module SPARQL; module Algebra
|
|
5
5
|
#
|
6
6
|
# Used for filters with more than one expression.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# [72] ExpressionList ::= NIL | '(' Expression ( ',' Expression )* ')'
|
9
|
+
#
|
10
|
+
# @example SPARQL Grammar
|
11
|
+
# PREFIX : <http://example.org/>
|
12
|
+
#
|
13
|
+
# SELECT ?v ?w
|
14
|
+
# {
|
15
|
+
# FILTER (?v = 2)
|
16
|
+
# FILTER (?w = 3)
|
17
|
+
# ?s :p ?v .
|
18
|
+
# ?s :q ?w .
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# @example SSE
|
22
|
+
# (prefix ((: <http://example.org/>))
|
10
23
|
# (project (?v ?w)
|
11
24
|
# (filter (exprlist (= ?v 2) (= ?w 3))
|
12
25
|
# (bgp
|
@@ -5,11 +5,52 @@ module SPARQL; module Algebra
|
|
5
5
|
#
|
6
6
|
# Extends a solution
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
8
|
+
# [60] Bind ::= 'BIND' '(' Expression 'AS' Var ')'
|
9
|
+
#
|
10
|
+
# @example SPARQL Grammar
|
11
|
+
# SELECT ?z
|
12
|
+
# {
|
13
|
+
# ?x <http://example.org/p> ?o
|
14
|
+
# BIND(?o+10 AS ?z)
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
# @example SSE
|
18
|
+
# (project (?z)
|
19
|
+
# (extend ((?z (+ ?o 10)))
|
20
|
+
# (bgp (triple ?x <http://example.org/p> ?o))))
|
21
|
+
#
|
22
|
+
# @example SPARQL Grammar (cast as boolean)
|
23
|
+
# PREFIX : <http://example.org/>
|
24
|
+
# PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
25
|
+
# PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
26
|
+
# SELECT ?a ?v (xsd:boolean(?v) AS ?boolean)
|
27
|
+
# WHERE { ?a :p ?v . }
|
28
|
+
#
|
29
|
+
# @example SSE (cast as boolean)
|
30
|
+
# (prefix ((: <http://example.org/>)
|
31
|
+
# (rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>)
|
32
|
+
# (xsd: <http://www.w3.org/2001/XMLSchema#>))
|
33
|
+
# (project (?a ?v ?boolean)
|
34
|
+
# (extend ((?boolean (xsd:boolean ?v)))
|
35
|
+
# (bgp (triple ?a :p ?v)))))
|
36
|
+
#
|
37
|
+
# @example SPARQL Grammar (inner bind)
|
38
|
+
# PREFIX : <http://example.org/>
|
39
|
+
#
|
40
|
+
# SELECT ?z ?s1
|
41
|
+
# {
|
42
|
+
# ?s ?p ?o .
|
43
|
+
# BIND(?o+1 AS ?z)
|
44
|
+
# ?s1 ?p1 ?z
|
45
|
+
# }
|
46
|
+
#
|
47
|
+
# @example SSE (inner bind)
|
48
|
+
# (prefix ((: <http://example.org/>))
|
49
|
+
# (project (?z ?s1)
|
50
|
+
# (join
|
51
|
+
# (extend ((?z (+ ?o 1)))
|
52
|
+
# (bgp (triple ?s ?p ?o)))
|
53
|
+
# (bgp (triple ?s1 ?p1 ?z)))))
|
13
54
|
#
|
14
55
|
# @see https://www.w3.org/TR/sparql11-query/#evaluation
|
15
56
|
class Extend < Operator::Binary
|
@@ -73,6 +114,23 @@ module SPARQL; module Algebra
|
|
73
114
|
end
|
74
115
|
super
|
75
116
|
end
|
76
|
-
|
117
|
+
|
118
|
+
##
|
119
|
+
#
|
120
|
+
# Returns a partial SPARQL grammar for this operator.
|
121
|
+
#
|
122
|
+
# Extracts bindings.
|
123
|
+
#
|
124
|
+
# @return [String]
|
125
|
+
def to_sparql(**options)
|
126
|
+
extensions = operands.first.inject({}) do |memo, (as, expression)|
|
127
|
+
memo.merge(as => expression)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Merge any inherited extensions from options
|
131
|
+
extensions = options.delete(:extensions).merge(extensions) if options.key?(:extensions)
|
132
|
+
operands.last.to_sparql(extensions: extensions, **options)
|
133
|
+
end
|
134
|
+
end # Extend
|
77
135
|
end # Operator
|
78
136
|
end; end # SPARQL::Algebra
|
@@ -3,11 +3,19 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL GraphPattern `filter` operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
6
|
+
# [68] Filter ::= 'FILTER' Constraint
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# SELECT ?v
|
10
|
+
# {
|
11
|
+
# ?s <http://example/p> ?v
|
12
|
+
# FILTER(?v = 2)
|
13
|
+
# }
|
14
|
+
#
|
15
|
+
# @example SSE
|
16
|
+
# (project (?v)
|
17
|
+
# (filter (= ?v 2)
|
18
|
+
# (bgp (triple ?s <http://example/p> ?v))))
|
11
19
|
#
|
12
20
|
# @see https://www.w3.org/TR/sparql11-query/#evaluation
|
13
21
|
class Filter < Operator::Binary
|
@@ -69,6 +77,20 @@ module SPARQL; module Algebra
|
|
69
77
|
end
|
70
78
|
self
|
71
79
|
end
|
80
|
+
|
81
|
+
##
|
82
|
+
#
|
83
|
+
# Returns a partial SPARQL grammar for this operator.
|
84
|
+
#
|
85
|
+
# Provides filters to descendant query.
|
86
|
+
#
|
87
|
+
# If filter operation is an Exprlist, then separate into multiple filter ops.
|
88
|
+
#
|
89
|
+
# @return [String]
|
90
|
+
def to_sparql(**options)
|
91
|
+
filter_ops = operands.first.is_a?(Operator::Exprlist) ? operands.first.operands : [operands.first]
|
92
|
+
str = operands.last.to_sparql(filter_ops: filter_ops, **options)
|
93
|
+
end
|
72
94
|
end # Filter
|
73
95
|
end # Operator
|
74
96
|
end; end # SPARQL::Algebra
|
@@ -3,8 +3,22 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL logical `floor` operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# [121] BuiltInCall ::= ... 'FLOOR' '(' Expression ')'
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX : <http://example.org/>
|
10
|
+
# PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
11
|
+
# SELECT ?s ?num (FLOOR(?num) AS ?floor) WHERE {
|
12
|
+
# ?s :num ?num
|
13
|
+
# }
|
14
|
+
#
|
15
|
+
# @example SSE
|
16
|
+
# (prefix
|
17
|
+
# ((: <http://example.org/>)
|
18
|
+
# (xsd: <http://www.w3.org/2001/XMLSchema#>))
|
19
|
+
# (project (?s ?num ?floor)
|
20
|
+
# (extend ((?floor (floor ?num)))
|
21
|
+
# (bgp (triple ?s :num ?num)))))
|
8
22
|
#
|
9
23
|
# @see https://www.w3.org/TR/sparql11-query/#func-floor
|
10
24
|
# @see https://www.w3.org/TR/xpath-functions/#func-floor
|
@@ -24,12 +38,21 @@ module SPARQL; module Algebra
|
|
24
38
|
# the operand
|
25
39
|
# @return [RDF::Literal] literal of same type
|
26
40
|
# @raise [TypeError] if the operand is not a numeric value
|
27
|
-
def apply(operand)
|
41
|
+
def apply(operand, **options)
|
28
42
|
case operand
|
29
43
|
when RDF::Literal::Numeric then operand.floor
|
30
44
|
else raise TypeError, "expected an RDF::Literal::Numeric, but got #{operand.inspect}"
|
31
45
|
end
|
32
46
|
end
|
47
|
+
|
48
|
+
##
|
49
|
+
#
|
50
|
+
# Returns a partial SPARQL grammar for this operator.
|
51
|
+
#
|
52
|
+
# @return [String]
|
53
|
+
def to_sparql(**options)
|
54
|
+
"FLOOR(#{operands.to_sparql(**options)})"
|
55
|
+
end
|
33
56
|
end # Floor
|
34
57
|
end # Operator
|
35
58
|
end; end # SPARQL::Algebra
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
module SPARQL; module Algebra
|
3
|
+
class Operator
|
4
|
+
##
|
5
|
+
# The SPARQL `function_call` operator.
|
6
|
+
#
|
7
|
+
# [70] FunctionCall ::= iri ArgList
|
8
|
+
#
|
9
|
+
# @example SPARQL Grammar
|
10
|
+
# PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
11
|
+
# SELECT *
|
12
|
+
# WHERE { ?s ?p ?o . FILTER xsd:integer(?o) }
|
13
|
+
#
|
14
|
+
# @example SSE
|
15
|
+
# (prefix
|
16
|
+
# ((xsd: <http://www.w3.org/2001/XMLSchema#>))
|
17
|
+
# (filter (xsd:integer ?o)
|
18
|
+
# (bgp (triple ?s ?p ?o))))
|
19
|
+
#
|
20
|
+
# @see https://www.w3.org/TR/sparql11-query/#funcex-regex
|
21
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-matches
|
22
|
+
class FunctionCall < Operator
|
23
|
+
include Evaluatable
|
24
|
+
|
25
|
+
NAME = :function_call
|
26
|
+
|
27
|
+
##
|
28
|
+
# Invokes the function with the passed arguments.
|
29
|
+
#
|
30
|
+
# @param [RDF::IRI] iri
|
31
|
+
# Identifies the function
|
32
|
+
# @param [Array<RDF::Term>] args
|
33
|
+
# @return [RDF::Term]
|
34
|
+
def apply(iri, *args, **options)
|
35
|
+
args = RDF.nil == args.last ? args[0..-2] : args
|
36
|
+
SPARQL::Algebra::Expression.extension(iri, *args, **options)
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Returns the SPARQL S-Expression (SSE) representation of this expression.
|
41
|
+
#
|
42
|
+
# Remove the optional argument.
|
43
|
+
#
|
44
|
+
# @return [Array] `self`
|
45
|
+
# @see https://openjena.org/wiki/SSE
|
46
|
+
def to_sxp_bin
|
47
|
+
@operands.map(&:to_sxp_bin)
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
#
|
52
|
+
# Returns a partial SPARQL grammar for this operator.
|
53
|
+
#
|
54
|
+
# @return [String]
|
55
|
+
def to_sparql(**options)
|
56
|
+
iri, args = operands
|
57
|
+
iri.to_sparql(**options) +
|
58
|
+
'(' +
|
59
|
+
args.to_sparql(delimiter: ', ', **options) +
|
60
|
+
')'
|
61
|
+
end
|
62
|
+
end # FunctionCall
|
63
|
+
end # Operator
|
64
|
+
end; end # SPARQL::Algebra
|
@@ -5,15 +5,63 @@ module SPARQL; module Algebra
|
|
5
5
|
#
|
6
6
|
# This is a wrapper to add a `graph_name` to the query, or an array of statements.
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# [58] GraphGraphPattern ::= 'GRAPH' VarOrIri GroupGraphPattern
|
9
|
+
#
|
10
|
+
# @example SPARQL Grammar (query)
|
11
|
+
# PREFIX : <http://example/>
|
12
|
+
# SELECT * {
|
13
|
+
# GRAPH ?g { ?s ?p ?o }
|
14
|
+
# }
|
15
|
+
#
|
16
|
+
# @example SSE
|
9
17
|
# (prefix ((: <http://example/>))
|
10
|
-
#
|
11
|
-
#
|
18
|
+
# (graph ?g
|
19
|
+
# (bgp (triple ?s ?p ?o))))
|
20
|
+
#
|
21
|
+
# @example SPARQL Grammar (named set of statements)
|
22
|
+
# PREFIX : <http://example/>
|
23
|
+
# SELECT * {
|
24
|
+
# GRAPH :g { :s :p :o }
|
25
|
+
# }
|
12
26
|
#
|
13
|
-
# @example named set of statements
|
27
|
+
# @example SSE (named set of statements)
|
14
28
|
# (prefix ((: <http://example/>))
|
15
|
-
#
|
16
|
-
#
|
29
|
+
# (graph :g
|
30
|
+
# (bgp (triple :s :p :o))))
|
31
|
+
#
|
32
|
+
# @example SPARQL Grammar (syntax-graph-05.rq)
|
33
|
+
# PREFIX : <http://example.org/>
|
34
|
+
# SELECT *
|
35
|
+
# WHERE
|
36
|
+
# {
|
37
|
+
# :x :p :z
|
38
|
+
# GRAPH ?g { :x :b ?a . GRAPH ?g2 { :x :p ?x } }
|
39
|
+
# }
|
40
|
+
#
|
41
|
+
# @example SSE (syntax-graph-05.rq)
|
42
|
+
# (prefix ((: <http://example.org/>))
|
43
|
+
# (join
|
44
|
+
# (bgp (triple :x :p :z))
|
45
|
+
# (graph ?g
|
46
|
+
# (join
|
47
|
+
# (bgp (triple :x :b ?a))
|
48
|
+
# (graph ?g2
|
49
|
+
# (bgp (triple :x :p ?x)))))))
|
50
|
+
#
|
51
|
+
# @example SPARQL Grammar (pp06.rq)
|
52
|
+
# prefix ex: <http://www.example.org/schema#>
|
53
|
+
# prefix in: <http://www.example.org/instance#>
|
54
|
+
#
|
55
|
+
# select ?x where {
|
56
|
+
# graph ?g {in:a ex:p1/ex:p2 ?x}
|
57
|
+
# }
|
58
|
+
#
|
59
|
+
# @example SSE (syntax-graph-05.rq)
|
60
|
+
# (prefix ((ex: <http://www.example.org/schema#>)
|
61
|
+
# (in: <http://www.example.org/instance#>))
|
62
|
+
# (project (?x)
|
63
|
+
# (graph ?g
|
64
|
+
# (path in:a (seq ex:p1 ex:p2) ?x))))
|
17
65
|
#
|
18
66
|
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
19
67
|
class Graph < Operator::Binary
|
@@ -76,6 +124,21 @@ module SPARQL; module Algebra
|
|
76
124
|
def rewrite(&block)
|
77
125
|
self
|
78
126
|
end
|
127
|
+
|
128
|
+
##
|
129
|
+
#
|
130
|
+
# Returns a partial SPARQL grammar for this operator.
|
131
|
+
#
|
132
|
+
# @param [Boolean] top_level (true)
|
133
|
+
# Treat this as a top-level, generating SELECT ... WHERE {}
|
134
|
+
# @return [String]
|
135
|
+
def to_sparql(top_level: true, **options)
|
136
|
+
query = operands.last.to_sparql(top_level: false, **options)
|
137
|
+
# Paths don't automatically get braces.
|
138
|
+
query = "{\n#{query}\n}" unless query.start_with?('{')
|
139
|
+
str = "GRAPH #{operands.first.to_sparql(**options)} " + query
|
140
|
+
top_level ? Operator.to_sparql(str, **options) : str
|
141
|
+
end
|
79
142
|
end # Graph
|
80
143
|
end # Operator
|
81
144
|
end; end # SPARQL::Algebra
|
@@ -3,8 +3,18 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL relational `>` (greater than) comparison operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# [114] RelationalExpression ::= NumericExpression ('>' NumericExpression)?
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
10
|
+
# PREFIX : <http://example.org/things#>
|
11
|
+
# SELECT ?x
|
12
|
+
# WHERE { ?x :p ?v . FILTER ( ?v > 1 ) }
|
13
|
+
#
|
14
|
+
# @example SSE
|
15
|
+
# (prefix
|
16
|
+
# ((xsd: <http://www.w3.org/2001/XMLSchema#>) (: <http://example.org/things#>))
|
17
|
+
# (project (?x) (filter (> ?v 1) (bgp (triple ?x :p ?v)))))
|
8
18
|
#
|
9
19
|
# @see https://www.w3.org/TR/sparql11-query/#OperatorMapping
|
10
20
|
# @see https://www.w3.org/TR/xpath-functions/#func-compare
|
@@ -24,8 +34,8 @@ module SPARQL; module Algebra
|
|
24
34
|
# a literal
|
25
35
|
# @return [RDF::Literal::Boolean] `true` or `false`
|
26
36
|
# @raise [TypeError] if either operand is not a literal
|
27
|
-
def apply(left, right)
|
28
|
-
super
|
37
|
+
def apply(left, right, **options)
|
38
|
+
RDF::Literal(super == RDF::Literal(1))
|
29
39
|
end
|
30
40
|
end # GreaterThan
|
31
41
|
end # Operator
|
@@ -4,8 +4,18 @@ module SPARQL; module Algebra
|
|
4
4
|
# The SPARQL relational `>=` (greater than or equal) comparison
|
5
5
|
# operator.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
7
|
+
# [114] RelationalExpression ::= NumericExpression ('>=' NumericExpression)?
|
8
|
+
#
|
9
|
+
# @example SPARQL Grammar
|
10
|
+
# PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
11
|
+
# PREFIX : <http://example.org/things#>
|
12
|
+
# SELECT ?x
|
13
|
+
# WHERE { ?x :p ?v . FILTER ( ?v >= 1 ) }
|
14
|
+
#
|
15
|
+
# @example SSE
|
16
|
+
# (prefix
|
17
|
+
# ((xsd: <http://www.w3.org/2001/XMLSchema#>) (: <http://example.org/things#>))
|
18
|
+
# (project (?x) (filter (>= ?v 1) (bgp (triple ?x :p ?v)))))
|
9
19
|
#
|
10
20
|
# @see https://www.w3.org/TR/sparql11-query/#OperatorMapping
|
11
21
|
# @see https://www.w3.org/TR/xpath-functions/#func-compare
|
@@ -25,8 +35,8 @@ module SPARQL; module Algebra
|
|
25
35
|
# a literal
|
26
36
|
# @return [RDF::Literal::Boolean] `true` or `false`
|
27
37
|
# @raise [TypeError] if either operand is not a literal
|
28
|
-
def apply(left, right)
|
29
|
-
super
|
38
|
+
def apply(left, right, **options)
|
39
|
+
RDF::Literal(super >= RDF::Literal(0))
|
30
40
|
end
|
31
41
|
end # GreaterThanOrEqual
|
32
42
|
end # Operator
|
@@ -8,14 +8,53 @@ module SPARQL; module Algebra
|
|
8
8
|
# query to be grouped. If three operands are provided,
|
9
9
|
# the second is an array of temporary bindings.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
11
|
+
# [19] GroupClause ::= 'GROUP' 'BY' GroupCondition+
|
12
|
+
#
|
13
|
+
# @example SPARQL Grammar
|
14
|
+
# PREFIX : <http://www.example.org>
|
15
|
+
#
|
16
|
+
# SELECT ?P (COUNT(?O) AS ?C)
|
17
|
+
# WHERE { ?S ?P ?O }
|
18
|
+
# GROUP BY ?P
|
19
|
+
#
|
20
|
+
# @example SSE
|
21
|
+
# (prefix
|
22
|
+
# ((: <http://www.example.org>))
|
23
|
+
# (project (?P ?C)
|
24
|
+
# (extend ((?C ??.0))
|
25
|
+
# (group (?P) ((??.0 (count ?O)))
|
26
|
+
# (bgp (triple ?S ?P ?O))))))
|
27
|
+
#
|
28
|
+
# @example SPARQL Grammar (HAVING aggregate)
|
29
|
+
# PREFIX : <http://www.example.org/>
|
30
|
+
# SELECT ?s (AVG(?o) AS ?avg)
|
31
|
+
# WHERE { ?s ?p ?o }
|
32
|
+
# GROUP BY ?s
|
33
|
+
# HAVING (AVG(?o) <= 2.0)
|
34
|
+
#
|
35
|
+
# @example SSE (HAVING aggregate)
|
36
|
+
# (prefix ((: <http://www.example.org/>))
|
37
|
+
# (project (?s ?avg)
|
38
|
+
# (filter (<= ??.0 2.0)
|
39
|
+
# (extend ((?avg ??.0))
|
40
|
+
# (group (?s) ((??.0 (avg ?o)))
|
41
|
+
# (bgp (triple ?s ?p ?o)))))) )
|
42
|
+
#
|
43
|
+
# @example SPARQL Grammar (non-triveal filters)
|
44
|
+
# PREFIX : <http://example.com/data/#>
|
45
|
+
# SELECT ?g (AVG(?p) AS ?avg) ((MIN(?p) + MAX(?p)) / 2 AS ?c)
|
46
|
+
# WHERE { ?g :p ?p . }
|
47
|
+
# GROUP BY ?g
|
48
|
+
#
|
49
|
+
# @example SSE (non-triveal filters)
|
50
|
+
# (prefix ((: <http://example.com/data/#>))
|
51
|
+
# (project (?g ?avg ?c)
|
52
|
+
# (extend ((?avg ??.0) (?c (/ (+ ??.1 ??.2) 2)))
|
53
|
+
# (group (?g)
|
54
|
+
# ((??.0 (avg ?p))
|
55
|
+
# (??.1 (min ?p))
|
56
|
+
# (??.2 (max ?p)))
|
57
|
+
# (bgp (triple ?g :p ?p)))) ))
|
19
58
|
#
|
20
59
|
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
21
60
|
class Group < Operator
|
@@ -122,6 +161,64 @@ module SPARQL; module Algebra
|
|
122
161
|
end
|
123
162
|
super
|
124
163
|
end
|
164
|
+
|
165
|
+
##
|
166
|
+
#
|
167
|
+
# Returns a partial SPARQL grammar for this operator.
|
168
|
+
#
|
169
|
+
# @param [Hash{Symbol => Operator}] extensions
|
170
|
+
# Variable bindings
|
171
|
+
# @param [Array<Operator>] filter_ops ([])
|
172
|
+
# Filter Operations
|
173
|
+
# @return [String]
|
174
|
+
def to_sparql(extensions: {}, filter_ops: [], **options)
|
175
|
+
having_ops = []
|
176
|
+
if operands.length > 2
|
177
|
+
temp_bindings = operands[1].inject({}) {|memo, (var, op)| memo.merge(var => op)}
|
178
|
+
# Replace extensions from temporary bindings
|
179
|
+
temp_bindings.each do |var, op|
|
180
|
+
# Update extensions using a temporarily bound variable with its binding
|
181
|
+
extensions = extensions.inject({}) do |memo, (ext_var, ext_op)|
|
182
|
+
if ext_op.is_a?(Operator)
|
183
|
+
# Try to recursivley replace variable within operator
|
184
|
+
new_op = ext_op.deep_dup.rewrite do |operand|
|
185
|
+
if operand.is_a?(Variable) && operand.to_sym == var.to_sym
|
186
|
+
op.dup
|
187
|
+
else
|
188
|
+
operand
|
189
|
+
end
|
190
|
+
end
|
191
|
+
memo.merge(ext_var => new_op)
|
192
|
+
elsif ext_op.is_a?(Variable) && ext_op.to_sym == var.to_sym
|
193
|
+
memo.merge(ext_var => op)
|
194
|
+
else
|
195
|
+
# Doesn't match this variable, so don't change
|
196
|
+
memo.merge(ext_var => ext_op)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Filter ops using temporary bindinds are used for HAVING clauses
|
201
|
+
filter_ops.each do |fop|
|
202
|
+
having_ops << fop if fop.descendants.include?(var) && !having_ops.include?(fop)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# If used in a HAVING clause, it's not also a filter
|
207
|
+
filter_ops -= having_ops
|
208
|
+
|
209
|
+
# Replace each operand in having using var with it's corresponding operation
|
210
|
+
having_ops = having_ops.map do |op|
|
211
|
+
op.dup.rewrite do |operand|
|
212
|
+
# Rewrite based on temporary bindings
|
213
|
+
temp_bindings.fetch(operand, operand)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
operands.last.to_sparql(extensions: extensions,
|
218
|
+
group_ops: operands.first,
|
219
|
+
having_ops: having_ops,
|
220
|
+
**options)
|
221
|
+
end
|
125
222
|
end # Group
|
126
223
|
end # Operator
|
127
224
|
end; end # SPARQL::Algebra
|