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
@@ -5,11 +5,20 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Returns the timezone part of `arg` as an xsd:dayTimeDuration. Raises an error if there is no timezone.
7
7
  #
8
- # @example
9
- # (prefix ((: <http://example.org/>))
10
- # (project (?s ?x)
11
- # (extend ((?x (timezone ?date)))
12
- # (bgp (triple ?s :date ?date)))))
8
+ # [121] BuiltInCall ::= ... | 'TIMEZONE' '(' Expression ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.org/>
12
+ # SELECT ?s (TIMEZONE(?date) AS ?x) WHERE {
13
+ # ?s :date ?date
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix
18
+ # ((: <http://example.org/>))
19
+ # (project (?s ?x)
20
+ # (extend ((?x (timezone ?date)))
21
+ # (bgp (triple ?s :date ?date)))))
13
22
  #
14
23
  # @see https://www.w3.org/TR/sparql11-query/#func-timezone
15
24
  class Timezone < Operator::Unary
@@ -24,13 +33,22 @@ module SPARQL; module Algebra
24
33
  #
25
34
  # @param [RDF::Literal] operand
26
35
  # the operand
27
- # @return [RDF::Literal]
36
+ # @return [RDF::Literal::Temporal]
28
37
  # @raise [TypeError] if the operand is not a simple literal
29
38
  def apply(operand, **options)
30
- raise TypeError, "expected an RDF::Literal::DateTime, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::DateTime)
39
+ raise TypeError, "expected an RDF::Literal::Temporal, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::Temporal)
31
40
  raise TypeError, "literal has no timezone" unless res = operand.timezone
32
41
  res
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
+ "TIMEZONE(" + operands.to_sparql(**options) + ")"
51
+ end
34
52
  end # Timezone
35
53
  end # Operator
36
54
  end; end # SPARQL::Algebra
@@ -5,6 +5,21 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # If the 3-tuple (term1, term2, term3) is an RDF-star triple, the function returns this triple. If the 3-tuple is not an RDF-star triple, then the function raises an error.
7
7
  #
8
+ # [121] BuiltInCall ::= ... | 'TRIPLE' '(' Expression ',' Expression ',' Expression ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.com/ns#>
12
+ # SELECT * {
13
+ # ?s ?p ?o .
14
+ # BIND(TRIPLE(?s, ?p, ?o) AS ?t1)
15
+ # }
16
+ #
17
+ # @example SSE
18
+ # (prefix ((: <http://example.com/ns#>))
19
+ # (extend ((?t1 (triple ?s ?p ?o)))
20
+ # (bgp (triple ?s ?p ?o))))
21
+ #
22
+ # @note This operator overlaps with RDF::Query::Pattern as used as an operand to a BGP.
8
23
  # @see https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#triple
9
24
  class Triple < Operator::Ternary
10
25
  include Evaluatable
@@ -22,6 +37,15 @@ module SPARQL; module Algebra
22
37
  raise TypeError, "valid components, but got #{triple.inspect}" unless triple.valid?
23
38
  triple
24
39
  end
40
+
41
+ ##
42
+ #
43
+ # Returns a partial SPARQL grammar for this operator.
44
+ #
45
+ # @return [String]
46
+ def to_sparql(**options)
47
+ "TRIPLE(#{operands.to_sparql(delimiter: ', ', **options)})"
48
+ end
25
49
  end # Triple
26
50
  end # Operator
27
51
  end; end # SPARQL::Algebra
@@ -5,11 +5,20 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Returns the timezone part of `arg` as a simple literal. Returns the empty string if there is no timezone.
7
7
  #
8
- # @example
9
- # (prefix ((: <http://example.org/>))
10
- # (project (?s ?x)
11
- # (extend ((?x (tz ?date)))
12
- # (bgp (triple ?s :date ?date)))))
8
+ # [121] BuiltInCall ::= ... | 'TZ' '(' Expression ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.org/>
12
+ # SELECT ?s (TZ(?date) AS ?x) WHERE {
13
+ # ?s :date ?date
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix
18
+ # ((: <http://example.org/>))
19
+ # (project (?s ?x)
20
+ # (extend ((?x (tz ?date)))
21
+ # (bgp (triple ?s :date ?date)))))
13
22
  #
14
23
  # @see https://www.w3.org/TR/sparql11-query/#func-tz
15
24
  class TZ < Operator::Unary
@@ -20,14 +29,22 @@ module SPARQL; module Algebra
20
29
  ##
21
30
  # Returns the timezone part of arg as a simple literal. Returns the empty string if there is no timezone.
22
31
  #
23
- # @param [RDF::Literal] operand
32
+ # @param [RDF::Literal::Temporal] operand
24
33
  # the operand
25
34
  # @return [RDF::Literal]
26
35
  # @raise [TypeError] if the operand is not a simple literal
27
36
  def apply(operand, **options)
28
- raise TypeError, "expected an RDF::Literal::DateTime, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::DateTime)
37
+ raise TypeError, "expected an RDF::Literal::Temporal, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::Temporal)
29
38
  operand.tz
30
39
  end
40
+ ##
41
+ #
42
+ # Returns a partial SPARQL grammar for this operator.
43
+ #
44
+ # @return [String]
45
+ def to_sparql(**options)
46
+ "TZ(" + operands.to_sparql(**options) + ")"
47
+ end
31
48
  end # TZ
32
49
  end # Operator
33
50
  end; end # SPARQL::Algebra
@@ -3,8 +3,20 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL logical `ucase` operator.
5
5
  #
6
- # @example
7
- # (ucase ?x)
6
+ # [121] BuiltInCall ::= ... | 'UCASE' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT ?s (UCASE(?str) AS ?ustr) WHERE {
11
+ # ?s :str ?str
12
+ # }
13
+ #
14
+ # @example SSE
15
+ # (prefix
16
+ # ((: <http://example.org/>))
17
+ # (project (?s ?ustr)
18
+ # (extend ((?ustr (ucase ?str)))
19
+ # (bgp (triple ?s :str ?str)))))
8
20
  #
9
21
  # @see https://www.w3.org/TR/sparql11-query/#func-ucase
10
22
  # @see https://www.w3.org/TR/xpath-functions/#func-ucase
@@ -26,6 +38,15 @@ module SPARQL; module Algebra
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
+ "UCASE(" + operands.last.to_sparql(**options) + ")"
49
+ end
29
50
  end # UCase
30
51
  end # Operator
31
52
  end; end # SPARQL::Algebra
@@ -3,12 +3,19 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `union` operator.
5
5
  #
6
- # @example
7
- # (prefix ((: <http://example/>))
8
- # (union
9
- # (bgp (triple ?s ?p ?o))
10
- # (graph ?g
11
- # (bgp (triple ?s ?p ?o)))))
6
+ # [67] GroupOrUnionGraphPattern::= GroupGraphPattern ( 'UNION' GroupGraphPattern )*
7
+ #
8
+ # @example SPARQL Grammar
9
+ # SELECT * {
10
+ # { ?s ?p ?o }
11
+ # UNION
12
+ # { GRAPH ?g { ?s ?p ?o } }}
13
+ #
14
+ # @example SSE
15
+ # (union
16
+ # (bgp (triple ?s ?p ?o))
17
+ # (graph ?g
18
+ # (bgp (triple ?s ?p ?o))))
12
19
  #
13
20
  # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
14
21
  class Union < Operator::Binary
@@ -66,6 +73,22 @@ module SPARQL; module Algebra
66
73
  @operands = ops
67
74
  self
68
75
  end
76
+
77
+ ##
78
+ #
79
+ # Returns a partial SPARQL grammar for this operator.
80
+ #
81
+ # @param [Boolean] top_level (true)
82
+ # Treat this as a top-level, generating SELECT ... WHERE {}
83
+ # @return [String]
84
+ def to_sparql(top_level: true, **options)
85
+ str = "{\n"
86
+ str << operands[0].to_sparql(top_level: false, **options)
87
+ str << "\n} UNION {\n"
88
+ str << operands[1].to_sparql(top_level: false, **options)
89
+ str << "\n}"
90
+ top_level ? Operator.to_sparql(str, **options) : str
91
+ end
69
92
  end # Union
70
93
  end # Operator
71
94
  end; end # SPARQL::Algebra
@@ -3,11 +3,44 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `prefix` operator.
5
5
  #
6
- # @example
7
- # (update
6
+ # [29] Update ::= Prologue ( Update1 ( ';' Update )? )?
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # PREFIX foaf: <http://xmlns.com/foaf/0.1/>
11
+ # DELETE { ?a foaf:knows ?b }
12
+ # INSERT { ?b foaf:knows ?a }
13
+ # WHERE { ?a foaf:knows ?b }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/>)
17
+ # (foaf: <http://xmlns.com/foaf/0.1/>))
18
+ # (update
19
+ # (modify
20
+ # (bgp (triple ?a foaf:knows ?b))
21
+ # (delete ((triple ?a foaf:knows ?b)))
22
+ # (insert ((triple ?b foaf:knows ?a)))) ))
23
+ #
24
+ # @example SPARQL Grammar (update multiple)
25
+ # PREFIX : <http://example.org/>
26
+ # PREFIX foaf: <http://xmlns.com/foaf/0.1/>
27
+ #
28
+ # DELETE { ?a foaf:knows ?b . }
29
+ # WHERE { ?a foaf:knows ?b . }
30
+ # ;
31
+ # INSERT { ?b foaf:knows ?a . }
32
+ # WHERE { ?a foaf:knows ?b .}
33
+ #
34
+ # @example SSE (update multiple)
35
+ # (prefix ((: <http://example.org/>)
36
+ # (foaf: <http://xmlns.com/foaf/0.1/>))
37
+ # (update
38
+ # (modify
39
+ # (bgp (triple ?a foaf:knows ?b))
40
+ # (delete ((triple ?a foaf:knows ?b))))
8
41
  # (modify
9
- # (bgp (triple ?s ?p ?o))
10
- # (insert ((triple ?s ?p "q")))))
42
+ # (bgp (triple ?a foaf:knows ?b))
43
+ # (insert ((triple ?b foaf:knows ?a))))))
11
44
  #
12
45
  # @see https://www.w3.org/TR/sparql11-update/#graphUpdate
13
46
  class Update < Operator
@@ -39,6 +72,15 @@ module SPARQL; module Algebra
39
72
  end
40
73
  queryable
41
74
  end
75
+
76
+ ##
77
+ #
78
+ # Returns a partial SPARQL grammar for this operator.
79
+ #
80
+ # @return [String]
81
+ def to_sparql(**options)
82
+ str = operands.map { |e| e.to_sparql(**options) }.join(";\n")
83
+ end
42
84
  end # Update
43
85
  end # Operator
44
86
  end; end # SPARQL::Algebra
@@ -6,8 +6,42 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # The USING and USING NAMED clauses affect the RDF Dataset used while evaluating the WHERE clause. This describes a dataset in the same way as FROM and FROM NAMED clauses describe RDF Datasets in the SPARQL 1.1 Query Language
8
8
  #
9
- # @example
10
- # (using (:g1) (bgp (triple ?s ?p ?o)))
9
+ # [44] UsingClause ::= 'USING' ( iri | 'NAMED' iri )
10
+ #
11
+ # @example SPARQL Grammar
12
+ # PREFIX : <http://example.org/>
13
+ # PREFIX foaf: <http://xmlns.com/foaf/0.1/>
14
+ #
15
+ # DELETE { ?s ?p ?o }
16
+ # USING <http://example.org/g2>
17
+ # WHERE {
18
+ # :a foaf:knows ?s .
19
+ # ?s ?p ?o
20
+ # }
21
+ #
22
+ # @example SSE
23
+ # (prefix
24
+ # ((: <http://example.org/>) (foaf: <http://xmlns.com/foaf/0.1/>))
25
+ # (update
26
+ # (modify
27
+ # (using (:g2)
28
+ # (bgp (triple :a foaf:knows ?s) (triple ?s ?p ?o)))
29
+ # (delete ((triple ?s ?p ?o)))) ))
30
+ #
31
+ # @example SPARQL Grammar (multiple clauses)
32
+ # PREFIX : <http://example.org/>
33
+ #
34
+ # INSERT { ?s ?p "q" }
35
+ # USING :g1
36
+ # USING :g2
37
+ # WHERE { ?s ?p ?o }
38
+ #
39
+ # @example SSE (multiple clauses)
40
+ # (prefix ((: <http://example.org/>))
41
+ # (update
42
+ # (modify
43
+ # (using (:g1 :g2) (bgp (triple ?s ?p ?o)))
44
+ # (insert ((triple ?s ?p "q"))))))
11
45
  #
12
46
  # @see https://www.w3.org/TR/sparql11-update/#add
13
47
  class Using < Operator
@@ -35,6 +69,19 @@ module SPARQL; module Algebra
35
69
  debug(options) {"Using"}
36
70
  Dataset.new(*operands).execute(queryable, depth: options[:depth].to_i + 1, **options, &block)
37
71
  end
72
+
73
+ ##
74
+ #
75
+ # Returns a partial SPARQL grammar for this operator.
76
+ #
77
+ # @return [String]
78
+ def to_sparql(**options)
79
+ str = "\n" + operands.first.map do |op|
80
+ "USING #{op.to_sparql(**options)}\n"
81
+ end.join("")
82
+ content = operands.last.to_sparql(top_level: false, **options)
83
+ str << Operator.to_sparql(content, project: nil, **options)
84
+ end
38
85
  end # Using
39
86
  end # Operator
40
87
  end; end # SPARQL::Algebra
@@ -5,14 +5,24 @@ module SPARQL; module Algebra
5
5
  ##
6
6
  # The SPARQL `uuid` function.
7
7
  #
8
- # @example
9
- # (prefix ((: <http://example.org/>)
10
- # (xsd: <http://www.w3.org/2001/XMLSchema#>))
11
- # (project (?length)
12
- # (extend ((?length (strlen (str ?uuid))))
13
- # (filter (&& (isIRI ?uuid) (regex (str ?uuid) "^urn: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 (uuid)))
15
- # (bgp))))))
8
+ # [121] BuiltInCall ::= ... | 'UUID' NIL
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.org/>
12
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
13
+ # ASK {
14
+ # BIND(UUID() AS ?u1)
15
+ # BIND(UUID() AS ?u2)
16
+ # FILTER(?u1 != ?u2)
17
+ # }
18
+ #
19
+ # @example SSE
20
+ # (prefix
21
+ # ((: <http://example.org/>) (xsd: <http://www.w3.org/2001/XMLSchema#>))
22
+ # (ask
23
+ # (filter (!= ?u1 ?u2)
24
+ # (extend ((?u1 (uuid)) (?u2 (uuid)))
25
+ # (bgp)))))
16
26
  #
17
27
  # @see https://www.w3.org/TR/sparql11-query/#func-uuid
18
28
  class UUID < Operator::Nullary
@@ -27,6 +37,15 @@ module SPARQL; module Algebra
27
37
  def apply(**options)
28
38
  RDF::URI("urn:uuid:#{SecureRandom.uuid}")
29
39
  end
40
+
41
+ ##
42
+ #
43
+ # Returns a partial SPARQL grammar for this operator.
44
+ #
45
+ # @return [String]
46
+ def to_sparql(**options)
47
+ "UUID(" + operands.to_sparql(delimiter: ', ', **options) + ")"
48
+ end
30
49
  end # UUID
31
50
  end # Operator
32
51
  end; end # SPARQL::Algebra
@@ -6,10 +6,21 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # The WITH clause provides a convenience for when an operation primarily refers to a single graph.
8
8
  #
9
- # @example
10
- # (with :g1
11
- # (bgp (triple ?s ?p ?o))
12
- # (insert ((triple ?s ?p "z"))))
9
+ # [41] Modify ::= ( 'WITH' iri )? ( DeleteClause InsertClause? | InsertClause ) UsingClause* 'WHERE' GroupGraphPattern
10
+ #
11
+ # @example SPARQL Grammar
12
+ # PREFIX : <http://example/>
13
+ # WITH :g
14
+ # DELETE { <base:s> ?p ?o . }
15
+ # WHERE { ?s ?p ?o }
16
+ #
17
+ # @example SSE
18
+ # (prefix ((: <http://example/>))
19
+ # (update
20
+ # (modify
21
+ # (with :g
22
+ # (bgp (triple ?s ?p ?o))
23
+ # (delete ((triple <base:s> ?p ?o)))))))
13
24
  #
14
25
  # @see https://www.w3.org/TR/sparql11-update/#deleteInsert
15
26
  class With < Operator
@@ -67,6 +78,29 @@ module SPARQL; module Algebra
67
78
  end
68
79
  end
69
80
  end
81
+
82
+ ##
83
+ #
84
+ # Returns a partial SPARQL grammar for this operator.
85
+ #
86
+ # @return [String]
87
+ def to_sparql(**options)
88
+ with, where, *ops = operands
89
+ str = "WITH #{with.to_sparql(**options)}\n"
90
+
91
+ # The content of the WHERE clause, may be USING
92
+ content = where.to_sparql(top_level: false, **options)
93
+
94
+ # DELETE | INSERT | DELETE INSERT
95
+ str << ops.to_sparql(top_level: false, delimiter: "\n", **options) + "\n"
96
+
97
+ # Append the WHERE or USING clause
98
+ str << if where.is_a?(Using)
99
+ content
100
+ else
101
+ Operator.to_sparql(content, project: nil, **options)
102
+ end
103
+ end
70
104
  end # With
71
105
  end # Operator
72
106
  end; end # SPARQL::Algebra
@@ -5,11 +5,20 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Returns the year part of `arg` as an integer.
7
7
  #
8
- # @example
9
- # (prefix ((: <http://example.org/>))
10
- # (project (?s ?x)
11
- # (extend ((?x (year ?date)))
12
- # (bgp (triple ?s :date ?date)))))
8
+ # [121] BuiltInCall ::= ... | 'YEAR' '(' Expression ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.org/>
12
+ # SELECT ?s (YEAR(?date) AS ?x) WHERE {
13
+ # ?s :date ?date
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix
18
+ # ((: <http://example.org/>))
19
+ # (project (?s ?x)
20
+ # (extend ((?x (year ?date)))
21
+ # (bgp (triple ?s :date ?date)))))
13
22
  #
14
23
  # @see https://www.w3.org/TR/sparql11-query/#func-year
15
24
  class Year < Operator::Unary
@@ -22,12 +31,21 @@ module SPARQL; module Algebra
22
31
  #
23
32
  # @param [RDF::Literal] operand
24
33
  # the operand
25
- # @return [RDF::Literal]
34
+ # @return [RDF::Literal::Temporal]
26
35
  # @raise [TypeError] if the operand is not a simple literal
27
36
  def apply(operand, **options)
28
- raise TypeError, "expected an RDF::Literal::DateTime, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::DateTime)
37
+ raise TypeError, "expected an RDF::Literal::Temporal, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::Temporal)
29
38
  RDF::Literal(operand.object.year)
30
39
  end
40
+
41
+ ##
42
+ #
43
+ # Returns a partial SPARQL grammar for this operator.
44
+ #
45
+ # @return [String]
46
+ def to_sparql(**options)
47
+ "YEAR(#{operands.last.to_sparql(**options)})"
48
+ end
31
49
  end # Year
32
50
  end # Operator
33
51
  end; end # SPARQL::Algebra