sparql 3.1.8 → 3.2.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.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +88 -60
  3. data/VERSION +1 -1
  4. data/bin/sparql +15 -35
  5. data/lib/rack/sparql/conneg.rb +22 -1
  6. data/lib/sinatra/sparql/extensions.rb +1 -1
  7. data/lib/sinatra/sparql.rb +57 -12
  8. data/lib/sparql/algebra/expression.rb +63 -10
  9. data/lib/sparql/algebra/extensions.rb +110 -46
  10. data/lib/sparql/algebra/operator/abs.rb +22 -2
  11. data/lib/sparql/algebra/operator/add.rb +21 -2
  12. data/lib/sparql/algebra/operator/adjust.rb +69 -0
  13. data/lib/sparql/algebra/operator/alt.rb +26 -2
  14. data/lib/sparql/algebra/operator/and.rb +25 -3
  15. data/lib/sparql/algebra/operator/asc.rb +20 -1
  16. data/lib/sparql/algebra/operator/ask.rb +17 -1
  17. data/lib/sparql/algebra/operator/avg.rb +19 -1
  18. data/lib/sparql/algebra/operator/base.rb +18 -1
  19. data/lib/sparql/algebra/operator/bgp.rb +13 -1
  20. data/lib/sparql/algebra/operator/bnode.rb +33 -10
  21. data/lib/sparql/algebra/operator/bound.rb +22 -1
  22. data/lib/sparql/algebra/operator/ceil.rb +25 -2
  23. data/lib/sparql/algebra/operator/clear.rb +26 -2
  24. data/lib/sparql/algebra/operator/coalesce.rb +33 -11
  25. data/lib/sparql/algebra/operator/compare.rb +9 -0
  26. data/lib/sparql/algebra/operator/concat.rb +26 -2
  27. data/lib/sparql/algebra/operator/construct.rb +29 -6
  28. data/lib/sparql/algebra/operator/contains.rb +24 -2
  29. data/lib/sparql/algebra/operator/copy.rb +19 -2
  30. data/lib/sparql/algebra/operator/count.rb +52 -6
  31. data/lib/sparql/algebra/operator/create.rb +20 -2
  32. data/lib/sparql/algebra/operator/dataset.rb +37 -2
  33. data/lib/sparql/algebra/operator/datatype.rb +25 -6
  34. data/lib/sparql/algebra/operator/day.rb +25 -7
  35. data/lib/sparql/algebra/operator/delete.rb +29 -2
  36. data/lib/sparql/algebra/operator/delete_data.rb +23 -2
  37. data/lib/sparql/algebra/operator/delete_where.rb +24 -2
  38. data/lib/sparql/algebra/operator/desc.rb +20 -1
  39. data/lib/sparql/algebra/operator/describe.rb +27 -4
  40. data/lib/sparql/algebra/operator/distinct.rb +20 -3
  41. data/lib/sparql/algebra/operator/divide.rb +26 -2
  42. data/lib/sparql/algebra/operator/drop.rb +27 -3
  43. data/lib/sparql/algebra/operator/encode_for_uri.rb +22 -2
  44. data/lib/sparql/algebra/operator/equal.rb +12 -2
  45. data/lib/sparql/algebra/operator/exists.rb +28 -4
  46. data/lib/sparql/algebra/operator/exprlist.rb +15 -2
  47. data/lib/sparql/algebra/operator/extend.rb +95 -7
  48. data/lib/sparql/algebra/operator/filter.rb +27 -5
  49. data/lib/sparql/algebra/operator/floor.rb +25 -2
  50. data/lib/sparql/algebra/operator/function_call.rb +64 -0
  51. data/lib/sparql/algebra/operator/graph.rb +69 -6
  52. data/lib/sparql/algebra/operator/greater_than.rb +12 -3
  53. data/lib/sparql/algebra/operator/greater_than_or_equal.rb +12 -2
  54. data/lib/sparql/algebra/operator/group.rb +133 -8
  55. data/lib/sparql/algebra/operator/group_concat.rb +43 -7
  56. data/lib/sparql/algebra/operator/hours.rb +25 -7
  57. data/lib/sparql/algebra/operator/if.rb +20 -3
  58. data/lib/sparql/algebra/operator/in.rb +18 -1
  59. data/lib/sparql/algebra/operator/insert.rb +24 -2
  60. data/lib/sparql/algebra/operator/insert_data.rb +23 -2
  61. data/lib/sparql/algebra/operator/iri.rb +21 -4
  62. data/lib/sparql/algebra/operator/is_blank.rb +20 -3
  63. data/lib/sparql/algebra/operator/is_iri.rb +20 -3
  64. data/lib/sparql/algebra/operator/is_literal.rb +20 -3
  65. data/lib/sparql/algebra/operator/is_numeric.rb +22 -5
  66. data/lib/sparql/algebra/operator/is_triple.rb +32 -0
  67. data/lib/sparql/algebra/operator/join.rb +58 -3
  68. data/lib/sparql/algebra/operator/lang.rb +25 -0
  69. data/lib/sparql/algebra/operator/lang_matches.rb +22 -1
  70. data/lib/sparql/algebra/operator/lcase.rb +22 -2
  71. data/lib/sparql/algebra/operator/left_join.rb +44 -3
  72. data/lib/sparql/algebra/operator/less_than.rb +12 -3
  73. data/lib/sparql/algebra/operator/less_than_or_equal.rb +12 -2
  74. data/lib/sparql/algebra/operator/load.rb +25 -2
  75. data/lib/sparql/algebra/operator/max.rb +19 -1
  76. data/lib/sparql/algebra/operator/md5.rb +22 -5
  77. data/lib/sparql/algebra/operator/min.rb +21 -3
  78. data/lib/sparql/algebra/operator/minus.rb +65 -7
  79. data/lib/sparql/algebra/operator/minutes.rb +25 -7
  80. data/lib/sparql/algebra/operator/modify.rb +62 -5
  81. data/lib/sparql/algebra/operator/month.rb +25 -7
  82. data/lib/sparql/algebra/operator/move.rb +20 -2
  83. data/lib/sparql/algebra/operator/multiply.rb +26 -3
  84. data/lib/sparql/algebra/operator/negate.rb +23 -3
  85. data/lib/sparql/algebra/operator/not.rb +24 -3
  86. data/lib/sparql/algebra/operator/not_equal.rb +13 -0
  87. data/lib/sparql/algebra/operator/notexists.rb +30 -6
  88. data/lib/sparql/algebra/operator/notin.rb +20 -3
  89. data/lib/sparql/algebra/operator/notoneof.rb +21 -2
  90. data/lib/sparql/algebra/operator/now.rb +24 -5
  91. data/lib/sparql/algebra/operator/object.rb +32 -0
  92. data/lib/sparql/algebra/operator/or.rb +26 -3
  93. data/lib/sparql/algebra/operator/order.rb +64 -1
  94. data/lib/sparql/algebra/operator/path.rb +29 -2
  95. data/lib/sparql/algebra/operator/path_opt.rb +28 -65
  96. data/lib/sparql/algebra/operator/path_plus.rb +37 -10
  97. data/lib/sparql/algebra/operator/path_range.rb +178 -0
  98. data/lib/sparql/algebra/operator/path_star.rb +25 -4
  99. data/lib/sparql/algebra/operator/path_zero.rb +110 -0
  100. data/lib/sparql/algebra/operator/plus.rb +49 -8
  101. data/lib/sparql/algebra/operator/predicate.rb +32 -0
  102. data/lib/sparql/algebra/operator/prefix.rb +24 -3
  103. data/lib/sparql/algebra/operator/project.rb +111 -6
  104. data/lib/sparql/algebra/operator/rand.rb +30 -2
  105. data/lib/sparql/algebra/operator/reduced.rb +20 -3
  106. data/lib/sparql/algebra/operator/regex.rb +26 -18
  107. data/lib/sparql/algebra/operator/replace.rb +26 -6
  108. data/lib/sparql/algebra/operator/reverse.rb +31 -2
  109. data/lib/sparql/algebra/operator/round.rb +25 -2
  110. data/lib/sparql/algebra/operator/same_term.rb +24 -6
  111. data/lib/sparql/algebra/operator/sample.rb +32 -8
  112. data/lib/sparql/algebra/operator/seconds.rb +25 -7
  113. data/lib/sparql/algebra/operator/seq.rb +23 -5
  114. data/lib/sparql/algebra/operator/sequence.rb +14 -11
  115. data/lib/sparql/algebra/operator/sha1.rb +18 -1
  116. data/lib/sparql/algebra/operator/sha256.rb +18 -1
  117. data/lib/sparql/algebra/operator/sha384.rb +18 -1
  118. data/lib/sparql/algebra/operator/sha512.rb +18 -1
  119. data/lib/sparql/algebra/operator/slice.rb +27 -5
  120. data/lib/sparql/algebra/operator/str.rb +21 -1
  121. data/lib/sparql/algebra/operator/strafter.rb +25 -2
  122. data/lib/sparql/algebra/operator/strbefore.rb +25 -2
  123. data/lib/sparql/algebra/operator/strdt.rb +22 -1
  124. data/lib/sparql/algebra/operator/strends.rb +25 -3
  125. data/lib/sparql/algebra/operator/strlang.rb +24 -6
  126. data/lib/sparql/algebra/operator/strlen.rb +23 -2
  127. data/lib/sparql/algebra/operator/strstarts.rb +25 -2
  128. data/lib/sparql/algebra/operator/struuid.rb +29 -9
  129. data/lib/sparql/algebra/operator/subject.rb +32 -0
  130. data/lib/sparql/algebra/operator/substr.rb +23 -2
  131. data/lib/sparql/algebra/operator/subtract.rb +37 -7
  132. data/lib/sparql/algebra/operator/sum.rb +24 -6
  133. data/lib/sparql/algebra/operator/table.rb +85 -4
  134. data/lib/sparql/algebra/operator/timezone.rb +25 -7
  135. data/lib/sparql/algebra/operator/triple.rb +24 -0
  136. data/lib/sparql/algebra/operator/tz.rb +24 -7
  137. data/lib/sparql/algebra/operator/ucase.rb +23 -2
  138. data/lib/sparql/algebra/operator/union.rb +29 -6
  139. data/lib/sparql/algebra/operator/update.rb +46 -4
  140. data/lib/sparql/algebra/operator/using.rb +49 -2
  141. data/lib/sparql/algebra/operator/uuid.rb +27 -8
  142. data/lib/sparql/algebra/operator/with.rb +38 -4
  143. data/lib/sparql/algebra/operator/year.rb +25 -7
  144. data/lib/sparql/algebra/operator.rb +150 -12
  145. data/lib/sparql/algebra/query.rb +5 -3
  146. data/lib/sparql/algebra/sxp_extensions.rb +3 -3
  147. data/lib/sparql/algebra.rb +42 -6
  148. data/lib/sparql/grammar/meta.rb +1367 -267
  149. data/lib/sparql/grammar/parser11.rb +829 -331
  150. data/lib/sparql/grammar/terminals11.rb +2 -2
  151. data/lib/sparql/grammar.rb +6 -4
  152. data/lib/sparql/results.rb +3 -2
  153. data/lib/sparql/server.rb +93 -0
  154. data/lib/sparql.rb +8 -5
  155. metadata +57 -35
@@ -3,7 +3,18 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `str` operator.
5
5
  #
6
- # @example
6
+ # [121] BuiltInCall ::= ... | 'STR' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
10
+ # PREFIX : <http://example.org/things#>
11
+ # SELECT ?x ?v
12
+ # WHERE
13
+ # { ?x :p ?v .
14
+ # FILTER ( str(?v) = "1" ) .
15
+ # }
16
+ #
17
+ # @example SSE
7
18
  # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
8
19
  # (: <http://example.org/things#>))
9
20
  # (project (?x ?v)
@@ -30,6 +41,15 @@ module SPARQL; module Algebra
30
41
  else raise TypeError, "expected an RDF::Literal or RDF::URI, but got #{term.inspect}"
31
42
  end
32
43
  end
44
+
45
+ ##
46
+ #
47
+ # Returns a partial SPARQL grammar for this operator.
48
+ #
49
+ # @return [String]
50
+ def to_sparql(**options)
51
+ "str(" + operands.first.to_sparql(**options) + ")"
52
+ end
33
53
  end # Str
34
54
  end # Operator
35
55
  end; end # SPARQL::Algebra
@@ -3,8 +3,22 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # A SPARQL `strafter` operator.
5
5
  #
6
- # @example
7
- # (strafter ?x ?y)
6
+ # [121] BuiltInCall ::= ... | 'STRAFTER' '(' Expression ',' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
11
+ # SELECT ?s (STRAFTER(?str,"e") AS ?suffix) WHERE {
12
+ # ?s :str ?str
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix
17
+ # ((: <http://example.org/>)
18
+ # (xsd: <http://www.w3.org/2001/XMLSchema#>))
19
+ # (project (?s ?suffix)
20
+ # (extend ((?suffix (strafter ?str "e")))
21
+ # (bgp (triple ?s :str ?str)))))
8
22
  #
9
23
  # @see https://www.w3.org/TR/sparql11-query/#func-strafter
10
24
  # @see https://www.w3.org/TR/xpath-functions/#func-substring-after
@@ -52,6 +66,15 @@ module SPARQL; module Algebra
52
66
  RDF::Literal(parts.last, datatype: left.datatype, language: left.language)
53
67
  end
54
68
  end
69
+
70
+ ##
71
+ #
72
+ # Returns a partial SPARQL grammar for this operator.
73
+ #
74
+ # @return [String]
75
+ def to_sparql(**options)
76
+ "STRAFTER(" + operands.to_sparql(delimiter: ', ', **options) + ")"
77
+ end
55
78
  end # StrAfter
56
79
  end # Operator
57
80
  end; end # SPARQL::Algebra
@@ -3,8 +3,22 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # A SPARQL `strbefore` operator.
5
5
  #
6
- # @example
7
- # (strbefore ?x ?y)
6
+ # [121] BuiltInCall ::= ... | 'STRBEFORE' '(' Expression ',' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
11
+ # SELECT ?s (STRBEFORE(?str,"s") AS ?prefix) WHERE {
12
+ # ?s :str ?str
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix
17
+ # ((: <http://example.org/>)
18
+ # (xsd: <http://www.w3.org/2001/XMLSchema#>))
19
+ # (project (?s ?prefix)
20
+ # (extend ((?prefix (strbefore ?str "s")))
21
+ # (bgp (triple ?s :str ?str)))))
8
22
  #
9
23
  # @see https://www.w3.org/TR/sparql11-query/#func-strbefore
10
24
  # @see https://www.w3.org/TR/xpath-functions/#func-substring-before
@@ -54,6 +68,15 @@ module SPARQL; module Algebra
54
68
  RDF::Literal(parts.first, language: left.language, datatype: left.datatype)
55
69
  end
56
70
  end
71
+
72
+ ##
73
+ #
74
+ # Returns a partial SPARQL grammar for this operator.
75
+ #
76
+ # @return [String]
77
+ def to_sparql(**options)
78
+ "STRBEFORE(" + operands.to_sparql(delimiter: ', ', **options) + ")"
79
+ end
57
80
  end # StrBefore
58
81
  end # Operator
59
82
  end; end # SPARQL::Algebra
@@ -3,7 +3,19 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `strdt` operator.
5
5
  #
6
- # @example
6
+ # [121] BuiltInCall ::= ... | 'STRDT' '(' Expression ',' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
11
+ # SELECT ?s (STRDT(?str,xsd:string) AS ?str1) WHERE {
12
+ # ?s :str ?str
13
+ # FILTER(LANGMATCHES(LANG(?str), "en"))
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix
18
+ # ((: <http://example.org/>) (xsd: <http://www.w3.org/2001/XMLSchema#>))
7
19
  # (project (?s ?str1)
8
20
  # (extend ((?str1 (strdt ?str xsd:string)))
9
21
  # (filter (langMatches (lang ?str) "en")
@@ -28,6 +40,15 @@ module SPARQL; module Algebra
28
40
  raise TypeError, "Literal #{value.inspect} is not simple" unless value.simple?
29
41
  RDF::Literal.new(value.to_s, datatype: datatypeIRI)
30
42
  end
43
+
44
+ ##
45
+ #
46
+ # Returns a partial SPARQL grammar for this operator.
47
+ #
48
+ # @return [String]
49
+ def to_sparql(**options)
50
+ "STRDT(" + operands.to_sparql(delimiter: ', ', **options) + ")"
51
+ end
31
52
  end # StrDT
32
53
  end # Operator
33
54
  end; end # SPARQL::Algebra
@@ -1,10 +1,23 @@
1
1
  module SPARQL; module Algebra
2
2
  class Operator
3
3
  ##
4
- # A SPARQL `contains` operator.
4
+ # A SPARQL `strends` operator.
5
5
  #
6
- # @example
7
- # (strends ?x ?y)
6
+ # [121] BuiltInCall ::= ... | 'STRENDS' '(' Expression ',' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT ?s ?str WHERE {
11
+ # ?s :str ?str
12
+ # FILTER STRENDS(?str, "a")
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix
17
+ # ((: <http://example.org/>))
18
+ # (project (?s ?str)
19
+ # (filter (strends ?str "a")
20
+ # (bgp (triple ?s :str ?str)))))
8
21
  #
9
22
  # @see https://www.w3.org/TR/sparql11-query/#func-strends
10
23
  # @see https://wwww.w3.org/TR/xpath-functions/#func-ends-with
@@ -41,6 +54,15 @@ module SPARQL; module Algebra
41
54
  else RDF::Literal::FALSE
42
55
  end
43
56
  end
57
+
58
+ ##
59
+ #
60
+ # Returns a partial SPARQL grammar for this operator.
61
+ #
62
+ # @return [String]
63
+ def to_sparql(**options)
64
+ "STRENDS(" + operands.to_sparql(delimiter: ', ', **options) + ")"
65
+ end
44
66
  end # StrEnds
45
67
  end # Operator
46
68
  end; end # SPARQL::Algebra
@@ -3,12 +3,21 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `strlang` operator.
5
5
  #
6
- # @example
7
- # (prefix ((: <http://example.org/>))
8
- # (project (?s ?s2)
9
- # (extend ((?s2 (strlang ?str "en-US")))
10
- # (filter (langMatches (lang ?str) "en")
11
- # (bgp (triple ?s :str ?str))))))
6
+ # [121] BuiltInCall ::= ... | 'STRLANG' '(' Expression ',' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT ?s (STRLANG(?str,"en-US") AS ?s2) WHERE {
11
+ # ?s :str ?str
12
+ # FILTER(LANGMATCHES(LANG(?str), "en"))
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/>))
17
+ # (project (?s ?s2)
18
+ # (extend ((?s2 (strlang ?str "en-US")))
19
+ # (filter (langMatches (lang ?str) "en")
20
+ # (bgp (triple ?s :str ?str))))))
12
21
  #
13
22
  # @see https://www.w3.org/TR/sparql11-query/#func-strlang
14
23
  class StrLang < Operator::Binary
@@ -29,6 +38,15 @@ module SPARQL; module Algebra
29
38
  raise TypeError, "Literal #{value.inspect} is not simple" unless value.simple?
30
39
  RDF::Literal.new(value.to_s, language: langTag.to_s)
31
40
  end
41
+
42
+ ##
43
+ #
44
+ # Returns a partial SPARQL grammar for this operator.
45
+ #
46
+ # @return [String]
47
+ def to_sparql(**options)
48
+ "STRLANG(" + operands.to_sparql(delimiter: ', ', **options) + ")"
49
+ end
32
50
  end # StrLang
33
51
  end # Operator
34
52
  end; end # SPARQL::Algebra
@@ -3,8 +3,20 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `strlen` operator.
5
5
  #
6
- # @example
7
- # (strlen ?x)
6
+ # [121] BuiltInCall ::= ... 'STRLEN' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT ?str (STRLEN(?str) AS ?len) WHERE {
11
+ # ?s :str ?str
12
+ # }
13
+ #
14
+ # @example SSE
15
+ # (prefix
16
+ # ((: <http://example.org/>))
17
+ # (project (?str ?len)
18
+ # (extend ((?len (strlen ?str)))
19
+ # (bgp (triple ?s :str ?str)))))
8
20
  #
9
21
  # @see https://www.w3.org/TR/sparql11-query/#func-strlen
10
22
  # @see https://www.w3.org/TR/xpath-functions/#func-string-length
@@ -29,6 +41,15 @@ module SPARQL; module Algebra
29
41
  raise TypeError, "expected a plain RDF::Literal, but got #{operand.inspect}" unless operand.literal? && operand.plain?
30
42
  RDF::Literal(operand.to_s.length)
31
43
  end
44
+
45
+ ##
46
+ #
47
+ # Returns a partial SPARQL grammar for this operator.
48
+ #
49
+ # @return [String]
50
+ def to_sparql(**options)
51
+ "STRLEN(" + operands.to_sparql(delimiter: ', ', **options) + ")"
52
+ end
32
53
  end # StrLen
33
54
  end # Operator
34
55
  end; end # SPARQL::Algebra
@@ -3,8 +3,22 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # A SPARQL `strstarts` operator.
5
5
  #
6
- # @example
7
- # (strstarts ?x ?y)
6
+ # [121] BuiltInCall ::= ... | 'STRSTARTS' '(' Expression ',' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+
11
+ # SELECT ?s ?str WHERE {
12
+ # ?s :str ?str
13
+ # FILTER STRSTARTS(?str, "a")
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix
18
+ # ((: <http://example.org/>))
19
+ # (project (?s ?str)
20
+ # (filter (strstarts ?str "a")
21
+ # (bgp (triple ?s :str ?str)))))
8
22
  #
9
23
  # @see https://www.w3.org/TR/sparql11-query/#func-strstarts
10
24
  # @see https://www.w3.org/TR/xpath-functions/#func-starts-with
@@ -41,6 +55,15 @@ module SPARQL; module Algebra
41
55
  else RDF::Literal::FALSE
42
56
  end
43
57
  end
58
+
59
+ ##
60
+ #
61
+ # Returns a partial SPARQL grammar for this operator.
62
+ #
63
+ # @return [String]
64
+ def to_sparql(**options)
65
+ "STRSTARTS(" + operands.to_sparql(delimiter: ', ', **options) + ")"
66
+ end
44
67
  end # StrStarts
45
68
  end # Operator
46
69
  end; end # SPARQL::Algebra
@@ -3,16 +3,27 @@ require 'securerandom'
3
3
  module SPARQL; module Algebra
4
4
  class Operator
5
5
  ##
6
- # The SPARQL `uuid` function.
6
+ # [121] BuiltInCall ::= ... | 'STRUUID' NIL
7
7
  #
8
- # @example
9
- # (prefix ((: <http://example.org/>)
10
- # (xsd: <http://www.w3.org/2001/XMLSchema#>))
11
- # (project (?length)
12
- # (extend ((?length (strlen ?uuid)))
13
- # (filter (&& (isLiteral ?uuid) (regex ?uuid "^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$" "i"))
14
- # (extend ((?uuid (struuid)))
15
- # (bgp))))))
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
11
+ # SELECT (STRLEN(?uuid) AS ?length)
12
+ # WHERE {
13
+ # BIND(STRUUID() AS ?uuid)
14
+ # FILTER(ISLITERAL(?uuid) && REGEX(?uuid, "^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$", "i"))
15
+ # }
16
+ #
17
+ # @example SSE
18
+ # (prefix ((: <http://example.org/>) (xsd: <http://www.w3.org/2001/XMLSchema#>))
19
+ # (project (?length)
20
+ # (extend ((?length (strlen ?uuid)))
21
+ # (filter
22
+ # (&&
23
+ # (isLiteral ?uuid)
24
+ # (regex ?uuid "^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$" "i"))
25
+ # (extend ((?uuid (struuid)))
26
+ # (bgp))))))
16
27
  #
17
28
  # @see https://www.w3.org/TR/sparql11-query/#func-struuid
18
29
  class StrUUID < Operator::Nullary
@@ -27,6 +38,15 @@ module SPARQL; module Algebra
27
38
  def apply(**options)
28
39
  RDF::Literal(SecureRandom.uuid)
29
40
  end
41
+
42
+ ##
43
+ #
44
+ # Returns a partial SPARQL grammar for this operator.
45
+ #
46
+ # @return [String]
47
+ def to_sparql(**options)
48
+ "STRUUID(" + operands.to_sparql(delimiter: ', ', **options) + ")"
49
+ end
30
50
  end # StrUUID
31
51
  end # Operator
32
52
  end; end # SPARQL::Algebra
@@ -7,6 +7,29 @@ module SPARQL; module Algebra
7
7
  #
8
8
  # If triple is an RDF-star triple, the function returns the subject of this triple. Passing anything other than an RDF-star triple is an error.
9
9
  #
10
+ # [121] BuiltInCall ::= ... | 'SUBJECT' '(' Expression ')'
11
+ #
12
+ # @example SPARQL Grammar
13
+ # PREFIX : <http://example.com/ns#>
14
+ # SELECT * {
15
+ # ?t :source :g
16
+ # FILTER(isTriple(?t))
17
+ # FILTER(SUBJECT(?t) = :s)
18
+ # FILTER(PREDICATE(?t) = :p)
19
+ # FILTER(OBJECT(?t) = :o)
20
+ # }
21
+ #
22
+ # @example SSE
23
+ # (prefix
24
+ # ((: <http://example.com/ns#>))
25
+ # (filter
26
+ # (exprlist
27
+ # (isTRIPLE ?t)
28
+ # (= (subject ?t) :s)
29
+ # (= (predicate ?t) :p)
30
+ # (= (object ?t) :o))
31
+ # (bgp (triple ?t :source :g))) )
32
+ #
10
33
  # @see https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#subject
11
34
  class Subject < Operator::Unary
12
35
  include Evaluatable
@@ -24,6 +47,15 @@ module SPARQL; module Algebra
24
47
  raise TypeError, "expected an RDF::Statement, but got #{operand.inspect}" unless operand.is_a?(RDF::Statement)
25
48
  operand.subject
26
49
  end
50
+
51
+ ##
52
+ #
53
+ # Returns a partial SPARQL grammar for this operator.
54
+ #
55
+ # @return [String]
56
+ def to_sparql(**options)
57
+ "SUBJECT(" + operands.last.to_sparql(**options) + ")"
58
+ end
27
59
  end # Subject
28
60
  end # Operator
29
61
  end; end # SPARQL::Algebra
@@ -3,8 +3,20 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # A SPARQL `substr` operator.
5
5
  #
6
- # @example
7
- # (substr ?x ?y)
6
+ # [123] SubstringExpression ::= 'SUBSTR' '(' Expression ',' Expression ( ',' Expression )? ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT ?s ?str (SUBSTR(?str,1,1) AS ?substr)
11
+ # WHERE {
12
+ # ?s :str ?str
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/>))
17
+ # (project (?s ?str ?substr)
18
+ # (extend ((?substr (substr ?str 1 1)))
19
+ # (bgp (triple ?s :str ?str)))))
8
20
  #
9
21
  # @see https://www.w3.org/TR/sparql11-query/#func-substr
10
22
  # @see https://www.w3.org/TR/xpath-functions/#func-substring
@@ -75,6 +87,15 @@ module SPARQL; module Algebra
75
87
  def to_sxp_bin
76
88
  [NAME] + operands.reject {|o| o.to_s == ""}
77
89
  end
90
+
91
+ ##
92
+ #
93
+ # Returns a partial SPARQL grammar for this operator.
94
+ #
95
+ # @return [String]
96
+ def to_sparql(**options)
97
+ "SUBSTR(" + operands.to_sparql(delimiter: ', ', **options) + ")"
98
+ end
78
99
  end # SubStr
79
100
  end # Operator
80
101
  end; end # SPARQL::Algebra
@@ -2,8 +2,25 @@ module SPARQL; module Algebra
2
2
  class Operator
3
3
  ##
4
4
  # The SPARQL numeric `subtract` operator.
5
- # (- ?x ?y)
6
- # (subtract ?x ?y)
5
+ #
6
+ # [116] AdditiveExpression ::= MultiplicativeExpression ( '-' MultiplicativeExpression )?
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT ?s WHERE {
11
+ # ?s :p ?o .
12
+ # ?s2 :p ?o2 .
13
+ # FILTER(?o - ?o2 = 3) .
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix
18
+ # ((: <http://example.org/>))
19
+ # (project (?s)
20
+ # (filter (= (- ?o ?o2) 3)
21
+ # (bgp
22
+ # (triple ?s :p ?o)
23
+ # (triple ?s2 :p ?o2)))))
7
24
  #
8
25
  # @see https://www.w3.org/TR/xpath-functions/#func-numeric-subtract
9
26
  class Subtract < Operator::Binary
@@ -14,19 +31,32 @@ module SPARQL; module Algebra
14
31
  ##
15
32
  # Returns the arithmetic difference of the operands.
16
33
  #
17
- # @param [RDF::Literal::Numeric] left
34
+ # @param [RDF::Literal::Numeric, RDF::Literal::Temporal] left
18
35
  # a numeric literal
19
- # @param [RDF::Literal::Numeric] right
36
+ # @param [RDF::Literal::Numeric, RDF::Literal::Temporal, RDF::Literal::Duration] right
20
37
  # a numeric literal
21
- # @return [RDF::Literal::Numeric]
22
- # @raise [TypeError] if either operand is not a numeric literal
38
+ # @return [RDF::Literal::Numeric, RDF::Literal::Temporal, RDF::Literal::Duration]
39
+ # @raise [TypeError] if either operand is neither a numeric nor a temporal literal
23
40
  def apply(left, right, **options)
24
41
  case
25
42
  when left.is_a?(RDF::Literal::Numeric) && right.is_a?(RDF::Literal::Numeric)
26
43
  left - right
27
- else raise TypeError, "expected two RDF::Literal::Numeric operands, but got #{left.inspect} and #{right.inspect}"
44
+ when left.is_a?(RDF::Literal::Temporal) && right.is_a?(RDF::Literal::Temporal)
45
+ left - right
46
+ when left.is_a?(RDF::Literal::Temporal) && right.is_a?(RDF::Literal::Duration)
47
+ left - right
48
+ else raise TypeError, "expected two RDF::Literal::Numeric, Temporal operands, or a Temporal and a Duration, but got #{left.inspect} and #{right.inspect}"
28
49
  end
29
50
  end
51
+
52
+ ##
53
+ #
54
+ # Returns a partial SPARQL grammar for this operator.
55
+ #
56
+ # @return [String]
57
+ def to_sparql(**options)
58
+ "(#{operands.first.to_sparql(**options)} - #{operands.last.to_sparql(**options)})"
59
+ end
30
60
  end # Subtract
31
61
  end # Operator
32
62
  end; end # SPARQL::Algebra
@@ -3,12 +3,19 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `sum` set function.
5
5
  #
6
- # @example
7
- # (prefix ((: <http://www.example.org/>))
8
- # (project (?sum)
9
- # (extend ((?sum ??.0))
10
- # (group () ((??.0 (sum ?o)))
11
- # (bgp (triple ?s :dec ?o))))))
6
+ # [127] Aggregate::= ... | 'SUM' '(' 'DISTINCT'? Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://www.example.org/>
10
+ # SELECT (SUM(?o) AS ?sum)
11
+ # WHERE { ?s :dec ?o }
12
+ #
13
+ # @example SSE
14
+ # (prefix ((: <http://www.example.org/>))
15
+ # (project (?sum)
16
+ # (extend ((?sum ??.0))
17
+ # (group () ((??.0 (sum ?o)))
18
+ # (bgp (triple ?s :dec ?o))))))
12
19
  #
13
20
  # @see https://www.w3.org/TR/sparql11-query/#defn_aggSum
14
21
  class Sum < Operator
@@ -33,6 +40,17 @@ module SPARQL; module Algebra
33
40
  raise TypeError, "Averaging non-numeric types: #{enum.flatten}"
34
41
  end
35
42
  end
43
+
44
+ ##
45
+ #
46
+ # Returns a partial SPARQL grammar for this operator.
47
+ #
48
+ # @return [String]
49
+ def to_sparql(**options)
50
+ distinct = operands.first == :distinct
51
+ args = distinct ? operands[1..-1] : operands
52
+ "SUM(#{'DISTINCT ' if distinct}#{args.to_sparql(**options)})"
53
+ end
36
54
  end # Sum
37
55
  end # Operator
38
56
  end; end # SPARQL::Algebra
@@ -6,13 +6,59 @@ module SPARQL; module Algebra
6
6
  # This is used to provide inline values. Each row becomes
7
7
  # a solution.
8
8
  #
9
- # @example
10
- # (table (vars ?book ?title)
11
- # (row (?title "SPARQL Tutorial"))
12
- # (row (?book :book2)))
9
+ # [28] ValuesClause ::= ( 'VALUES' DataBlock )?
10
+ #
11
+ # @example SPARQL Grammar (ValuesClause)
12
+ # PREFIX dc: <http://purl.org/dc/elements/1.1/>
13
+ # PREFIX : <http://example.org/book/>
14
+ # PREFIX ns: <http://example.org/ns#>
15
+ # SELECT ?book ?title ?price {
16
+ # ?book dc:title ?title ;
17
+ # ns:price ?price .
18
+ # }
19
+ # VALUES ?book { :book1 }
20
+ #
21
+ # @example SSE (ValuesClause)
22
+ # (prefix ((dc: <http://purl.org/dc/elements/1.1/>)
23
+ # (: <http://example.org/book/>)
24
+ # (ns: <http://example.org/ns#>))
25
+ # (project (?book ?title ?price)
26
+ # (join
27
+ # (bgp (triple ?book dc:title ?title) (triple ?book ns:price ?price))
28
+ # (table (vars ?book) (row (?book :book1)))) ))
29
+ #
30
+ # @example SPARQL Grammar (empty query no values)
31
+ # SELECT * { } VALUES () { }
32
+ #
33
+ # @example SSE (empty query no values)
34
+ # (join (bgp) (table empty))
35
+ #
36
+ # [61] InlineData ::= 'VALUES' DataBlock
37
+ #
38
+ # @example SPARQL Grammar (InlineData)
39
+ # PREFIX dc: <http://purl.org/dc/elements/1.1/>
40
+ # PREFIX : <http://example.org/book/>
41
+ # PREFIX ns: <http://example.org/ns#>
42
+ #
43
+ # SELECT ?book ?title ?price
44
+ # {
45
+ # VALUES ?book { :book1 }
46
+ # ?book dc:title ?title ;
47
+ # ns:price ?price .
48
+ # }
49
+ #
50
+ # @example SSE (InlineData)
51
+ # (prefix ((dc: <http://purl.org/dc/elements/1.1/>)
52
+ # (: <http://example.org/book/>)
53
+ # (ns: <http://example.org/ns#>))
54
+ # (project (?book ?title ?price)
55
+ # (join
56
+ # (table (vars ?book) (row (?book :book1)))
57
+ # (bgp (triple ?book dc:title ?title) (triple ?book ns:price ?price))) ))
13
58
  #
14
59
  # @example empty table
15
60
  # (table unit)
61
+ #
16
62
  # @see https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#inline-data
17
63
  class Table < Operator
18
64
  include Query
@@ -43,9 +89,44 @@ module SPARQL; module Algebra
43
89
  end
44
90
  @solutions << RDF::Query::Solution.new(bindings)
45
91
  end
92
+ @solutions.variable_names = self.variables.keys
46
93
  @solutions.each(&block) if block_given?
47
94
  @solutions
48
95
  end
96
+
97
+ ##
98
+ # In-scope variables for a table are the variables operand
99
+ #
100
+ # @return [Hash{Symbol => RDF::Query::Variable}]
101
+ def variables
102
+ in_scope = operands.first.is_a?(Array) ? operands.first[1..-1] : []
103
+ in_scope.inject({}) {|memo, v| memo.merge(v.variables)}
104
+ end
105
+
106
+ ##
107
+ #
108
+ # Returns a partial SPARQL grammar for this operator.
109
+ #
110
+ # @param [Boolean] top_level (true)
111
+ # Treat this as a top-level, generating SELECT ... WHERE {}
112
+ # @return [String]
113
+ def to_sparql(top_level: true, **options)
114
+ str = "VALUES (#{Array(operands.first)[1..-1].map { |e| e.to_sparql(**options) }.join(' ')}) {\n"
115
+ operands[1..-1].each do |row|
116
+ line = '('
117
+ row[1..-1].each do |col|
118
+ v = col[1].to_sparql(**options)
119
+ line << v + ' '
120
+ end
121
+ line = line.chomp(' ')
122
+ line << ")\n"
123
+
124
+ str << line
125
+ end
126
+
127
+ str << "}\n"
128
+ top_level ? Operator.to_sparql(str, **options) : str
129
+ end
49
130
  end # Table
50
131
  end # Operator
51
132
  end; end # SPARQL::Algebra