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,15 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `if` function.
5
5
  #
6
- # @example
6
+ # [121] BuiltInCall ::= ... | 'IF' '(' Expression ',' Expression ',' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # BASE <http://example.org/>
10
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
11
+ # SELECT ?o (IF(lang(?o) = "ja", true, false) AS ?integer)
12
+ # WHERE { ?s ?p ?o }
13
+ #
14
+ # @example SSE
7
15
  # (base <http://example.org/>
8
16
  # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>))
9
17
  # (project (?o ?integer)
@@ -37,8 +45,17 @@ module SPARQL; module Algebra
37
45
  operand(0).evaluate(bindings, depth: options[:depth].to_i + 1, **options) == RDF::Literal::TRUE ?
38
46
  operand(1).evaluate(bindings, depth: options[:depth].to_i + 1, **options) :
39
47
  operand(2).evaluate(bindings, depth: options[:depth].to_i + 1, **options)
40
- rescue
41
- raise TypeError
48
+ rescue
49
+ raise TypeError
50
+ end
51
+
52
+ ##
53
+ #
54
+ # Returns a partial SPARQL grammar for this operator.
55
+ #
56
+ # @return [String]
57
+ def to_sparql(**options)
58
+ "IF(" + operands.to_sparql(delimiter: ', ', **options) + ")"
42
59
  end
43
60
  end # If
44
61
  end # Operator
@@ -3,7 +3,12 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `in` operator.
5
5
  #
6
- # @example
6
+ # [114] RelationalExpression ::= NumericExpression ('IN' ExpressionList)?
7
+ #
8
+ # @example SPARQL Grammar
9
+ # ASK { FILTER(2 IN (1, 2, 3)) }
10
+ #
11
+ # @example SSE
7
12
  # (ask (filter (in 2 1 2 3) (bgp)))
8
13
  #
9
14
  # @see https://www.w3.org/TR/sparql11-query/#func-in
@@ -54,6 +59,18 @@ module SPARQL; module Algebra
54
59
  else RDF::Literal::FALSE
55
60
  end
56
61
  end
62
+
63
+ ##
64
+ #
65
+ # Returns a partial SPARQL grammar for this operator.
66
+ #
67
+ # @return [String]
68
+ def to_sparql(**options)
69
+ "(" + operands.first.to_sparql(**options) +
70
+ " IN (" +
71
+ operands[1..-1].map {|e| e.to_sparql(**options)}.join(", ") +
72
+ "))"
73
+ end
57
74
  end # In
58
75
  end # Operator
59
76
  end; end # SPARQL::Algebra
@@ -6,8 +6,19 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # The INSERT operation is a form of the DELETE/INSERT operation having no DELETE section
8
8
  #
9
- # @example
10
- # (insert ((triple ?s ?p "q")))
9
+ # [43] InsertClause ::= 'INSERT' QuadPattern
10
+ #
11
+ # @example SPARQL Grammar
12
+ # PREFIX : <http://example.org/>
13
+ # INSERT { ?s ?p "q" }
14
+ # WHERE { ?s ?p ?o }
15
+ #
16
+ # @example SSE
17
+ # (prefix
18
+ # ((: <http://example.org/>))
19
+ # (update
20
+ # (modify (bgp (triple ?s ?p ?o))
21
+ # (insert ((triple ?s ?p "q"))))))
11
22
  #
12
23
  # @see https://www.w3.org/TR/sparql11-update/#insert
13
24
  class Insert < Operator::Unary
@@ -51,6 +62,17 @@ module SPARQL; module Algebra
51
62
  end
52
63
  queryable
53
64
  end
65
+
66
+ ##
67
+ #
68
+ # Returns a partial SPARQL grammar for this term.
69
+ #
70
+ # @return [String]
71
+ def to_sparql(**options)
72
+ "INSERT {\n" +
73
+ operands.first.to_sparql(delimiter: " .\n", **options) +
74
+ "\n}"
75
+ end
54
76
  end # Insert
55
77
  end # Operator
56
78
  end; end # SPARQL::Algebra
@@ -6,8 +6,18 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # The INSERT DATA operation adds some triples, given inline in the request, into the Graph Store
8
8
  #
9
- # @example
10
- # (insertData ((graph <http://example.org/g1> ((triple :s :p :o)))))
9
+ # [38] InsertData ::= 'INSERT DATA' QuadData
10
+ #
11
+ # @example SPARQL Grammar
12
+ # PREFIX : <http://example.org/ns#>
13
+ # INSERT DATA { GRAPH <http://example.org/g1> { :s :p :o } }
14
+ #
15
+ # @example SSE
16
+ # (prefix
17
+ # ((: <http://example.org/ns#>))
18
+ # (update
19
+ # (insertData (
20
+ # (graph <http://example.org/g1> ((triple :s :p :o)))))))
11
21
  #
12
22
  # @see https://www.w3.org/TR/sparql11-update/#insertData
13
23
  class InsertData < Operator::Unary
@@ -36,6 +46,17 @@ module SPARQL; module Algebra
36
46
  end
37
47
  queryable
38
48
  end
49
+
50
+ ##
51
+ #
52
+ # Returns a partial SPARQL grammar for this term.
53
+ #
54
+ # @return [String]
55
+ def to_sparql(**options)
56
+ "INSERT DATA {\n" +
57
+ operands.first.to_sparql(top_level: false, delimiter: ". \n", **options) +
58
+ "\n}"
59
+ end
39
60
  end # InsertData
40
61
  end # Operator
41
62
  end; end # SPARQL::Algebra
@@ -3,10 +3,18 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `iri` operator.
5
5
  #
6
- # @example
7
- # (base <http://example.org/> (project (?uri ?iri)
8
- # (extend ((?uri (uri "uri")) (?iri (iri "iri")))
9
- # (bgp))))
6
+ # [121] BuiltInCall ::= ... | 'IRI' '(' Expression ')' | 'URI' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # BASE <http://example.org/>
10
+ # SELECT (URI("uri") AS ?uri) (IRI("iri") AS ?iri)
11
+ # WHERE {}
12
+ #
13
+ # @example SSE
14
+ # (base <http://example.org/>
15
+ # (project (?uri ?iri)
16
+ # (extend ((?uri (iri "uri")) (?iri (iri "iri")))
17
+ # (bgp))))
10
18
  #
11
19
  # @see https://www.w3.org/TR/sparql11-query/#func-iri
12
20
  class IRI < Operator::Unary
@@ -35,6 +43,15 @@ module SPARQL; module Algebra
35
43
  base.join(literal.to_s)
36
44
  end
37
45
 
46
+ ##
47
+ #
48
+ # Returns a partial SPARQL grammar for this operator.
49
+ #
50
+ # @return [String]
51
+ def to_sparql(**options)
52
+ "IRI(" + operands.last.to_sparql(**options) + ")"
53
+ end
54
+
38
55
  Operator::URI = IRI
39
56
  end # IRI
40
57
  end # Operator
@@ -3,9 +3,17 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `isBlank` operator.
5
5
  #
6
- # @example
7
- # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
8
- # (: <http://example.org/things#>))
6
+ # [121] BuiltInCall ::= ... | 'isBlank' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/things#>
10
+ # SELECT ?x ?v WHERE {
11
+ # ?x :p ?v .
12
+ # FILTER isBlank(?v) .
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/things#>))
9
17
  # (project (?x ?v)
10
18
  # (filter (isBlank ?v)
11
19
  # (bgp (triple ?x :p ?v)))))
@@ -30,6 +38,15 @@ module SPARQL; module Algebra
30
38
  else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
31
39
  end
32
40
  end
41
+
42
+ ##
43
+ #
44
+ # Returns a partial SPARQL grammar for this operator.
45
+ #
46
+ # @return [String]
47
+ def to_sparql(**options)
48
+ "isBlank(" + operands.first.to_sparql(**options) + ")"
49
+ end
33
50
  end # IsBlank
34
51
  end # Operator
35
52
  end; end # SPARQL::Algebra
@@ -3,9 +3,17 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `isIRI`/`isURI` operator.
5
5
  #
6
- # @example
7
- # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
8
- # (: <http://example.org/things#>))
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
16
+ # (prefix ((: <http://example.org/things#>))
9
17
  # (project (?x ?v)
10
18
  # (filter (isIRI ?v)
11
19
  # (bgp (triple ?x :p ?v)))))
@@ -32,6 +40,15 @@ module SPARQL; module Algebra
32
40
  end
33
41
 
34
42
  Operator::IsURI = IsIRI
43
+
44
+ ##
45
+ #
46
+ # Returns a partial SPARQL grammar for this operator.
47
+ #
48
+ # @return [String]
49
+ def to_sparql(**options)
50
+ "isIRI(" + operands.first.to_sparql(**options) + ")"
51
+ end
35
52
  end # IsIRI
36
53
  end # Operator
37
54
  end; end # SPARQL::Algebra
@@ -3,9 +3,17 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `isLiteral` operator.
5
5
  #
6
- # @example
7
- # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
8
- # (: <http://example.org/things#>))
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
16
+ # (prefix ((: <http://example.org/things#>))
9
17
  # (project (?x ?v)
10
18
  # (filter (isLiteral ?v)
11
19
  # (bgp (triple ?x :p ?v)))))
@@ -31,6 +39,15 @@ module SPARQL; module Algebra
31
39
  else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
32
40
  end
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
+ "isLiteral(" + operands.first.to_sparql(**options) + ")"
50
+ end
34
51
  end # IsLiteral
35
52
  end # Operator
36
53
  end; end # SPARQL::Algebra
@@ -3,11 +3,19 @@ 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
9
- # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
10
- # (: <http://example.org/things#>))
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
18
+ # (prefix ((: <http://example.org/things#>))
11
19
  # (project (?x ?v)
12
20
  # (filter (isNumeric ?v)
13
21
  # (bgp (triple ?x :p ?v)))))
@@ -16,7 +24,7 @@ module SPARQL; module Algebra
16
24
  class IsNumeric < Operator::Unary
17
25
  include Evaluatable
18
26
 
19
- NAME = :isnumeric
27
+ NAME = :isNumeric
20
28
 
21
29
  ##
22
30
  # Returns `true` if the operand is an `RDF::Literal::Numeric`, `false`
@@ -36,6 +44,15 @@ module SPARQL; module Algebra
36
44
  else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
37
45
  end
38
46
  end
47
+
48
+ ##
49
+ #
50
+ # Returns a partial SPARQL grammar for this operator.
51
+ #
52
+ # @return [String]
53
+ def to_sparql(**options)
54
+ "isNumeric(" + operands.first.to_sparql(**options) + ")"
55
+ end
39
56
  end # IsNumeric
40
57
  end # Operator
41
58
  end; end # SPARQL::Algebra
@@ -5,6 +5,29 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Returns true if term is an RDF-star triple. Returns false otherwise.
7
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
+ #
8
31
  # @see https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#istriple
9
32
  class IsTriple < Operator::Unary
10
33
  include Evaluatable
@@ -25,6 +48,15 @@ module SPARQL; module Algebra
25
48
  else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
26
49
  end
27
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
28
60
  end # IsTriple
29
61
  end # Operator
30
62
  end; end # SPARQL::Algebra
@@ -3,13 +3,38 @@ 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))
10
19
  # (graph ?g
11
20
  # (bgp (triple ?s ?q ?v)))))
12
21
  #
22
+ # @example SPARQL Grammar (inline filter)
23
+ # PREFIX : <http://xmlns.com/foaf/0.1/>
24
+ # ASK {
25
+ # :who :homepage ?homepage
26
+ # FILTER REGEX(?homepage, "^http://example.org/")
27
+ # :who :schoolHomepage ?schoolPage
28
+ # }
29
+ #
30
+ # @example SSE (inline filter)
31
+ # (prefix ((: <http://xmlns.com/foaf/0.1/>))
32
+ # (ask
33
+ # (filter (regex ?homepage "^http://example.org/")
34
+ # (join
35
+ # (bgp (triple :who :homepage ?homepage))
36
+ # (bgp (triple :who :schoolHomepage ?schoolPage))))))
37
+ #
13
38
  # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
14
39
  class Join < Operator::Binary
15
40
  include Query
@@ -32,8 +57,8 @@ module SPARQL; module Algebra
32
57
  # @return [RDF::Query::Solutions]
33
58
  # the resulting solution sequence
34
59
  # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
35
- # @see https://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#merge-instance_method
36
- # @see https://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#compatible%3F-instance_method
60
+ # @see https://ruby-rdf.github.io/rdf/RDF/Query/Solution#merge-instance_method
61
+ # @see https://ruby-rdf.github.io/rdf/RDF/Query/Solution#compatible%3F-instance_method
37
62
  def execute(queryable, **options, &block)
38
63
  # Join(Ω1, Ω2) = { merge(μ1, μ2) | μ1 in Ω1 and μ2 in Ω2, and μ1 and μ2 are compatible }
39
64
  # eval(D(G), Join(P1, P2)) = Join(eval(D(G), P1), eval(D(G), P2))
@@ -82,6 +107,36 @@ module SPARQL; module Algebra
82
107
  @operands = ops
83
108
  self
84
109
  end
110
+
111
+ ##
112
+ #
113
+ # Returns a partial SPARQL grammar for this operator.
114
+ #
115
+ # @param [Boolean] top_level (true)
116
+ # Treat this as a top-level, generating SELECT ... WHERE {}
117
+ # @param [Hash{String => Operator}] extensions
118
+ # Variable bindings
119
+ # @param [Array<Operator>] filter_ops ([])
120
+ # Filter Operations
121
+ # @return [String]
122
+ def to_sparql(top_level: true, filter_ops: [], extensions: {}, **options)
123
+ # If this is top-level, and the last operand is a Table (values), put the values at the outer-level
124
+ str = "{\n" + operands.first.to_sparql(top_level: false, extensions: {}, **options)
125
+
126
+ # Any accrued filters go here.
127
+ filter_ops.each do |op|
128
+ str << "\nFILTER (#{op.to_sparql(**options)}) ."
129
+ end
130
+
131
+ if top_level && operands.last.is_a?(Table)
132
+ str << "\n}"
133
+ options = options.merge(values_clause: operands.last)
134
+ else
135
+ str << "\n{\n" + operands.last.to_sparql(top_level: false, extensions: {}, **options) + "\n}\n}"
136
+ end
137
+
138
+ top_level ? Operator.to_sparql(str, extensions: extensions, **options) : str
139
+ end
85
140
  end # Join
86
141
  end # Operator
87
142
  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
@@ -24,6 +40,15 @@ module SPARQL; module Algebra
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))))
@@ -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,19 @@ 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 ((: <http://example.org/>))
16
+ # (project (?s ?lstr)
17
+ # (extend ((?lstr (lcase ?str)))
18
+ # (bgp (triple ?s :str ?str)))))
8
19
  #
9
20
  # @see https://www.w3.org/TR/sparql11-query/#func-lcase
10
21
  # @see https://www.w3.org/TR/xpath-functions/#func-lcase
@@ -26,6 +37,15 @@ module SPARQL; module Algebra
26
37
  else raise TypeError, "expected an RDF::Literal::Numeric, but got #{operand.inspect}"
27
38
  end
28
39
  end
40
+
41
+ ##
42
+ #
43
+ # Returns a partial SPARQL grammar for this operator.
44
+ #
45
+ # @return [String]
46
+ def to_sparql(**options)
47
+ "LCASE(" + operands.last.to_sparql(**options) + ")"
48
+ end
29
49
  end # LCase
30
50
  end # Operator
31
51
  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))
@@ -32,8 +44,8 @@ module SPARQL; module Algebra
32
44
  # @return [RDF::Query::Solutions]
33
45
  # the resulting solution sequence
34
46
  # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
35
- # @see https://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#merge-instance_method
36
- # @see https://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#compatible%3F-instance_method
47
+ # @see https://ruby-rdf.github.io/rdf/RDF/Query/Solution#merge-instance_method
48
+ # @see https://ruby-rdf.github.io/rdf/RDF/Query/Solution#compatible%3F-instance_method
37
49
  def execute(queryable, **options, &block)
38
50
  filter = operand(2)
39
51
 
@@ -112,6 +124,35 @@ 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
+ # @param [Hash{String => Operator}] extensions
135
+ # Variable bindings
136
+ # @param [Array<Operator>] filter_ops ([])
137
+ # Filter Operations
138
+ # @return [String]
139
+ def to_sparql(top_level: true, filter_ops: [], extensions: {}, **options)
140
+ str = "{\n" + operands[0].to_sparql(top_level: false, extensions: {}, **options)
141
+ str <<
142
+ "\nOPTIONAL {\n" +
143
+ operands[1].to_sparql(top_level: false, extensions: {}, **options)
144
+ case operands[2]
145
+ when SPARQL::Algebra::Operator::Exprlist
146
+ operands[2].operands.each do |op|
147
+ str << "\nFILTER (" + op.to_sparql(**options) + ")"
148
+ end
149
+ when nil
150
+ else
151
+ str << "\nFILTER (" + operands[2].to_sparql(**options) + ")"
152
+ end
153
+ str << "\n}}"
154
+ top_level ? Operator.to_sparql(str, filter_ops: filter_ops, extensions: extensions, **options) : str
155
+ end
115
156
  end # LeftJoin
116
157
  end # Operator
117
158
  end; end # SPARQL::Algebra