sparql 3.1.6 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +31 -22
  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 +28 -3
  8. data/lib/sparql/algebra/extensions.rb +109 -45
  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 +20 -2
  16. data/lib/sparql/algebra/operator/base.rb +18 -1
  17. data/lib/sparql/algebra/operator/bgp.rb +13 -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 +26 -2
  22. data/lib/sparql/algebra/operator/coalesce.rb +33 -11
  23. data/lib/sparql/algebra/operator/compare.rb +48 -40
  24. data/lib/sparql/algebra/operator/concat.rb +26 -2
  25. data/lib/sparql/algebra/operator/construct.rb +29 -6
  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 +53 -7
  29. data/lib/sparql/algebra/operator/create.rb +20 -2
  30. data/lib/sparql/algebra/operator/dataset.rb +27 -2
  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 +29 -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 +20 -3
  39. data/lib/sparql/algebra/operator/divide.rb +27 -3
  40. data/lib/sparql/algebra/operator/drop.rb +27 -3
  41. data/lib/sparql/algebra/operator/encode_for_uri.rb +23 -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 +15 -2
  45. data/lib/sparql/algebra/operator/extend.rb +64 -6
  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/function_call.rb +64 -0
  49. data/lib/sparql/algebra/operator/graph.rb +69 -6
  50. data/lib/sparql/algebra/operator/greater_than.rb +14 -4
  51. data/lib/sparql/algebra/operator/greater_than_or_equal.rb +14 -4
  52. data/lib/sparql/algebra/operator/group.rb +105 -8
  53. data/lib/sparql/algebra/operator/group_concat.rb +44 -8
  54. data/lib/sparql/algebra/operator/hours.rb +24 -6
  55. data/lib/sparql/algebra/operator/if.rb +20 -3
  56. data/lib/sparql/algebra/operator/in.rb +18 -1
  57. data/lib/sparql/algebra/operator/insert.rb +24 -2
  58. data/lib/sparql/algebra/operator/insert_data.rb +23 -2
  59. data/lib/sparql/algebra/operator/iri.rb +22 -5
  60. data/lib/sparql/algebra/operator/is_blank.rb +21 -4
  61. data/lib/sparql/algebra/operator/is_iri.rb +21 -4
  62. data/lib/sparql/algebra/operator/is_literal.rb +21 -4
  63. data/lib/sparql/algebra/operator/is_numeric.rb +23 -6
  64. data/lib/sparql/algebra/operator/is_triple.rb +33 -1
  65. data/lib/sparql/algebra/operator/join.rb +56 -1
  66. data/lib/sparql/algebra/operator/lang.rb +26 -1
  67. data/lib/sparql/algebra/operator/lang_matches.rb +23 -2
  68. data/lib/sparql/algebra/operator/lcase.rb +23 -3
  69. data/lib/sparql/algebra/operator/left_join.rb +42 -1
  70. data/lib/sparql/algebra/operator/less_than.rb +14 -4
  71. data/lib/sparql/algebra/operator/less_than_or_equal.rb +14 -4
  72. data/lib/sparql/algebra/operator/load.rb +25 -2
  73. data/lib/sparql/algebra/operator/max.rb +20 -2
  74. data/lib/sparql/algebra/operator/md5.rb +23 -6
  75. data/lib/sparql/algebra/operator/min.rb +22 -4
  76. data/lib/sparql/algebra/operator/minus.rb +65 -7
  77. data/lib/sparql/algebra/operator/minutes.rb +24 -6
  78. data/lib/sparql/algebra/operator/modify.rb +41 -5
  79. data/lib/sparql/algebra/operator/month.rb +24 -6
  80. data/lib/sparql/algebra/operator/move.rb +20 -2
  81. data/lib/sparql/algebra/operator/multiply.rb +27 -4
  82. data/lib/sparql/algebra/operator/negate.rb +24 -4
  83. data/lib/sparql/algebra/operator/not.rb +25 -4
  84. data/lib/sparql/algebra/operator/not_equal.rb +16 -1
  85. data/lib/sparql/algebra/operator/notexists.rb +30 -6
  86. data/lib/sparql/algebra/operator/notin.rb +20 -3
  87. data/lib/sparql/algebra/operator/notoneof.rb +21 -2
  88. data/lib/sparql/algebra/operator/now.rb +25 -6
  89. data/lib/sparql/algebra/operator/object.rb +33 -1
  90. data/lib/sparql/algebra/operator/or.rb +26 -3
  91. data/lib/sparql/algebra/operator/order.rb +71 -2
  92. data/lib/sparql/algebra/operator/path.rb +29 -2
  93. data/lib/sparql/algebra/operator/path_opt.rb +21 -2
  94. data/lib/sparql/algebra/operator/path_plus.rb +21 -2
  95. data/lib/sparql/algebra/operator/path_star.rb +20 -2
  96. data/lib/sparql/algebra/operator/plus.rb +43 -4
  97. data/lib/sparql/algebra/operator/predicate.rb +33 -1
  98. data/lib/sparql/algebra/operator/prefix.rb +24 -3
  99. data/lib/sparql/algebra/operator/project.rb +69 -5
  100. data/lib/sparql/algebra/operator/rand.rb +31 -3
  101. data/lib/sparql/algebra/operator/reduced.rb +20 -3
  102. data/lib/sparql/algebra/operator/regex.rb +27 -19
  103. data/lib/sparql/algebra/operator/replace.rb +27 -7
  104. data/lib/sparql/algebra/operator/reverse.rb +31 -2
  105. data/lib/sparql/algebra/operator/round.rb +26 -3
  106. data/lib/sparql/algebra/operator/same_term.rb +25 -7
  107. data/lib/sparql/algebra/operator/sample.rb +33 -9
  108. data/lib/sparql/algebra/operator/seconds.rb +24 -6
  109. data/lib/sparql/algebra/operator/seq.rb +20 -2
  110. data/lib/sparql/algebra/operator/sequence.rb +4 -11
  111. data/lib/sparql/algebra/operator/sha1.rb +19 -2
  112. data/lib/sparql/algebra/operator/sha256.rb +19 -2
  113. data/lib/sparql/algebra/operator/sha384.rb +19 -2
  114. data/lib/sparql/algebra/operator/sha512.rb +19 -2
  115. data/lib/sparql/algebra/operator/slice.rb +27 -5
  116. data/lib/sparql/algebra/operator/str.rb +22 -2
  117. data/lib/sparql/algebra/operator/strafter.rb +26 -3
  118. data/lib/sparql/algebra/operator/strbefore.rb +26 -3
  119. data/lib/sparql/algebra/operator/strdt.rb +23 -2
  120. data/lib/sparql/algebra/operator/strends.rb +26 -4
  121. data/lib/sparql/algebra/operator/strlang.rb +25 -7
  122. data/lib/sparql/algebra/operator/strlen.rb +24 -3
  123. data/lib/sparql/algebra/operator/strstarts.rb +26 -3
  124. data/lib/sparql/algebra/operator/struuid.rb +30 -10
  125. data/lib/sparql/algebra/operator/subject.rb +33 -1
  126. data/lib/sparql/algebra/operator/substr.rb +24 -3
  127. data/lib/sparql/algebra/operator/subtract.rb +29 -3
  128. data/lib/sparql/algebra/operator/sum.rb +25 -7
  129. data/lib/sparql/algebra/operator/table.rb +76 -4
  130. data/lib/sparql/algebra/operator/timezone.rb +24 -6
  131. data/lib/sparql/algebra/operator/tz.rb +23 -6
  132. data/lib/sparql/algebra/operator/ucase.rb +24 -3
  133. data/lib/sparql/algebra/operator/union.rb +29 -6
  134. data/lib/sparql/algebra/operator/update.rb +46 -4
  135. data/lib/sparql/algebra/operator/using.rb +49 -2
  136. data/lib/sparql/algebra/operator/uuid.rb +28 -9
  137. data/lib/sparql/algebra/operator/with.rb +38 -4
  138. data/lib/sparql/algebra/operator/year.rb +24 -6
  139. data/lib/sparql/algebra/operator.rb +135 -14
  140. data/lib/sparql/algebra/sxp_extensions.rb +3 -3
  141. data/lib/sparql/algebra.rb +20 -3
  142. data/lib/sparql/grammar/meta.rb +1103 -907
  143. data/lib/sparql/grammar/parser11.rb +63 -56
  144. metadata +43 -29
  145. data/lib/sparql/algebra/operator/triple.rb +0 -27
@@ -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,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
@@ -20,12 +31,21 @@ module SPARQL; module Algebra
20
31
  # the operand
21
32
  # @return [RDF::Literal] literal of same type
22
33
  # @raise [TypeError] if the operand is not a literal value
23
- def apply(operand)
34
+ def apply(operand, **options)
24
35
  case operand
25
36
  when RDF::Literal then RDF::Literal(operand.to_s.downcase, datatype: operand.datatype, language: operand.language)
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))
@@ -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{Symbol => 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
@@ -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,17 @@ 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
+ distinct = operands.first == :distinct
60
+ args = distinct ? operands[1..-1] : operands
61
+ "MAX(#{'DISTINCT ' if distinct}#{args.to_sparql(**options)})"
62
+ end
45
63
  end # Max
46
64
  end # Operator
47
65
  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,12 +3,19 @@ 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
- # (bgp (triple ?s ?p ?o))))))
18
+ # (bgp (triple ?s :dec ?o))))))
12
19
  #
13
20
  # @see https://www.w3.org/TR/sparql11-query/#defn_aggMin
14
21
  class Min < Operator
@@ -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,17 @@ 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
+ distinct = operands.first == :distinct
60
+ args = distinct ? operands[1..-1] : operands
61
+ "MIN(#{'DISTINCT ' if distinct}#{args.to_sparql(**options)})"
62
+ end
45
63
  end # Min
46
64
  end # Operator
47
65
  end; end # SPARQL::Algebra
@@ -3,13 +3,42 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `minus` operator.
5
5
  #
6
- # @example
7
- # (prefix ((ex: <http://www.w3.org/2009/sparql/docs/tests/data-sparql11/negation#>))
8
- # (project (?animal)
9
- # (minus
10
- # (bgp (triple ?animal <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ex:Animal))
11
- # (filter (|| (= ?type ex:Reptile) (= ?type ex:Insect))
12
- # (bgp (triple ?animal <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type))))))
6
+ # [66] MinusGraphPattern ::= 'MINUS' GroupGraphPattern
7
+ #
8
+ # @example SPARQL Grammar
9
+ # SELECT * { ?s ?p ?o MINUS { ?s ?q ?v } }
10
+ #
11
+ # @example SSE
12
+ # (minus
13
+ # (bgp
14
+ # (triple ?s ?p ?o))
15
+ # (bgp (triple ?s ?q ?v)))
16
+ #
17
+ # @example SPARQL Grammar (inline filter)
18
+ # PREFIX : <http://example/>
19
+ # SELECT (?s1 AS ?subset) (?s2 AS ?superset)
20
+ # WHERE {
21
+ # ?s2 a :Set .
22
+ # ?s1 a :Set .
23
+ # FILTER(?s1 != ?s2)
24
+ # MINUS {
25
+ # ?s1 a :Set .
26
+ # ?s2 a :Set .
27
+ # FILTER(?s1 != ?s2)
28
+ # }
29
+ # }
30
+ #
31
+ # @example SSE (inline filter)
32
+ # (prefix ((: <http://example/>))
33
+ # (project (?subset ?superset)
34
+ # (extend ((?subset ?s1) (?superset ?s2))
35
+ # (filter (!= ?s1 ?s2)
36
+ # (minus
37
+ # (bgp (triple ?s2 a :Set) (triple ?s1 a :Set))
38
+ # (filter (!= ?s1 ?s2)
39
+ # (bgp
40
+ # (triple ?s1 a :Set)
41
+ # (triple ?s2 a :Set))))))))
13
42
  #
14
43
  # @see https://www.w3.org/TR/xpath-functions/#func-numeric-unary-minus
15
44
  # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
@@ -66,6 +95,35 @@ module SPARQL; module Algebra
66
95
  @operands = ops
67
96
  self
68
97
  end
98
+
99
+ ##
100
+ #
101
+ # Returns a partial SPARQL grammar for this operator.
102
+ #
103
+ # @param [Hash{Symbol => Operator}] extensions
104
+ # Variable bindings
105
+ # @param [Array<Operator>] filter_ops ([])
106
+ # Filter Operations
107
+ # @param [Boolean] top_level (true)
108
+ # Treat this as a top-level, generating SELECT ... WHERE {}
109
+ # @return [String]
110
+ def to_sparql(top_level: true, filter_ops: [], extensions: {}, **options)
111
+ lhs, *rhs = operands
112
+ str = "{\n" + lhs.to_sparql(top_level: false, extensions: {}, **options)
113
+
114
+ # Any accrued filters go here.
115
+ filter_ops.each do |op|
116
+ str << "\nFILTER (#{op.to_sparql(**options)}) ."
117
+ end
118
+
119
+ rhs.each do |minus|
120
+ str << "\nMINUS {\n"
121
+ str << minus.to_sparql(top_level: false, extensions: {}, **options)
122
+ str << "\n}"
123
+ end
124
+ str << "}"
125
+ top_level ? Operator.to_sparql(str, extensions: extensions, **options) : str
126
+ end
69
127
  end # Minus
70
128
  end # Operator
71
129
  end; end # SPARQL::Algebra
@@ -5,11 +5,20 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Returns the minutes part of the lexical form of `arg`. The value is as given in the lexical form of the XSD dateTime.
7
7
  #
8
- # @example
9
- # (prefix ((: <http://example.org/>))
10
- # (project (?s ?x)
11
- # (extend ((?x (minutes ?date)))
12
- # (bgp (triple ?s :date ?date)))))
8
+ # [121] BuiltInCall ::= ... | 'MINUTES' '(' Expression ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.org/>
12
+ # SELECT ?s (MINUTES(?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 (minutes ?date)))
21
+ # (bgp (triple ?s :date ?date)))))
13
22
  #
14
23
  # @see https://www.w3.org/TR/sparql11-query/#func-minutes
15
24
  class Minutes < Operator::Unary
@@ -24,10 +33,19 @@ module SPARQL; module Algebra
24
33
  # the operand
25
34
  # @return [RDF::Literal]
26
35
  # @raise [TypeError] if the operand is not a simple literal
27
- def apply(operand)
36
+ def apply(operand, **options)
28
37
  raise TypeError, "expected an RDF::Literal::DateTime, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::DateTime)
29
38
  RDF::Literal(operand.object.minute)
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
+ "MINUTES(#{operands.last.to_sparql(**options)})"
48
+ end
31
49
  end # Minutes
32
50
  end # Operator
33
51
  end; end # SPARQL::Algebra
@@ -6,11 +6,23 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # Wraps delete/insert
8
8
  #
9
- # @example
10
- # (modify
11
- # (bgp (triple ?a foaf:knows ?b))
12
- # (delete ((triple ?a foaf:knows ?b)))
13
- # (insert ((triple ?b foaf:knows ?a)))
9
+ # [41] Modify ::= ( 'WITH' iri )? ( DeleteClause InsertClause? | InsertClause ) UsingClause* 'WHERE' GroupGraphPattern
10
+ #
11
+ # @example SPARQL Grammar
12
+ # PREFIX : <http://example.org/>
13
+ # PREFIX foaf: <http://xmlns.com/foaf/0.1/>
14
+ # DELETE { ?a foaf:knows ?b }
15
+ # INSERT { ?b foaf:knows ?a }
16
+ # WHERE { ?a foaf:knows ?b }
17
+ #
18
+ # @example SSE
19
+ # (prefix ((: <http://example.org/>)
20
+ # (foaf: <http://xmlns.com/foaf/0.1/>))
21
+ # (update
22
+ # (modify
23
+ # (bgp (triple ?a foaf:knows ?b))
24
+ # (delete ((triple ?a foaf:knows ?b)))
25
+ # (insert ((triple ?b foaf:knows ?a)))) ))
14
26
  #
15
27
  # @see XXX
16
28
  class Modify < Operator
@@ -48,6 +60,30 @@ module SPARQL; module Algebra
48
60
  end
49
61
  queryable
50
62
  end
63
+
64
+ ##
65
+ #
66
+ # Returns a partial SPARQL grammar for this operator.
67
+ #
68
+ # @return [String]
69
+ def to_sparql(**options)
70
+ if operands.first.is_a?(With)
71
+ operands.first.to_sparql(**options)
72
+ else
73
+ # The content of the WHERE clause, may be USING
74
+ content = operands.first.to_sparql(top_level: false, **options)
75
+
76
+ # DELETE | INSERT | DELETE INSERT
77
+ str = operands[1..-1].to_sparql(top_level: false, delimiter: "\n", **options) + "\n"
78
+
79
+ # Append the WHERE or USING clause
80
+ str << if operands.first.is_a?(Using)
81
+ content
82
+ else
83
+ Operator.to_sparql(content, project: nil, **options)
84
+ end
85
+ end
86
+ end
51
87
  end # Modify
52
88
  end # Operator
53
89
  end; end # SPARQL::Algebra
@@ -5,11 +5,20 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Returns the month part of `arg` as an integer.
7
7
  #
8
- # @example
9
- # (prefix ((: <http://example.org/>))
10
- # (project (?s ?x)
11
- # (extend ((?x (month ?date)))
12
- # (bgp (triple ?s :date ?date)))))
8
+ # [121] BuiltInCall ::= ... | 'MONTH' '(' Expression ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.org/>
12
+ # SELECT ?s (MONTH(?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 (month ?date)))
21
+ # (bgp (triple ?s :date ?date)))))
13
22
  #
14
23
  # @see https://www.w3.org/TR/sparql11-query/#func-month
15
24
  class Month < Operator::Unary
@@ -24,10 +33,19 @@ module SPARQL; module Algebra
24
33
  # the operand
25
34
  # @return [RDF::Literal]
26
35
  # @raise [TypeError] if the operand is not a simple literal
27
- def apply(operand)
36
+ def apply(operand, **options)
28
37
  raise TypeError, "expected an RDF::Literal::DateTime, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::DateTime)
29
38
  RDF::Literal(operand.object.month)
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
+ "MONTH(#{operands.last.to_sparql(**options)})"
48
+ end
31
49
  end # Month
32
50
  end # Operator
33
51
  end; end # SPARQL::Algebra
@@ -6,8 +6,14 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # The MOVE operation is a shortcut for moving all data from an input graph into a destination graph. The input graph is removed after insertion and data from the destination graph, if any, is removed before insertion.
8
8
  #
9
- # @example
10
- # (move silent <iri> to default)
9
+ # [36] Move ::= 'MOVE' 'SILENT'? GraphOrDefault 'TO' GraphOrDefault
10
+ #
11
+ # @example SPARQL Grammar
12
+ # MOVE SILENT GRAPH <http://www.example.com/g1> TO DEFAULT
13
+ #
14
+ # @example SSE
15
+ # (update
16
+ # (move silent <http://www.example.com/g1> default))
11
17
  #
12
18
  # @see https://www.w3.org/TR/sparql11-update/#move
13
19
  class Move < Operator
@@ -62,6 +68,18 @@ module SPARQL; module Algebra
62
68
  end
63
69
  queryable
64
70
  end
71
+
72
+ ##
73
+ #
74
+ # Returns a partial SPARQL grammar for this operator.
75
+ #
76
+ # @return [String]
77
+ def to_sparql(**options)
78
+ *args, last = operands.dup
79
+ args += [:TO, last]
80
+
81
+ "MOVE " + args.to_sparql(**options)
82
+ end
65
83
  end # Move
66
84
  end # Operator
67
85
  end; end # SPARQL::Algebra