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 Property Path `path*` (ZeroOrMorePath) operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# [91] PathElt ::= PathPrimary PathMod?
|
7
|
+
# [93] PathMod ::= '*' | '?' | '+'
|
8
|
+
|
9
|
+
# @example SPARQL Grammar
|
10
|
+
# PREFIX : <http://example/>
|
11
|
+
# SELECT * WHERE {
|
12
|
+
# :a :p* ?z
|
13
|
+
# }
|
14
|
+
#
|
15
|
+
# @example SSE
|
16
|
+
# (prefix ((: <http://example/>))
|
17
|
+
# (path :a (path* :p) ?z))
|
8
18
|
#
|
9
19
|
# @see https://www.w3.org/TR/sparql11-query/#defn_evalPP_ZeroOrMorePath
|
10
20
|
class PathStar < Operator::Unary
|
@@ -37,6 +47,14 @@ module SPARQL; module Algebra
|
|
37
47
|
query = PathOpt.new(PathPlus.new(*operands))
|
38
48
|
query.execute(queryable, depth: options[:depth].to_i + 1, **options, &block)
|
39
49
|
end
|
50
|
+
##
|
51
|
+
#
|
52
|
+
# Returns a partial SPARQL grammar for this operator.
|
53
|
+
#
|
54
|
+
# @return [String]
|
55
|
+
def to_sparql(**options)
|
56
|
+
"(#{operands.first.to_sparql(**options)})*"
|
57
|
+
end
|
40
58
|
end # PathStar
|
41
59
|
end # Operator
|
42
60
|
end; end # SPARQL::Algebra
|
@@ -3,9 +3,39 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL numeric binary/unary `+` operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# [118] UnaryExpression ::= ... | '+' PrimaryExpression
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX : <http://example.org/>
|
10
|
+
# SELECT ?s WHERE {
|
11
|
+
# ?s :p ?o .
|
12
|
+
# FILTER(-?o = +3) .
|
13
|
+
# }
|
14
|
+
#
|
15
|
+
# @example SSE
|
16
|
+
# (prefix ((: <http://example.org/>))
|
17
|
+
# (project (?s)
|
18
|
+
# (filter (= (- ?o) +3)
|
19
|
+
# (bgp (triple ?s :p ?o)))))
|
20
|
+
#
|
21
|
+
# [116] AdditiveExpression ::= MultiplicativeExpression ( '+' MultiplicativeExpression )?
|
22
|
+
#
|
23
|
+
# @example SPARQL Grammar
|
24
|
+
# PREFIX : <http://example.org/>
|
25
|
+
# SELECT ?s WHERE {
|
26
|
+
# ?s :p ?o .
|
27
|
+
# ?s2 :p ?o2 .
|
28
|
+
# FILTER(?o + ?o2 = 3) .
|
29
|
+
# }
|
30
|
+
#
|
31
|
+
# @example SSE
|
32
|
+
# (prefix
|
33
|
+
# ((: <http://example.org/>))
|
34
|
+
# (project (?s)
|
35
|
+
# (filter (= (+ ?o ?o2) 3)
|
36
|
+
# (bgp
|
37
|
+
# (triple ?s :p ?o)
|
38
|
+
# (triple ?s2 :p ?o2)))))
|
9
39
|
#
|
10
40
|
# @see https://www.w3.org/TR/xpath-functions/#func-numeric-unary-plus
|
11
41
|
# @see https://www.w3.org/TR/xpath-functions/#func-numeric-add
|
@@ -23,7 +53,7 @@ module SPARQL; module Algebra
|
|
23
53
|
# a numeric literal
|
24
54
|
# @return [RDF::Literal::Numeric]
|
25
55
|
# @raise [TypeError] if either operand is not a numeric literal
|
26
|
-
def apply(left, right = nil)
|
56
|
+
def apply(left, right = nil, **options)
|
27
57
|
case
|
28
58
|
when left.is_a?(RDF::Literal::Numeric) && right.is_a?(RDF::Literal::Numeric)
|
29
59
|
left + right
|
@@ -32,6 +62,15 @@ module SPARQL; module Algebra
|
|
32
62
|
else raise TypeError, "expected two RDF::Literal::Numeric operands, but got #{left.inspect} and #{right.inspect}"
|
33
63
|
end
|
34
64
|
end
|
65
|
+
|
66
|
+
##
|
67
|
+
#
|
68
|
+
# Returns a partial SPARQL grammar for this operator.
|
69
|
+
#
|
70
|
+
# @return [String]
|
71
|
+
def to_sparql(**options)
|
72
|
+
"(#{operands.first.to_sparql(**options)} + #{operands.last.to_sparql(**options)})"
|
73
|
+
end
|
35
74
|
end # Plus
|
36
75
|
end # Operator
|
37
76
|
end; end # SPARQL::Algebra
|
@@ -5,6 +5,29 @@ module SPARQL; module Algebra
|
|
5
5
|
#
|
6
6
|
# If triple is an RDF-star triple, the function returns the predicate of this triple. Passing anything other than an RDF-star triple is an error.
|
7
7
|
#
|
8
|
+
# [121] BuiltInCall ::= ... | 'PREDICATE' '(' Expression ')'
|
9
|
+
#
|
10
|
+
# @example SPARQL Grammar
|
11
|
+
# PREFIX : <http://example.com/ns#>
|
12
|
+
# SELECT * {
|
13
|
+
# ?t :source :g
|
14
|
+
# FILTER(isTriple(?t))
|
15
|
+
# FILTER(SUBJECT(?t) = :s)
|
16
|
+
# FILTER(PREDICATE(?t) = :p)
|
17
|
+
# FILTER(OBJECT(?t) = :o)
|
18
|
+
# }
|
19
|
+
#
|
20
|
+
# @example SSE
|
21
|
+
# (prefix
|
22
|
+
# ((: <http://example.com/ns#>))
|
23
|
+
# (filter
|
24
|
+
# (exprlist
|
25
|
+
# (isTRIPLE ?t)
|
26
|
+
# (= (subject ?t) :s)
|
27
|
+
# (= (predicate ?t) :p)
|
28
|
+
# (= (object ?t) :o))
|
29
|
+
# (bgp (triple ?t :source :g))) )
|
30
|
+
#
|
8
31
|
# @see https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#predicate
|
9
32
|
class Predicate < Operator::Unary
|
10
33
|
include Evaluatable
|
@@ -18,10 +41,19 @@ module SPARQL; module Algebra
|
|
18
41
|
# the operand
|
19
42
|
# @return [RDF::Literal]
|
20
43
|
# @raise [TypeError] if the operand is not a statement
|
21
|
-
def apply(operand)
|
44
|
+
def apply(operand, **options)
|
22
45
|
raise TypeError, "expected an RDF::Statement, but got #{operand.inspect}" unless operand.is_a?(RDF::Statement)
|
23
46
|
operand.predicate
|
24
47
|
end
|
48
|
+
|
49
|
+
##
|
50
|
+
#
|
51
|
+
# Returns a partial SPARQL grammar for this operator.
|
52
|
+
#
|
53
|
+
# @return [String]
|
54
|
+
def to_sparql(**options)
|
55
|
+
"PREDICATE(" + operands.last.to_sparql(**options) + ")"
|
56
|
+
end
|
25
57
|
end # Predicate
|
26
58
|
end # Operator
|
27
59
|
end; end # SPARQL::Algebra
|
@@ -3,10 +3,15 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL GraphPattern `prefix` operator.
|
5
5
|
#
|
6
|
-
#
|
6
|
+
# [6] PrefixDecl ::= 'PREFIX' PNAME_NS IRIREF
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX : <http://example/>
|
10
|
+
# SELECT * { :s :p :o }
|
11
|
+
#
|
12
|
+
# @example SSE
|
7
13
|
# (prefix ((: <http://example/>))
|
8
|
-
#
|
9
|
-
# (bgp (triple ?s ?p ?o))))
|
14
|
+
# (bgp (triple :s :p :o)))
|
10
15
|
#
|
11
16
|
# @see https://www.w3.org/TR/sparql11-query/#QSynIRI
|
12
17
|
class Prefix < Binary
|
@@ -65,6 +70,22 @@ module SPARQL; module Algebra
|
|
65
70
|
def query_yields_statements?
|
66
71
|
operands.last.query_yields_statements?
|
67
72
|
end
|
73
|
+
|
74
|
+
##
|
75
|
+
#
|
76
|
+
# Returns a partial SPARQL grammar for this term.
|
77
|
+
#
|
78
|
+
# @return [String]
|
79
|
+
def to_sparql(**options)
|
80
|
+
prefixes = {}
|
81
|
+
str = operands.first.map do |(pfx, sfx)|
|
82
|
+
pfx = pfx.to_s.chomp(':').to_sym
|
83
|
+
prefixes[pfx] = sfx
|
84
|
+
"PREFIX #{pfx}: #{sfx.to_sparql}\n"
|
85
|
+
end.join("")
|
86
|
+
|
87
|
+
str << operands.last.to_sparql(prefixes: prefixes, **options)
|
88
|
+
end
|
68
89
|
end # Prefix
|
69
90
|
end # Operator
|
70
91
|
end; end # SPARQL::Algebra
|
@@ -3,11 +3,53 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL GraphPattern `project` operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
6
|
+
# [9] SelectClause ::= 'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' )
|
7
|
+
#
|
8
|
+
# ## Basic Projection
|
9
|
+
#
|
10
|
+
# @example SPARQL Grammar
|
11
|
+
# PREFIX : <http://example/>
|
12
|
+
# SELECT ?v {
|
13
|
+
# ?s :p ?v .
|
14
|
+
# FILTER (?v = 2)
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
# @example SSE
|
18
|
+
# (prefix ((: <http://example/>))
|
19
|
+
# (project (?v)
|
20
|
+
# (filter (= ?v 2)
|
21
|
+
# (bgp (triple ?s :p ?v)))))
|
22
|
+
#
|
23
|
+
# @example SPARQL Grammar (Sub select)
|
24
|
+
# SELECT (1 AS ?X ) {
|
25
|
+
# SELECT (2 AS ?Y ) {}
|
26
|
+
# }
|
27
|
+
#
|
28
|
+
# @example SSE (Sub select)
|
29
|
+
# (project (?X)
|
30
|
+
# (extend ((?X 1))
|
31
|
+
# (project (?Y)
|
32
|
+
# (extend ((?Y 2))
|
33
|
+
# (bgp)))))
|
34
|
+
#
|
35
|
+
# @example SPARQL Grammar (filter projection)
|
36
|
+
# PREFIX : <http://www.example.org/>
|
37
|
+
# ASK {
|
38
|
+
# {SELECT (GROUP_CONCAT(?o) AS ?g) WHERE {
|
39
|
+
# :a :p1 ?o
|
40
|
+
# }}
|
41
|
+
# FILTER(?g = "1 22" || ?g = "22 1")
|
42
|
+
# }
|
43
|
+
#
|
44
|
+
# @example SSE (filter projection)
|
45
|
+
# (prefix ((: <http://www.example.org/>))
|
46
|
+
# (ask
|
47
|
+
# (filter
|
48
|
+
# (|| (= ?g "1 22") (= ?g "22 1"))
|
49
|
+
# (project (?g)
|
50
|
+
# (extend ((?g ??.0))
|
51
|
+
# (group () ((??.0 (group_concat ?o)))
|
52
|
+
# (bgp (triple :a :p1 ?o)))))) ))
|
11
53
|
#
|
12
54
|
# @see https://www.w3.org/TR/sparql11-query/#modProjection
|
13
55
|
class Project < Operator::Binary
|
@@ -36,6 +78,28 @@ module SPARQL; module Algebra
|
|
36
78
|
@solutions.each(&block) if block_given?
|
37
79
|
@solutions
|
38
80
|
end
|
81
|
+
|
82
|
+
##
|
83
|
+
#
|
84
|
+
# Returns a partial SPARQL grammar for this operator.
|
85
|
+
#
|
86
|
+
# Extracts projections
|
87
|
+
#
|
88
|
+
# If there are already extensions or filters, then this is a sub-select.
|
89
|
+
#
|
90
|
+
# @return [String]
|
91
|
+
def to_sparql(**options)
|
92
|
+
vars = operands[0].empty? ? [:*] : operands[0]
|
93
|
+
if options[:extensions] || options[:filter_ops] || options[:project]
|
94
|
+
# Any of these options indicates we're in a sub-select
|
95
|
+
opts = options.dup.delete_if {|k,v| %I{extensions filter_ops project}.include?(k)}
|
96
|
+
content = operands.last.to_sparql(project: vars, **opts)
|
97
|
+
content = "{#{content}}" unless content.start_with?('{') && content.end_with?('}')
|
98
|
+
Operator.to_sparql(content, **options)
|
99
|
+
else
|
100
|
+
operands.last.to_sparql(project: vars, **options)
|
101
|
+
end
|
102
|
+
end
|
39
103
|
end # Project
|
40
104
|
end # Operator
|
41
105
|
end; end # SPARQL::Algebra
|
@@ -5,8 +5,25 @@ module SPARQL; module Algebra
|
|
5
5
|
#
|
6
6
|
# Returns a pseudo-random number between 0 (inclusive) and 1.0e0 (exclusive). Different numbers can be produced every time this function is invoked. Numbers should be produced with approximately equal probability.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# [121] BuiltInCall ::= ... | 'RAND' NIL
|
9
|
+
#
|
10
|
+
# @example SPARQL Grammar
|
11
|
+
# PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
12
|
+
# ASK {
|
13
|
+
# BIND(RAND() AS ?r)
|
14
|
+
# FILTER(DATATYPE(?r) = xsd:double && ?r >= 0.0 && ?r < 1.0)
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
# @example SSE
|
18
|
+
# (prefix
|
19
|
+
# ((xsd: <http://www.w3.org/2001/XMLSchema#>))
|
20
|
+
# (ask
|
21
|
+
# (filter
|
22
|
+
# (&&
|
23
|
+
# (&& (= (datatype ?r) xsd:double) (>= ?r 0.0))
|
24
|
+
# (< ?r 1.0))
|
25
|
+
# (extend ((?r (rand)))
|
26
|
+
# (bgp)))))
|
10
27
|
#
|
11
28
|
# @see https://www.w3.org/TR/sparql11-query/#idp2130040
|
12
29
|
class Rand < Operator::Nullary
|
@@ -18,9 +35,20 @@ module SPARQL; module Algebra
|
|
18
35
|
# Returns a pseudo-random number between 0 (inclusive) and 1.0e0 (exclusive). Different numbers can be produced every time this function is invoked. Numbers should be produced with approximately equal probability.
|
19
36
|
#
|
20
37
|
# @return [RDF::Literal::Double] random value
|
21
|
-
def apply
|
38
|
+
def apply(**options)
|
22
39
|
RDF::Literal::Double.new(Random.rand)
|
23
40
|
end
|
41
|
+
|
42
|
+
##
|
43
|
+
#
|
44
|
+
# Returns a partial SPARQL grammar for this operator.
|
45
|
+
#
|
46
|
+
# Extracts projections
|
47
|
+
#
|
48
|
+
# @return [String]
|
49
|
+
def to_sparql(**options)
|
50
|
+
"RAND()"
|
51
|
+
end
|
24
52
|
end # Rand
|
25
53
|
end # Operator
|
26
54
|
end; end # SPARQL::Algebra
|
@@ -3,9 +3,17 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL GraphPattern `reduced` operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# [9] SelectClause ::= 'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' )
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX : <http://example.org/>
|
10
|
+
# PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
11
|
+
# SELECT REDUCED ?v
|
12
|
+
# WHERE { ?x ?p ?v }
|
13
|
+
#
|
14
|
+
# @example SSE
|
15
|
+
# (prefix ((: <http://example.org/>)
|
16
|
+
# (xsd: <http://www.w3.org/2001/XMLSchema#>))
|
9
17
|
# (reduced
|
10
18
|
# (project (?v)
|
11
19
|
# (bgp (triple ?x ?p ?v)))))
|
@@ -37,6 +45,15 @@ module SPARQL; module Algebra
|
|
37
45
|
@solutions.each(&block) if block_given?
|
38
46
|
@solutions
|
39
47
|
end
|
48
|
+
|
49
|
+
##
|
50
|
+
#
|
51
|
+
# Returns a partial SPARQL grammar for this operator.
|
52
|
+
#
|
53
|
+
# @return [String]
|
54
|
+
def to_sparql(**options)
|
55
|
+
operands.first.to_sparql(reduced: true, **options)
|
56
|
+
end
|
40
57
|
end # Reduced
|
41
58
|
end # Operator
|
42
59
|
end; end # SPARQL::Algebra
|
@@ -3,33 +3,31 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL `regex` operator.
|
5
5
|
#
|
6
|
-
#
|
6
|
+
# [122] RegexExpression ::= 'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')'
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX ex: <http://example.com/#>
|
10
|
+
# PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
11
|
+
# SELECT ?val
|
12
|
+
# WHERE {
|
13
|
+
# ex:foo rdf:value ?val .
|
14
|
+
# FILTER regex(?val, "GHI")
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
# @example SSE
|
7
18
|
# (prefix ((ex: <http://example.com/#>)
|
8
19
|
# (rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>))
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
20
|
+
# (project (?val)
|
21
|
+
# (filter (regex ?val "GHI")
|
22
|
+
# (bgp (triple ex:foo rdf:value ?val)))))
|
12
23
|
#
|
13
24
|
# @see https://www.w3.org/TR/sparql11-query/#funcex-regex
|
14
25
|
# @see https://www.w3.org/TR/xpath-functions/#func-matches
|
15
|
-
class Regex < Operator
|
26
|
+
class Regex < Operator
|
16
27
|
include Evaluatable
|
17
28
|
|
18
29
|
NAME = :regex
|
19
30
|
|
20
|
-
##
|
21
|
-
# Initializes a new operator instance.
|
22
|
-
#
|
23
|
-
# @param [RDF::Term] text
|
24
|
-
# @param [RDF::Term] pattern
|
25
|
-
# @param [RDF::Term] flags
|
26
|
-
# @param [Hash{Symbol => Object}] options
|
27
|
-
# any additional options (see {Operator#initialize})
|
28
|
-
# @raise [TypeError] if any operand is invalid
|
29
|
-
def initialize(text, pattern, flags = RDF::Literal(''), **options)
|
30
|
-
super
|
31
|
-
end
|
32
|
-
|
33
31
|
##
|
34
32
|
# Matches `text` against a regular expression `pattern`.
|
35
33
|
#
|
@@ -42,7 +40,7 @@ module SPARQL; module Algebra
|
|
42
40
|
# @return [RDF::Literal::Boolean] `true` or `false`
|
43
41
|
# @raise [TypeError] if any operand is unbound
|
44
42
|
# @raise [TypeError] if any operand is not a simple literal
|
45
|
-
def apply(text, pattern, flags = RDF::Literal(''))
|
43
|
+
def apply(text, pattern, flags = RDF::Literal(''), **options)
|
46
44
|
# @see https://www.w3.org/TR/xpath-functions/#regex-syntax
|
47
45
|
raise TypeError, "expected a plain RDF::Literal, but got #{text.inspect}" unless text.is_a?(RDF::Literal) && text.plain?
|
48
46
|
text = text.to_s
|
@@ -65,6 +63,16 @@ module SPARQL; module Algebra
|
|
65
63
|
options |= Regexp::EXTENDED if flags.include?(?x)
|
66
64
|
RDF::Literal(Regexp.new(pattern, options) === text)
|
67
65
|
end
|
66
|
+
|
67
|
+
##
|
68
|
+
#
|
69
|
+
# Returns a partial SPARQL grammar for this operator.
|
70
|
+
#
|
71
|
+
# @return [String]
|
72
|
+
def to_sparql(**options)
|
73
|
+
ops = operands.last.to_s.empty? ? operands[0..-2] : operands
|
74
|
+
"regex(" + ops.to_sparql(delimiter: ', ', **options) + ")"
|
75
|
+
end
|
68
76
|
end # Regex
|
69
77
|
end # Operator
|
70
78
|
end; end # SPARQL::Algebra
|
@@ -3,12 +3,22 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL `replace` operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
6
|
+
# [124] StrReplaceExpression ::= 'REPLACE' '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')'
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX : <http://example.org/>
|
10
|
+
# PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
11
|
+
# SELECT ?s (REPLACE(?str,"[^a-z0-9]", "-") AS ?new)
|
12
|
+
# WHERE {
|
13
|
+
# ?s :str ?str
|
14
|
+
# }
|
15
|
+
#
|
16
|
+
# @example SSE
|
17
|
+
# (prefix ((: <http://example.org/>)
|
18
|
+
# (xsd: <http://www.w3.org/2001/XMLSchema#>))
|
19
|
+
# (project (?s ?new)
|
20
|
+
# (extend ((?new (replace ?str "[^a-z0-9]" "-")))
|
21
|
+
# (bgp (triple ?s :str ?str)))))
|
12
22
|
#
|
13
23
|
# @see https://www.w3.org/TR/sparql11-query/#funcex-replace
|
14
24
|
# @see https://www.w3.org/TR/xpath-functions/#func-replace
|
@@ -42,7 +52,7 @@ module SPARQL; module Algebra
|
|
42
52
|
# @return [RDF::Literal]
|
43
53
|
# @raise [TypeError] if any operand is unbound
|
44
54
|
# @raise [TypeError] if any operand is not a plain literal
|
45
|
-
def apply(text, pattern, replacement, flags = RDF::Literal(''))
|
55
|
+
def apply(text, pattern, replacement, flags = RDF::Literal(''), **options)
|
46
56
|
raise TypeError, "expected a plain RDF::Literal, but got #{text.inspect}" unless text.literal? && text.plain?
|
47
57
|
# TODO: validate text syntax
|
48
58
|
|
@@ -76,6 +86,16 @@ module SPARQL; module Algebra
|
|
76
86
|
def to_sxp_bin
|
77
87
|
[NAME] + operands.reject {|o| o.to_s == ""}
|
78
88
|
end
|
89
|
+
|
90
|
+
##
|
91
|
+
#
|
92
|
+
# Returns a partial SPARQL grammar for this operator.
|
93
|
+
#
|
94
|
+
# @return [String]
|
95
|
+
def to_sparql(**options)
|
96
|
+
ops = operands.last.to_s.empty? ? operands[0..-2] : operands
|
97
|
+
"REPLACE(" + ops.to_sparql(delimiter: ', ', **options) + ")"
|
98
|
+
end
|
79
99
|
end # Replace
|
80
100
|
end # Operator
|
81
101
|
end; end # SPARQL::Algebra
|
@@ -3,8 +3,28 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL Property Path `reverse` (NegatedPropertySet) operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# [92] PathEltOrInverse ::= PathElt | '^' PathElt
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX ex: <http://www.example.org/schema#>
|
10
|
+
# PREFIX in: <http://www.example.org/instance#>
|
11
|
+
# ASK { in:b ^ex:p in:a }
|
12
|
+
#
|
13
|
+
# @example SSE
|
14
|
+
# (prefix ((ex: <http://www.example.org/schema#>)
|
15
|
+
# (in: <http://www.example.org/instance#>))
|
16
|
+
# (ask (path in:b (reverse ex:p) in:a)))
|
17
|
+
#
|
18
|
+
# @example SPARQL Grammar
|
19
|
+
# prefix ex: <http://www.example.org/schema#>
|
20
|
+
# prefix in: <http://www.example.org/instance#>
|
21
|
+
#
|
22
|
+
# select * where { in:c ^(ex:p1/ex:p2) ?x }
|
23
|
+
#
|
24
|
+
# @example SSE
|
25
|
+
# (prefix ((ex: <http://www.example.org/schema#>)
|
26
|
+
# (in: <http://www.example.org/instance#>))
|
27
|
+
# (path in:c (reverse (seq ex:p1 ex:p2)) ?x))
|
8
28
|
#
|
9
29
|
# @see https://www.w3.org/TR/sparql11-query/#defn_evalPP_inverse
|
10
30
|
class Reverse < Operator::Unary
|
@@ -49,6 +69,15 @@ module SPARQL; module Algebra
|
|
49
69
|
), &block)
|
50
70
|
|
51
71
|
end
|
72
|
+
|
73
|
+
##
|
74
|
+
#
|
75
|
+
# Returns a partial SPARQL grammar for this operator.
|
76
|
+
#
|
77
|
+
# @return [String]
|
78
|
+
def to_sparql(**options)
|
79
|
+
"^(" + operands.first.to_sparql(**options) + ')'
|
80
|
+
end
|
52
81
|
end # Reverse
|
53
82
|
end # Operator
|
54
83
|
end; end # SPARQL::Algebra
|
@@ -5,8 +5,22 @@ module SPARQL; module Algebra
|
|
5
5
|
#
|
6
6
|
# Returns the number with no fractional part that is closest to the argument. If there are two such numbers, then the one that is closest to positive infinity is returned. An error is raised if `arg` is not a numeric value.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# [121] BuiltInCall ::= ... 'ROUND' '(' Expression ')'
|
9
|
+
#
|
10
|
+
# @example SPARQL Grammar
|
11
|
+
# PREFIX : <http://example.org/>
|
12
|
+
# PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
13
|
+
# SELECT ?s ?num (ROUND(?num) AS ?round) WHERE {
|
14
|
+
# ?s :num ?num
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
# @example SSE
|
18
|
+
# (prefix
|
19
|
+
# ((: <http://example.org/>)
|
20
|
+
# (xsd: <http://www.w3.org/2001/XMLSchema#>))
|
21
|
+
# (project (?s ?num ?round)
|
22
|
+
# (extend ((?round (round ?num)))
|
23
|
+
# (bgp (triple ?s :num ?num)))))
|
10
24
|
#
|
11
25
|
# @see https://www.w3.org/TR/sparql11-query/#func-round
|
12
26
|
# @see https://www.w3.org/TR/xpath-functions/#func-round
|
@@ -22,12 +36,21 @@ module SPARQL; module Algebra
|
|
22
36
|
# the operand
|
23
37
|
# @return [RDF::Literal] literal of same type
|
24
38
|
# @raise [TypeError] if the operand is not a numeric value
|
25
|
-
def apply(operand)
|
39
|
+
def apply(operand, **options)
|
26
40
|
case operand
|
27
41
|
when RDF::Literal::Numeric then operand.round
|
28
42
|
else raise TypeError, "expected an RDF::Literal::Numeric, but got #{operand.inspect}"
|
29
43
|
end
|
30
44
|
end
|
31
45
|
end # Round
|
46
|
+
|
47
|
+
##
|
48
|
+
#
|
49
|
+
# Returns a partial SPARQL grammar for this operator.
|
50
|
+
#
|
51
|
+
# @return [String]
|
52
|
+
def to_sparql(**options)
|
53
|
+
"ROUND(#{operands.to_sparql(**options)})"
|
54
|
+
end
|
32
55
|
end # Operator
|
33
56
|
end; end # SPARQL::Algebra
|
@@ -3,12 +3,21 @@ module SPARQL; module Algebra
|
|
3
3
|
##
|
4
4
|
# The SPARQL `sameTerm` operator.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
6
|
+
# [121] BuiltInCall ::= ... | 'sameTerm' '(' Expression ',' Expression ')'
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX : <http://example.org/things#>
|
10
|
+
# SELECT * {
|
11
|
+
# ?x1 :p ?v1 .
|
12
|
+
# ?x2 :p ?v2 .
|
13
|
+
# FILTER sameTerm(?v1, ?v2)
|
14
|
+
# }
|
15
|
+
#
|
16
|
+
# @example SSE
|
17
|
+
# (prefix
|
18
|
+
# ((: <http://example.org/things#>))
|
19
|
+
# (filter (sameTerm ?v1 ?v2)
|
20
|
+
# (bgp (triple ?x1 :p ?v1) (triple ?x2 :p ?v2))))
|
12
21
|
#
|
13
22
|
# @see https://www.w3.org/TR/sparql11-query/#func-sameTerm
|
14
23
|
class SameTerm < Operator::Binary
|
@@ -26,7 +35,7 @@ module SPARQL; module Algebra
|
|
26
35
|
# an RDF term
|
27
36
|
# @return [RDF::Literal::Boolean] `true` or `false`
|
28
37
|
# @raise [TypeError] if either operand is unbound
|
29
|
-
def apply(term1, term2)
|
38
|
+
def apply(term1, term2, **options)
|
30
39
|
RDF::Literal(term1.eql?(term2))
|
31
40
|
end
|
32
41
|
|
@@ -44,6 +53,15 @@ module SPARQL; module Algebra
|
|
44
53
|
super # @see Operator#optimize!
|
45
54
|
end
|
46
55
|
end
|
56
|
+
|
57
|
+
##
|
58
|
+
#
|
59
|
+
# Returns a partial SPARQL grammar for this operator.
|
60
|
+
#
|
61
|
+
# @return [String]
|
62
|
+
def to_sparql(**options)
|
63
|
+
"sameTerm(#{operands.to_sparql(delimiter: ', ', **options)})"
|
64
|
+
end
|
47
65
|
end # SameTerm
|
48
66
|
end # Operator
|
49
67
|
end; end # SPARQL::Algebra
|