sparql 3.1.5 → 3.2.0

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.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +35 -28
  3. data/VERSION +1 -1
  4. data/bin/sparql +14 -4
  5. data/lib/sparql/algebra/aggregate.rb +1 -1
  6. data/lib/sparql/algebra/evaluatable.rb +4 -4
  7. data/lib/sparql/algebra/expression.rb +4 -1
  8. data/lib/sparql/algebra/extensions.rb +96 -29
  9. data/lib/sparql/algebra/operator/abs.rb +23 -3
  10. data/lib/sparql/algebra/operator/add.rb +21 -2
  11. data/lib/sparql/algebra/operator/alt.rb +26 -2
  12. data/lib/sparql/algebra/operator/and.rb +25 -3
  13. data/lib/sparql/algebra/operator/asc.rb +20 -1
  14. data/lib/sparql/algebra/operator/ask.rb +17 -1
  15. data/lib/sparql/algebra/operator/avg.rb +18 -2
  16. data/lib/sparql/algebra/operator/base.rb +18 -1
  17. data/lib/sparql/algebra/operator/bgp.rb +5 -1
  18. data/lib/sparql/algebra/operator/bnode.rb +34 -11
  19. data/lib/sparql/algebra/operator/bound.rb +22 -1
  20. data/lib/sparql/algebra/operator/ceil.rb +26 -3
  21. data/lib/sparql/algebra/operator/clear.rb +16 -2
  22. data/lib/sparql/algebra/operator/coalesce.rb +33 -11
  23. data/lib/sparql/algebra/operator/compare.rb +48 -33
  24. data/lib/sparql/algebra/operator/concat.rb +26 -2
  25. data/lib/sparql/algebra/operator/construct.rb +31 -7
  26. data/lib/sparql/algebra/operator/contains.rb +25 -3
  27. data/lib/sparql/algebra/operator/copy.rb +19 -2
  28. data/lib/sparql/algebra/operator/count.rb +18 -2
  29. data/lib/sparql/algebra/operator/create.rb +19 -2
  30. data/lib/sparql/algebra/operator/dataset.rb +17 -0
  31. data/lib/sparql/algebra/operator/datatype.rb +26 -7
  32. data/lib/sparql/algebra/operator/day.rb +24 -6
  33. data/lib/sparql/algebra/operator/delete.rb +27 -2
  34. data/lib/sparql/algebra/operator/delete_data.rb +23 -2
  35. data/lib/sparql/algebra/operator/delete_where.rb +24 -2
  36. data/lib/sparql/algebra/operator/desc.rb +20 -1
  37. data/lib/sparql/algebra/operator/describe.rb +27 -4
  38. data/lib/sparql/algebra/operator/distinct.rb +18 -1
  39. data/lib/sparql/algebra/operator/divide.rb +27 -3
  40. data/lib/sparql/algebra/operator/drop.rb +17 -2
  41. data/lib/sparql/algebra/operator/encode_for_uri.rb +25 -3
  42. data/lib/sparql/algebra/operator/equal.rb +13 -3
  43. data/lib/sparql/algebra/operator/exists.rb +28 -4
  44. data/lib/sparql/algebra/operator/exprlist.rb +12 -1
  45. data/lib/sparql/algebra/operator/extend.rb +33 -18
  46. data/lib/sparql/algebra/operator/filter.rb +27 -5
  47. data/lib/sparql/algebra/operator/floor.rb +26 -3
  48. data/lib/sparql/algebra/operator/graph.rb +13 -0
  49. data/lib/sparql/algebra/operator/greater_than.rb +14 -4
  50. data/lib/sparql/algebra/operator/greater_than_or_equal.rb +14 -4
  51. data/lib/sparql/algebra/operator/group.rb +34 -8
  52. data/lib/sparql/algebra/operator/group_concat.rb +20 -8
  53. data/lib/sparql/algebra/operator/hours.rb +24 -6
  54. data/lib/sparql/algebra/operator/if.rb +21 -4
  55. data/lib/sparql/algebra/operator/in.rb +18 -1
  56. data/lib/sparql/algebra/operator/insert.rb +22 -2
  57. data/lib/sparql/algebra/operator/insert_data.rb +23 -2
  58. data/lib/sparql/algebra/operator/iri.rb +22 -5
  59. data/lib/sparql/algebra/operator/is_blank.rb +20 -2
  60. data/lib/sparql/algebra/operator/is_iri.rb +20 -2
  61. data/lib/sparql/algebra/operator/is_literal.rb +20 -2
  62. data/lib/sparql/algebra/operator/is_numeric.rb +22 -4
  63. data/lib/sparql/algebra/operator/is_triple.rb +62 -0
  64. data/lib/sparql/algebra/operator/join.rb +22 -1
  65. data/lib/sparql/algebra/operator/lang.rb +26 -1
  66. data/lib/sparql/algebra/operator/lang_matches.rb +23 -2
  67. data/lib/sparql/algebra/operator/lcase.rb +24 -3
  68. data/lib/sparql/algebra/operator/left_join.rb +29 -1
  69. data/lib/sparql/algebra/operator/less_than.rb +14 -4
  70. data/lib/sparql/algebra/operator/less_than_or_equal.rb +14 -4
  71. data/lib/sparql/algebra/operator/load.rb +25 -2
  72. data/lib/sparql/algebra/operator/max.rb +18 -2
  73. data/lib/sparql/algebra/operator/md5.rb +23 -6
  74. data/lib/sparql/algebra/operator/min.rb +19 -3
  75. data/lib/sparql/algebra/operator/minus.rb +25 -7
  76. data/lib/sparql/algebra/operator/minutes.rb +24 -6
  77. data/lib/sparql/algebra/operator/modify.rb +41 -5
  78. data/lib/sparql/algebra/operator/month.rb +24 -6
  79. data/lib/sparql/algebra/operator/move.rb +20 -2
  80. data/lib/sparql/algebra/operator/multiply.rb +27 -4
  81. data/lib/sparql/algebra/operator/negate.rb +24 -4
  82. data/lib/sparql/algebra/operator/not.rb +25 -4
  83. data/lib/sparql/algebra/operator/not_equal.rb +16 -1
  84. data/lib/sparql/algebra/operator/notexists.rb +30 -6
  85. data/lib/sparql/algebra/operator/notin.rb +20 -3
  86. data/lib/sparql/algebra/operator/notoneof.rb +12 -2
  87. data/lib/sparql/algebra/operator/now.rb +25 -6
  88. data/lib/sparql/algebra/operator/object.rb +59 -0
  89. data/lib/sparql/algebra/operator/or.rb +26 -3
  90. data/lib/sparql/algebra/operator/order.rb +27 -2
  91. data/lib/sparql/algebra/operator/path.rb +29 -2
  92. data/lib/sparql/algebra/operator/path_opt.rb +21 -2
  93. data/lib/sparql/algebra/operator/path_plus.rb +21 -2
  94. data/lib/sparql/algebra/operator/path_star.rb +20 -2
  95. data/lib/sparql/algebra/operator/plus.rb +43 -4
  96. data/lib/sparql/algebra/operator/predicate.rb +59 -0
  97. data/lib/sparql/algebra/operator/prefix.rb +24 -3
  98. data/lib/sparql/algebra/operator/project.rb +51 -5
  99. data/lib/sparql/algebra/operator/rand.rb +31 -3
  100. data/lib/sparql/algebra/operator/reduced.rb +18 -1
  101. data/lib/sparql/algebra/operator/regex.rb +27 -19
  102. data/lib/sparql/algebra/operator/replace.rb +27 -7
  103. data/lib/sparql/algebra/operator/reverse.rb +20 -2
  104. data/lib/sparql/algebra/operator/round.rb +26 -3
  105. data/lib/sparql/algebra/operator/same_term.rb +25 -7
  106. data/lib/sparql/algebra/operator/sample.rb +31 -9
  107. data/lib/sparql/algebra/operator/seconds.rb +24 -6
  108. data/lib/sparql/algebra/operator/seq.rb +20 -2
  109. data/lib/sparql/algebra/operator/sequence.rb +0 -10
  110. data/lib/sparql/algebra/operator/sha1.rb +19 -2
  111. data/lib/sparql/algebra/operator/sha256.rb +19 -2
  112. data/lib/sparql/algebra/operator/sha384.rb +19 -2
  113. data/lib/sparql/algebra/operator/sha512.rb +19 -2
  114. data/lib/sparql/algebra/operator/slice.rb +27 -5
  115. data/lib/sparql/algebra/operator/str.rb +22 -2
  116. data/lib/sparql/algebra/operator/strafter.rb +26 -3
  117. data/lib/sparql/algebra/operator/strbefore.rb +26 -3
  118. data/lib/sparql/algebra/operator/strdt.rb +23 -2
  119. data/lib/sparql/algebra/operator/strends.rb +26 -4
  120. data/lib/sparql/algebra/operator/strlang.rb +26 -7
  121. data/lib/sparql/algebra/operator/strlen.rb +24 -3
  122. data/lib/sparql/algebra/operator/strstarts.rb +26 -3
  123. data/lib/sparql/algebra/operator/struuid.rb +30 -10
  124. data/lib/sparql/algebra/operator/subject.rb +61 -0
  125. data/lib/sparql/algebra/operator/substr.rb +24 -3
  126. data/lib/sparql/algebra/operator/subtract.rb +29 -3
  127. data/lib/sparql/algebra/operator/sum.rb +18 -2
  128. data/lib/sparql/algebra/operator/table.rb +42 -4
  129. data/lib/sparql/algebra/operator/timezone.rb +24 -6
  130. data/lib/sparql/algebra/operator/tz.rb +23 -6
  131. data/lib/sparql/algebra/operator/ucase.rb +24 -3
  132. data/lib/sparql/algebra/operator/union.rb +29 -6
  133. data/lib/sparql/algebra/operator/update.rb +25 -4
  134. data/lib/sparql/algebra/operator/using.rb +32 -2
  135. data/lib/sparql/algebra/operator/uuid.rb +28 -9
  136. data/lib/sparql/algebra/operator/with.rb +38 -4
  137. data/lib/sparql/algebra/operator/year.rb +24 -6
  138. data/lib/sparql/algebra/operator.rb +112 -7
  139. data/lib/sparql/algebra/sxp_extensions.rb +3 -3
  140. data/lib/sparql/grammar/meta.rb +5390 -2410
  141. data/lib/sparql/grammar/parser11.rb +119 -53
  142. data/lib/sparql/grammar/terminals11.rb +2 -0
  143. data/lib/sparql/grammar.rb +0 -25
  144. metadata +40 -34
@@ -3,7 +3,16 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `isIRI`/`isURI` operator.
5
5
  #
6
- # @example
6
+ # [121] BuiltInCall ::= ... | 'isIRI' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/things#>
10
+ # SELECT ?x ?v WHERE {
11
+ # ?x :p ?v .
12
+ # FILTER isIRI(?v) .
13
+ # }
14
+ #
15
+ # @example SSE
7
16
  # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
8
17
  # (: <http://example.org/things#>))
9
18
  # (project (?x ?v)
@@ -23,7 +32,7 @@ module SPARQL; module Algebra
23
32
  # an RDF term
24
33
  # @return [RDF::Literal::Boolean] `true` or `false`
25
34
  # @raise [TypeError] if the operand is not an RDF term
26
- def apply(term)
35
+ def apply(term, **options)
27
36
  case term
28
37
  when RDF::URI then RDF::Literal::TRUE
29
38
  when RDF::Term then RDF::Literal::FALSE
@@ -32,6 +41,15 @@ module SPARQL; module Algebra
32
41
  end
33
42
 
34
43
  Operator::IsURI = IsIRI
44
+
45
+ ##
46
+ #
47
+ # Returns a partial SPARQL grammar for this operator.
48
+ #
49
+ # @return [String]
50
+ def to_sparql(**options)
51
+ "isIRI(" + operands.first.to_sparql(**options) + ")"
52
+ end
35
53
  end # IsIRI
36
54
  end # Operator
37
55
  end; end # SPARQL::Algebra
@@ -3,7 +3,16 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `isLiteral` operator.
5
5
  #
6
- # @example
6
+ # [121] BuiltInCall ::= ... | 'isLiteral' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/things#>
10
+ # SELECT ?x ?v WHERE {
11
+ # ?x :p ?v .
12
+ # FILTER isLiteral(?v) .
13
+ # }
14
+ #
15
+ # @example SSE
7
16
  # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
8
17
  # (: <http://example.org/things#>))
9
18
  # (project (?x ?v)
@@ -24,13 +33,22 @@ module SPARQL; module Algebra
24
33
  # an RDF term
25
34
  # @return [RDF::Literal::Boolean] `true` or `false`
26
35
  # @raise [TypeError] if the operand is not an RDF term
27
- def apply(term)
36
+ def apply(term, **options)
28
37
  case term
29
38
  when RDF::Literal then RDF::Literal::TRUE
30
39
  when RDF::Term then RDF::Literal::FALSE
31
40
  else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
32
41
  end
33
42
  end
43
+
44
+ ##
45
+ #
46
+ # Returns a partial SPARQL grammar for this operator.
47
+ #
48
+ # @return [String]
49
+ def to_sparql(**options)
50
+ "isLiteral(" + operands.first.to_sparql(**options) + ")"
51
+ end
34
52
  end # IsLiteral
35
53
  end # Operator
36
54
  end; end # SPARQL::Algebra
@@ -3,9 +3,18 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `isNumeric` operator.
5
5
  #
6
- # Note numeric denotes typed literals with datatypes xsd:integer, xsd:decimal, xsd:float, and xsd:double, not derived types.
6
+ # Note numeric denotes typed literals with datatypes `xsd:integer`, `xsd:decimal`, `xsd:float`, and `xsd:double`, not derived types.
7
7
  #
8
- # @example
8
+ # [121] BuiltInCall ::= ... | 'isNumeric' '(' Expression ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.org/things#>
12
+ # SELECT ?x ?v WHERE {
13
+ # ?x :p ?v .
14
+ # FILTER isNumeric(?v) .
15
+ # }
16
+ #
17
+ # @example SSE
9
18
  # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
10
19
  # (: <http://example.org/things#>))
11
20
  # (project (?x ?v)
@@ -16,7 +25,7 @@ module SPARQL; module Algebra
16
25
  class IsNumeric < Operator::Unary
17
26
  include Evaluatable
18
27
 
19
- NAME = :isnumeric
28
+ NAME = :isNumeric
20
29
 
21
30
  ##
22
31
  # Returns `true` if the operand is an `RDF::Literal::Numeric`, `false`
@@ -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 the operand is not an RDF term
29
- def apply(term)
38
+ def apply(term, **options)
30
39
  case term
31
40
  when RDF::Literal::NonPositiveInteger then RDF::Literal::FALSE
32
41
  when RDF::Literal::NonNegativeInteger then RDF::Literal::FALSE
@@ -36,6 +45,15 @@ module SPARQL; module Algebra
36
45
  else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
37
46
  end
38
47
  end
48
+
49
+ ##
50
+ #
51
+ # Returns a partial SPARQL grammar for this operator.
52
+ #
53
+ # @return [String]
54
+ def to_sparql(**options)
55
+ "isNumeric(" + operands.first.to_sparql(**options) + ")"
56
+ end
39
57
  end # IsNumeric
40
58
  end # Operator
41
59
  end; end # SPARQL::Algebra
@@ -0,0 +1,62 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL `isTRIPLE` operator.
5
+ #
6
+ # Returns true if term is an RDF-star triple. Returns false otherwise.
7
+ #
8
+ # [121] BuiltInCall ::= ... | 'isTreiple' '(' 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
+ #
31
+ # @see https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#istriple
32
+ class IsTriple < Operator::Unary
33
+ include Evaluatable
34
+
35
+ NAME = :isTRIPLE
36
+
37
+ ##
38
+ # Returns `true` if the operand is an `RDF::Statement`, `false` otherwise.
39
+ #
40
+ # @param [RDF::Term] term
41
+ # an RDF term
42
+ # @return [RDF::Literal::Boolean] `true` or `false`
43
+ # @raise [TypeError] if the operand is not an RDF term
44
+ def apply(term, **options)
45
+ case term
46
+ when RDF::Statement then RDF::Literal::TRUE
47
+ when RDF::Term then RDF::Literal::FALSE
48
+ else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
49
+ end
50
+ end
51
+
52
+ ##
53
+ #
54
+ # Returns a partial SPARQL grammar for this operator.
55
+ #
56
+ # @return [String]
57
+ def to_sparql(**options)
58
+ "isTRIPLE(" + operands.first.to_sparql(**options) + ")"
59
+ end
60
+ end # IsTriple
61
+ end # Operator
62
+ end; end # SPARQL::Algebra
@@ -3,7 +3,16 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `join` operator.
5
5
  #
6
- # @example
6
+ # [54] GroupGraphPatternSub ::= TriplesBlock? (GraphPatternNotTriples "."? TriplesBlock? )*
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example/>
10
+ # SELECT * {
11
+ # ?s ?p ?o
12
+ # GRAPH ?g { ?s ?q ?v }
13
+ # }
14
+ #
15
+ # @example SSE
7
16
  # (prefix ((: <http://example/>))
8
17
  # (join
9
18
  # (bgp (triple ?s ?p ?o))
@@ -82,6 +91,18 @@ module SPARQL; module Algebra
82
91
  @operands = ops
83
92
  self
84
93
  end
94
+
95
+ ##
96
+ #
97
+ # Returns a partial SPARQL grammar for this operator.
98
+ #
99
+ # @param [Boolean] top_level (true)
100
+ # Treat this as a top-level, generating SELECT ... WHERE {}
101
+ # @return [String]
102
+ def to_sparql(top_level: true, **options)
103
+ str = operands.to_sparql(top_level: false, delimiter: "\n", **options)
104
+ top_level ? Operator.to_sparql(str, **options) : str
105
+ end
85
106
  end # Join
86
107
  end # Operator
87
108
  end; end # SPARQL::Algebra
@@ -3,6 +3,22 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `lang` operator.
5
5
  #
6
+ # [121] BuiltInCall ::= ... | 'LANG' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example/>
10
+ #
11
+ # SELECT ?x
12
+ # { ?x :p ?v .
13
+ # FILTER ( lang(?v) != '@NotALangTag@' )
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix ((: <http://example/>))
18
+ # (project (?x)
19
+ # (filter (!= (lang ?v) "@NotALangTag@")
20
+ # (bgp (triple ?x :p ?v)))))
21
+ #
6
22
  # @see https://www.w3.org/TR/sparql11-query/#func-lang
7
23
  class Lang < Operator::Unary
8
24
  include Evaluatable
@@ -18,12 +34,21 @@ module SPARQL; module Algebra
18
34
  # a literal
19
35
  # @return [RDF::Literal] a simple literal
20
36
  # @raise [TypeError] if the operand is not a literal
21
- def apply(literal)
37
+ def apply(literal, **options)
22
38
  case literal
23
39
  when RDF::Literal then RDF::Literal(literal.language.to_s)
24
40
  else raise TypeError, "expected an RDF::Literal, but got #{literal.inspect}"
25
41
  end
26
42
  end
43
+
44
+ ##
45
+ #
46
+ # Returns a partial SPARQL grammar for this operator.
47
+ #
48
+ # @return [String]
49
+ def to_sparql(**options)
50
+ "lang(" + operands.first.to_sparql(**options) + ")"
51
+ end
27
52
  end # Lang
28
53
  end # Operator
29
54
  end; end # SPARQL::Algebra
@@ -3,7 +3,15 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `langMatches` operator.
5
5
  #
6
- # @example
6
+ # [121] BuiltInCall ::= ... | 'LANGMATCHES' '(' Expression ',' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/#>
10
+ #
11
+ # SELECT *
12
+ # { :x ?p ?v . FILTER langMatches(lang(?v), "en-GB") . }
13
+ #
14
+ # @example SSE
7
15
  # (prefix ((: <http://example.org/#>))
8
16
  # (filter (langMatches (lang ?v) "en-GB")
9
17
  # (bgp (triple :x ?p ?v))))
@@ -27,7 +35,7 @@ module SPARQL; module Algebra
27
35
  # @return [RDF::Literal::Boolean] `true` or `false`
28
36
  # @raise [TypeError] if either operand is unbound
29
37
  # @raise [TypeError] if either operand is not a simple literal
30
- def apply(language_tag, language_range)
38
+ def apply(language_tag, language_range, **options)
31
39
  raise TypeError, "expected a plain RDF::Literal for language_tag, but got #{language_tag.inspect}" unless language_tag.is_a?(RDF::Literal) && language_tag.simple?
32
40
  language_tag = language_tag.to_s.downcase
33
41
 
@@ -48,6 +56,19 @@ module SPARQL; module Algebra
48
56
  RDF::Literal(language_tag.start_with?(language_range + '-'))
49
57
  end
50
58
  end
59
+
60
+ ##
61
+ #
62
+ # Returns a partial SPARQL grammar for this operator.
63
+ #
64
+ # @return [String]
65
+ def to_sparql(**options)
66
+ "langMatches(" +
67
+ operands.first.to_sparql(**options) +
68
+ ", " +
69
+ operands.last.to_sparql(**options) +
70
+ ")"
71
+ end
51
72
  end # LangMatches
52
73
  end # Operator
53
74
  end; end # SPARQL::Algebra
@@ -3,8 +3,20 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL logical `lcase` operator.
5
5
  #
6
- # @example
7
- # (lcase ?x)
6
+ # [121] BuiltInCall ::= ... | 'LCASE' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT ?s (LCASE(?str) AS ?lstr) WHERE {
11
+ # ?s :str ?str
12
+ # }
13
+ #
14
+ # @example SSE
15
+ # (prefix
16
+ # ((: <http://example.org/>))
17
+ # (project (?str ?lstr)
18
+ # (extend ((?lstr (lcase ?str)))
19
+ # (bgp (triple ?s :str ?str)))))
8
20
  #
9
21
  # @see https://www.w3.org/TR/sparql11-query/#func-lcase
10
22
  # @see https://www.w3.org/TR/xpath-functions/#func-lcase
@@ -20,12 +32,21 @@ module SPARQL; module Algebra
20
32
  # the operand
21
33
  # @return [RDF::Literal] literal of same type
22
34
  # @raise [TypeError] if the operand is not a literal value
23
- def apply(operand)
35
+ def apply(operand, **options)
24
36
  case operand
25
37
  when RDF::Literal then RDF::Literal(operand.to_s.downcase, datatype: operand.datatype, language: operand.language)
26
38
  else raise TypeError, "expected an RDF::Literal::Numeric, but got #{operand.inspect}"
27
39
  end
28
40
  end
41
+
42
+ ##
43
+ #
44
+ # Returns a partial SPARQL grammar for this operator.
45
+ #
46
+ # @return [String]
47
+ def to_sparql(**options)
48
+ "LCASE(" + operands.last.to_sparql(**options) + ")"
49
+ end
29
50
  end # LCase
30
51
  end # Operator
31
52
  end; end # SPARQL::Algebra
@@ -3,7 +3,19 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `leftjoin` operator.
5
5
  #
6
- # @example
6
+ # [57] OptionalGraphPattern ::= 'OPTIONAL' GroupGraphPattern
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example/>
10
+ # SELECT * {
11
+ # ?x :p ?v .
12
+ # OPTIONAL {
13
+ # ?y :q ?w .
14
+ # FILTER(?v=2)
15
+ # }
16
+ # }
17
+ #
18
+ # @example SSE
7
19
  # (prefix ((: <http://example/>))
8
20
  # (leftjoin
9
21
  # (bgp (triple ?x :p ?v))
@@ -112,6 +124,22 @@ module SPARQL; module Algebra
112
124
  expr ? LeftJoin.new(ops[0], ops[1], expr) : LeftJoin.new(ops[0], ops[1])
113
125
  end
114
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
+ str = operands[0].to_sparql(top_level: false, **options) +
137
+ "\nOPTIONAL { \n" +
138
+ operands[1].to_sparql(top_level: false, **options) + "\n"
139
+ str << 'FILTER (' + operands[2].to_sparql(**options) + ") \n" if operands[2]
140
+ str << '}'
141
+ top_level ? Operator.to_sparql(str, **options) : str
142
+ end
115
143
  end # LeftJoin
116
144
  end # Operator
117
145
  end; end # SPARQL::Algebra
@@ -3,8 +3,18 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL relational `<` (less than) comparison operator.
5
5
  #
6
- # @example
7
- # (< ?x ?y)
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 # LessThan
31
41
  end # Operator
@@ -3,8 +3,18 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL relational `<=` (less than or equal) comparison operator.
5
5
  #
6
- # @example
7
- # (<= ?x ?y)
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(0))
29
39
  end
30
40
  end # LessThanOrEqual
31
41
  end # Operator
@@ -6,8 +6,14 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # The LOAD operation reads an RDF document from a IRI and inserts its triples into the specified graph in the Graph Store. The specified destination graph should be created if required; again, implementations providing an update service over a fixed set of graphs must return with failure for a request that would create a disallowed graph. If the destination graph already exists, then no data in that graph will be removed.
8
8
  #
9
- # @example
10
- # (load <remote> <g>)
9
+ #
10
+ # [31] Load ::= 'LOAD' 'SILENT'? iri ( 'INTO' GraphRef )?
11
+ #
12
+ # @example SPARQL Grammar
13
+ # LOAD <http://example.org/remote> INTO GRAPH <http://example.org/g> ;
14
+ #
15
+ # @example SSE
16
+ # (update (load <http://example.org/remote> <http://example.org/g>))
11
17
  #
12
18
  # @see https://www.w3.org/TR/sparql11-update/#load
13
19
  class Load < Operator
@@ -43,6 +49,23 @@ module SPARQL; module Algebra
43
49
  ensure
44
50
  queryable
45
51
  end
52
+
53
+ ##
54
+ #
55
+ # Returns a partial SPARQL grammar for this operator.
56
+ #
57
+ # @return [String]
58
+ def to_sparql(**options)
59
+ silent = operands.first == :silent
60
+ ops = silent ? operands[1..-1] : operands
61
+ location, name = ops
62
+
63
+ str = "LOAD "
64
+ str << "SILENT " if silent
65
+ str << location.to_sparql(**options)
66
+ str << " INTO GRAPH " + name.to_sparql(**options) if name
67
+ str
68
+ end
46
69
  end # Load
47
70
  end # Operator
48
71
  end; end # SPARQL::Algebra
@@ -3,7 +3,14 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `max` set function.
5
5
  #
6
- # @example
6
+ # [127] Aggregate::= ... | 'MAX' '(' 'DISTINCT'? Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://www.example.org/>
10
+ # SELECT (MAX(?o) AS ?max)
11
+ # WHERE { ?s ?p ?o }
12
+ #
13
+ # @example SSE
7
14
  # (prefix ((: <http://www.example.org/>))
8
15
  # (project (?max)
9
16
  # (extend ((?max ??.0))
@@ -31,7 +38,7 @@ module SPARQL; module Algebra
31
38
  # @param [Enumerable<Array<RDF::Term>>] enum
32
39
  # enum of evaluated operand
33
40
  # @return [RDF::Literal] The maximum value of the terms
34
- def apply(enum)
41
+ def apply(enum, **options)
35
42
  # FIXME: we don't actually do anything with distinct
36
43
  operands.shift if distinct = (operands.first == :distinct)
37
44
  if enum.empty?
@@ -42,6 +49,15 @@ module SPARQL; module Algebra
42
49
  raise TypeError, "Maximum of non-literals: #{enum.flatten}"
43
50
  end
44
51
  end
52
+
53
+ ##
54
+ #
55
+ # Returns a partial SPARQL grammar for this operator.
56
+ #
57
+ # @return [String]
58
+ def to_sparql(**options)
59
+ "MAX(" + operands.to_sparql(**options) + ")"
60
+ end
45
61
  end # Max
46
62
  end # Operator
47
63
  end; end # SPARQL::Algebra
@@ -7,11 +7,19 @@ module SPARQL; module Algebra
7
7
  #
8
8
  # Returns the MD5 checksum, as a hex digit string, calculated on the UTF-8 representation of the simple literal or lexical form of the `xsd:string`. Hex digits `SHOULD` be in lower case.
9
9
  #
10
- # @example
11
- # (prefix ((: <http://example.org/>))
12
- # (project (?hash)
13
- # (extend ((?hash (md5 ?l)))
14
- # (bgp (triple :s1 :str ?l)))))
10
+ # [121] BuiltInCall ::= ... | 'MD5' '(' Expression ')'
11
+ #
12
+ # @example SPARQL Grammar
13
+ # PREFIX : <http://example.org/>
14
+ # SELECT (MD5(?l) AS ?hash) WHERE {
15
+ # :s1 :str ?l
16
+ # }
17
+ #
18
+ # @example SSE
19
+ # (prefix ((: <http://example.org/>))
20
+ # (project (?hash)
21
+ # (extend ((?hash (md5 ?l)))
22
+ # (bgp (triple :s1 :str ?l)))))
15
23
  #
16
24
  # @see https://www.w3.org/TR/sparql11-query/#func-md5
17
25
  class MD5 < Operator::Unary
@@ -26,11 +34,20 @@ module SPARQL; module Algebra
26
34
  # the operand
27
35
  # @return [RDF::Literal]
28
36
  # @raise [TypeError] if the operand is not a simple literal
29
- def apply(operand)
37
+ def apply(operand, **options)
30
38
  raise TypeError, "expected an RDF::Literal, but got #{operand.inspect}" unless operand.literal?
31
39
  raise TypeError, "expected simple literal or xsd:string, but got #{operand.inspect}" unless (operand.datatype || RDF::XSD.string) == RDF::XSD.string
32
40
  RDF::Literal(Digest::MD5.new.hexdigest(operand.to_s))
33
41
  end
42
+
43
+ ##
44
+ #
45
+ # Returns a partial SPARQL grammar for this operator.
46
+ #
47
+ # @return [String]
48
+ def to_sparql(**options)
49
+ "MD5(" + operands.to_sparql(**options) + ")"
50
+ end
34
51
  end # MD5
35
52
  end # Operator
36
53
  end; end # SPARQL::Algebra
@@ -3,9 +3,16 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `min` set function.
5
5
  #
6
- # @example
6
+ # [127] Aggregate::= ... | 'MIN' '(' 'DISTINCT'? Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://www.example.org/>
10
+ # SELECT (MIN(?o) AS ?min)
11
+ # WHERE { ?s :dec ?o }
12
+ #
13
+ # @example SSE
7
14
  # (prefix ((: <http://www.example.org/>))
8
- # (project (?max)
15
+ # (project (?min)
9
16
  # (extend ((?min ??.0))
10
17
  # (group () ((??.0 (min ?o)))
11
18
  # (bgp (triple ?s ?p ?o))))))
@@ -31,7 +38,7 @@ module SPARQL; module Algebra
31
38
  # @param [Enumerable<Array<RDF::Term>>] enum
32
39
  # enum of evaluated operand
33
40
  # @return [RDF::Literal] The maximum value of the terms
34
- def apply(enum)
41
+ def apply(enum, **options)
35
42
  # FIXME: we don't actually do anything with distinct
36
43
  operands.shift if distinct = (operands.first == :distinct)
37
44
  if enum.empty?
@@ -42,6 +49,15 @@ module SPARQL; module Algebra
42
49
  raise TypeError, "Minumuim of non-literals: #{enum.flatten}"
43
50
  end
44
51
  end
52
+
53
+ ##
54
+ #
55
+ # Returns a partial SPARQL grammar for this operator.
56
+ #
57
+ # @return [String]
58
+ def to_sparql(**options)
59
+ "MIN(" + operands.to_sparql(**options) + ")"
60
+ end
45
61
  end # Min
46
62
  end # Operator
47
63
  end; end # SPARQL::Algebra