sparql 3.1.8 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +29 -22
  3. data/VERSION +1 -1
  4. data/bin/sparql +13 -4
  5. data/lib/sparql/algebra/extensions.rb +93 -33
  6. data/lib/sparql/algebra/operator/abs.rb +22 -2
  7. data/lib/sparql/algebra/operator/add.rb +21 -2
  8. data/lib/sparql/algebra/operator/alt.rb +26 -2
  9. data/lib/sparql/algebra/operator/and.rb +25 -3
  10. data/lib/sparql/algebra/operator/asc.rb +20 -1
  11. data/lib/sparql/algebra/operator/ask.rb +17 -1
  12. data/lib/sparql/algebra/operator/avg.rb +17 -1
  13. data/lib/sparql/algebra/operator/base.rb +18 -1
  14. data/lib/sparql/algebra/operator/bgp.rb +5 -1
  15. data/lib/sparql/algebra/operator/bnode.rb +33 -10
  16. data/lib/sparql/algebra/operator/bound.rb +22 -1
  17. data/lib/sparql/algebra/operator/ceil.rb +25 -2
  18. data/lib/sparql/algebra/operator/clear.rb +16 -2
  19. data/lib/sparql/algebra/operator/coalesce.rb +33 -11
  20. data/lib/sparql/algebra/operator/compare.rb +9 -0
  21. data/lib/sparql/algebra/operator/concat.rb +26 -2
  22. data/lib/sparql/algebra/operator/construct.rb +29 -6
  23. data/lib/sparql/algebra/operator/contains.rb +24 -2
  24. data/lib/sparql/algebra/operator/copy.rb +19 -2
  25. data/lib/sparql/algebra/operator/count.rb +17 -1
  26. data/lib/sparql/algebra/operator/create.rb +19 -2
  27. data/lib/sparql/algebra/operator/dataset.rb +17 -0
  28. data/lib/sparql/algebra/operator/datatype.rb +25 -6
  29. data/lib/sparql/algebra/operator/day.rb +23 -5
  30. data/lib/sparql/algebra/operator/delete.rb +27 -2
  31. data/lib/sparql/algebra/operator/delete_data.rb +23 -2
  32. data/lib/sparql/algebra/operator/delete_where.rb +24 -2
  33. data/lib/sparql/algebra/operator/desc.rb +20 -1
  34. data/lib/sparql/algebra/operator/describe.rb +27 -4
  35. data/lib/sparql/algebra/operator/distinct.rb +18 -1
  36. data/lib/sparql/algebra/operator/divide.rb +26 -2
  37. data/lib/sparql/algebra/operator/drop.rb +17 -2
  38. data/lib/sparql/algebra/operator/encode_for_uri.rb +24 -2
  39. data/lib/sparql/algebra/operator/equal.rb +12 -2
  40. data/lib/sparql/algebra/operator/exists.rb +28 -4
  41. data/lib/sparql/algebra/operator/exprlist.rb +12 -1
  42. data/lib/sparql/algebra/operator/extend.rb +31 -6
  43. data/lib/sparql/algebra/operator/filter.rb +27 -5
  44. data/lib/sparql/algebra/operator/floor.rb +25 -2
  45. data/lib/sparql/algebra/operator/graph.rb +13 -0
  46. data/lib/sparql/algebra/operator/greater_than.rb +12 -3
  47. data/lib/sparql/algebra/operator/greater_than_or_equal.rb +12 -2
  48. data/lib/sparql/algebra/operator/group.rb +34 -8
  49. data/lib/sparql/algebra/operator/group_concat.rb +19 -7
  50. data/lib/sparql/algebra/operator/hours.rb +23 -5
  51. data/lib/sparql/algebra/operator/if.rb +21 -4
  52. data/lib/sparql/algebra/operator/in.rb +18 -1
  53. data/lib/sparql/algebra/operator/insert.rb +22 -2
  54. data/lib/sparql/algebra/operator/insert_data.rb +23 -2
  55. data/lib/sparql/algebra/operator/iri.rb +21 -4
  56. data/lib/sparql/algebra/operator/is_blank.rb +19 -1
  57. data/lib/sparql/algebra/operator/is_iri.rb +19 -1
  58. data/lib/sparql/algebra/operator/is_literal.rb +19 -1
  59. data/lib/sparql/algebra/operator/is_numeric.rb +21 -3
  60. data/lib/sparql/algebra/operator/is_triple.rb +32 -0
  61. data/lib/sparql/algebra/operator/join.rb +22 -1
  62. data/lib/sparql/algebra/operator/lang.rb +25 -0
  63. data/lib/sparql/algebra/operator/lang_matches.rb +22 -1
  64. data/lib/sparql/algebra/operator/lcase.rb +23 -2
  65. data/lib/sparql/algebra/operator/left_join.rb +29 -1
  66. data/lib/sparql/algebra/operator/less_than.rb +12 -3
  67. data/lib/sparql/algebra/operator/less_than_or_equal.rb +12 -2
  68. data/lib/sparql/algebra/operator/load.rb +25 -2
  69. data/lib/sparql/algebra/operator/max.rb +17 -1
  70. data/lib/sparql/algebra/operator/md5.rb +22 -5
  71. data/lib/sparql/algebra/operator/min.rb +18 -2
  72. data/lib/sparql/algebra/operator/minus.rb +25 -7
  73. data/lib/sparql/algebra/operator/minutes.rb +23 -5
  74. data/lib/sparql/algebra/operator/modify.rb +41 -5
  75. data/lib/sparql/algebra/operator/month.rb +23 -5
  76. data/lib/sparql/algebra/operator/move.rb +20 -2
  77. data/lib/sparql/algebra/operator/multiply.rb +26 -3
  78. data/lib/sparql/algebra/operator/negate.rb +23 -3
  79. data/lib/sparql/algebra/operator/not.rb +24 -3
  80. data/lib/sparql/algebra/operator/not_equal.rb +13 -0
  81. data/lib/sparql/algebra/operator/notexists.rb +30 -6
  82. data/lib/sparql/algebra/operator/notin.rb +20 -3
  83. data/lib/sparql/algebra/operator/notoneof.rb +12 -2
  84. data/lib/sparql/algebra/operator/now.rb +24 -5
  85. data/lib/sparql/algebra/operator/object.rb +32 -0
  86. data/lib/sparql/algebra/operator/or.rb +26 -3
  87. data/lib/sparql/algebra/operator/order.rb +20 -1
  88. data/lib/sparql/algebra/operator/path.rb +29 -2
  89. data/lib/sparql/algebra/operator/path_opt.rb +21 -2
  90. data/lib/sparql/algebra/operator/path_plus.rb +21 -2
  91. data/lib/sparql/algebra/operator/path_star.rb +20 -2
  92. data/lib/sparql/algebra/operator/plus.rb +42 -3
  93. data/lib/sparql/algebra/operator/predicate.rb +32 -0
  94. data/lib/sparql/algebra/operator/prefix.rb +24 -3
  95. data/lib/sparql/algebra/operator/project.rb +51 -5
  96. data/lib/sparql/algebra/operator/rand.rb +30 -2
  97. data/lib/sparql/algebra/operator/reduced.rb +18 -1
  98. data/lib/sparql/algebra/operator/regex.rb +26 -18
  99. data/lib/sparql/algebra/operator/replace.rb +26 -6
  100. data/lib/sparql/algebra/operator/reverse.rb +20 -2
  101. data/lib/sparql/algebra/operator/round.rb +25 -2
  102. data/lib/sparql/algebra/operator/same_term.rb +24 -6
  103. data/lib/sparql/algebra/operator/sample.rb +30 -8
  104. data/lib/sparql/algebra/operator/seconds.rb +23 -5
  105. data/lib/sparql/algebra/operator/seq.rb +20 -2
  106. data/lib/sparql/algebra/operator/sequence.rb +0 -10
  107. data/lib/sparql/algebra/operator/sha1.rb +18 -1
  108. data/lib/sparql/algebra/operator/sha256.rb +18 -1
  109. data/lib/sparql/algebra/operator/sha384.rb +18 -1
  110. data/lib/sparql/algebra/operator/sha512.rb +18 -1
  111. data/lib/sparql/algebra/operator/slice.rb +27 -5
  112. data/lib/sparql/algebra/operator/str.rb +21 -1
  113. data/lib/sparql/algebra/operator/strafter.rb +25 -2
  114. data/lib/sparql/algebra/operator/strbefore.rb +25 -2
  115. data/lib/sparql/algebra/operator/strdt.rb +22 -1
  116. data/lib/sparql/algebra/operator/strends.rb +25 -3
  117. data/lib/sparql/algebra/operator/strlang.rb +25 -6
  118. data/lib/sparql/algebra/operator/strlen.rb +23 -2
  119. data/lib/sparql/algebra/operator/strstarts.rb +25 -2
  120. data/lib/sparql/algebra/operator/struuid.rb +29 -9
  121. data/lib/sparql/algebra/operator/subject.rb +32 -0
  122. data/lib/sparql/algebra/operator/substr.rb +23 -2
  123. data/lib/sparql/algebra/operator/subtract.rb +28 -2
  124. data/lib/sparql/algebra/operator/sum.rb +17 -1
  125. data/lib/sparql/algebra/operator/table.rb +42 -4
  126. data/lib/sparql/algebra/operator/timezone.rb +23 -5
  127. data/lib/sparql/algebra/operator/tz.rb +22 -5
  128. data/lib/sparql/algebra/operator/ucase.rb +23 -2
  129. data/lib/sparql/algebra/operator/union.rb +29 -6
  130. data/lib/sparql/algebra/operator/update.rb +25 -4
  131. data/lib/sparql/algebra/operator/using.rb +32 -2
  132. data/lib/sparql/algebra/operator/uuid.rb +27 -8
  133. data/lib/sparql/algebra/operator/with.rb +38 -4
  134. data/lib/sparql/algebra/operator/year.rb +23 -5
  135. data/lib/sparql/algebra/operator.rb +99 -6
  136. data/lib/sparql/algebra/sxp_extensions.rb +3 -3
  137. data/lib/sparql/grammar/parser11.rb +4 -4
  138. metadata +22 -35
  139. data/lib/sparql/algebra/operator/triple.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fc6d6745c325bd23d83fe640eb238a22406b567cf06223703afd90ea5733be1
4
- data.tar.gz: 056cde1c14633aa791f492be673eb023bab95d7af4e5b19fb94c99540fc22908
3
+ metadata.gz: ecbe9289bf43f7fa28940a82545ec08b19c54d8bdf64693934405e83ddb4cc53
4
+ data.tar.gz: 24ab0942be18a9d9d281452ba9a7195dcad2a31755bda6d84afe4f49fe7c34c1
5
5
  SHA512:
6
- metadata.gz: 32187664d7d06bd49cffa8354987ce3f11ba44b35960a92ac80353a538a15489b342f1d3e66a0ad792971489e83cc57ab05b936e93f8e04fe2f5df4a527d3d39
7
- data.tar.gz: 9d8a75fd40c9ccbac6a9753d9b7a04b9e26a4504a55636d61d3d34c1d4dde77c6838d5ac45828a40d06b7c4658971c1f435da0c6812e7b2eda4aa5dfcfaa9cda
6
+ metadata.gz: 89a77c749eb99b0fe83f27d5f413556ac2f6cf22af7e06b8e0588155bbf5a50eb053b1f87ffe11a13b5fd873d5fcaaee1166cdf336aacd3029380898a82da382
7
+ data.tar.gz: 13be95c405b9fdf7e678bc9bbaf6dcc45075a692a08e1762deacc0779948996fdc992376f3a564644f50270282c76a759023d7393e28db07ec7828a73324a948
data/README.md CHANGED
@@ -23,8 +23,7 @@ This is a [Ruby][] implementation of [SPARQL][] for [RDF.rb][].
23
23
  * Compatible with any [Rack][] or [Sinatra][] application and any Rack-based framework.
24
24
  * Helper method for describing [SPARQL Service Description][SSD]
25
25
  * Implementation Report: {file:etc/earl.html EARL}
26
- * Compatible with Ruby >= 2.2.2.
27
- * Compatible with older Ruby versions with the help of the [Backports][] gem.
26
+ * Compatible with Ruby >= 2.6.
28
27
  * Supports Unicode query strings both on all versions of Ruby.
29
28
  * Provisional support for [SPARQL-star][].
30
29
 
@@ -248,27 +247,27 @@ a full set of RDF formats.
248
247
  ### Querying a repository with a SPARQL query
249
248
 
250
249
  queryable = RDF::Repository.load("etc/doap.ttl")
251
- sse = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
252
- queryable.query(sse) do |result|
250
+ query = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
251
+ queryable.query(query) do |result|
253
252
  result.inspect
254
253
  end
255
254
 
256
255
  ### Executing a SPARQL query against a repository
257
256
 
258
257
  queryable = RDF::Repository.load("etc/doap.ttl")
259
- sse = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
260
- sse.execute(queryable) do |result|
258
+ query = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
259
+ query.execute(queryable) do |result|
261
260
  result.inspect
262
261
  end
263
262
 
264
263
  ### Updating a repository
265
264
 
266
265
  queryable = RDF::Repository.load("etc/doap.ttl")
267
- sse = SPARQL.parse(%(
266
+ update = SPARQL.parse(%(
268
267
  PREFIX doap: <http://usefulinc.com/ns/doap#>
269
268
  INSERT DATA { <https://rubygems> doap:implements <http://www.w3.org/TR/sparql11-update/>}
270
269
  ), update: true)
271
- sse.execute(queryable)
270
+ update.execute(queryable)
272
271
 
273
272
  ### Rendering solutions as JSON, XML, CSV, TSV or HTML
274
273
  queryable = RDF::Repository.load("etc/doap.ttl")
@@ -277,8 +276,13 @@ a full set of RDF formats.
277
276
 
278
277
  ### Parsing a SPARQL query string to SSE
279
278
 
280
- sse = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
281
- sse.to_sxp #=> (bgp (triple ?s ?p ?o))
279
+ query = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
280
+ query.to_sxp #=> (bgp (triple ?s ?p ?o))
281
+
282
+ ### Parsing a SSE to SPARQL query or update string to SPARQL
283
+
284
+ query = SPARQL::Algebra.parse(%{(bgp (triple ?s ?p ?o))})
285
+ sparql = query.to_sparql #=> "SELECT * WHERE { ?s ?p ?o }"
282
286
 
283
287
  ### Command line processing
284
288
 
@@ -289,6 +293,10 @@ a full set of RDF formats.
289
293
  sparql parse etc/input.rq
290
294
  sparql parse -e "SELECT * WHERE { ?s ?p ?o }"
291
295
 
296
+ # Generate SPARQL Query from SSE
297
+ sparql parse --sse etc/input.sse --format sparql
298
+ sparql parse --sse --format sparql -e "(dataset (<http://usefulinc.com/ns/doap>) (bgp (triple ?s ?p ?o))))"
299
+
292
300
  # Run query using SSE input
293
301
  sparql execute --dataset etc/doap.ttl --sse etc/input.sse
294
302
  sparql execute --sse -e "(dataset (<etc/doap.ttl>) (bgp (triple ?s ?p ?o))))"
@@ -368,19 +376,19 @@ Full documentation available on [Rubydoc.info][SPARQL doc]
368
376
 
369
377
  ## Dependencies
370
378
 
371
- * [Ruby](https://ruby-lang.org/) (>= 2.2.2)
372
- * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.0)
373
- * [SPARQL::Client](https://rubygems.org/gems/sparql-client) (~> 3.0)
374
- * [SXP](https://rubygems.org/gems/sxp) (~> 1.0)
375
- * [Builder](https://rubygems.org/gems/builder) (>= 3.0.0)
376
- * [JSON](https://rubygems.org/gems/json) (>= 1.8.2)
377
- * Soft dependency on [Linked Data][] (>= 3.0)
378
- * Soft dependency on [Nokogiri](https://rubygems.org/gems/nokogiri) (>= 1.7)
379
+ * [Ruby](https://ruby-lang.org/) (>= 2.6)
380
+ * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.2)
381
+ * [SPARQL::Client](https://rubygems.org/gems/sparql-client) (~> 3.1)
382
+ * [SXP](https://rubygems.org/gems/sxp) (~> 1.2)
383
+ * [Builder](https://rubygems.org/gems/builder) (~> 3.2)
384
+ * [JSON](https://rubygems.org/gems/json) (~> 2.6)
385
+ * Soft dependency on [Linked Data][] (>= 3.1)
386
+ * Soft dependency on [Nokogiri](https://rubygems.org/gems/nokogiri) (~> 1.12)
379
387
  Falls back to REXML for XML parsing Builder for XML serializing. Nokogiri is much more efficient
380
- * Soft dependency on [Equivalent XML](https://rubygems.org/gems/equivalent-xml) (>= 0.3.0)
388
+ * Soft dependency on [Equivalent XML](https://rubygems.org/gems/equivalent-xml) (>= 0.6)
381
389
  Equivalent XML performs more efficient comparisons of XML Literals when Nokogiri is included
382
- * Soft dependency on [Rack][] (>= 2.0)
383
- * Soft dependency on [Sinatra][] (>= 2.0)
390
+ * Soft dependency on [Rack][] (~> 2.2)
391
+ * Soft dependency on [Sinatra][] (~> 2.1)
384
392
 
385
393
  ## Installation
386
394
 
@@ -450,7 +458,6 @@ A copy of the [SPARQL 1.0 tests][] and [SPARQL 1.1 tests][] are also included in
450
458
  [RDF.rb]: https://rubydoc.info/github/ruby-rdf/rdf
451
459
  [RDF-star]: https://w3c.github.io/rdf-star/rdf-star-cg-spec.html
452
460
  [SPARQL-star]: https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#sparql-query-language
453
- [Backports]: https://rubygems.org/gems/backports
454
461
  [Linked Data]: https://rubygems.org/gems/linkeddata
455
462
  [SPARQL doc]: https://rubydoc.info/github/ruby-rdf/sparql/frames
456
463
  [SPARQL XML]: https://www.w3.org/TR/rdf-sparql-XMLres/
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.8
1
+ 3.2.0
data/bin/sparql CHANGED
@@ -45,9 +45,18 @@ def run(input, **options)
45
45
  SPARQL::Grammar.parse(input, **options)
46
46
  end
47
47
 
48
- puts ("\nSSE:\n" + query.to_sse) if options[:debug] || options[:to_sse]
48
+ puts ("\nSSE:\n" + query.to_sse) if options[:debug]
49
49
 
50
- unless options[:to_sse]
50
+ if options[:parse_only]
51
+ case options[:format]
52
+ when :sparql
53
+ puts ("\nSPARQL:\n" + query.to_sparql)
54
+ when nil, :sse
55
+ puts ("\nSSE:\n" + query.to_sse)
56
+ else
57
+ $stderr.puts "Unknown output format for parsing: #{options[:format]}. Use 'sse' or 'sparql'"
58
+ end
59
+ else
51
60
  res = query.execute(options[:dataset], logger: options[:logger])
52
61
  display_results(res, **options)
53
62
  end
@@ -98,7 +107,7 @@ def usage
98
107
  puts " --dataset: File containing RDF graph or dataset"
99
108
  puts " --debug: Display detailed debug output"
100
109
  puts " --execute,-e: Use option argument as the SPARQL input if no query-file given"
101
- puts " --format: Output format for results"
110
+ puts " --format: Output format for results (json, xml, csv, tsv, html, sparql, sse, or another RDF format)"
102
111
  puts " --port,-p Port on which to run server; defaults to 9292"
103
112
  puts " --sse: Query input is in SSE format"
104
113
  puts " --update: Process query as a SPARQL Update"
@@ -151,7 +160,7 @@ end
151
160
 
152
161
  case cmd
153
162
  when 'execute', 'parse'
154
- options[:to_sse] = true if cmd == 'parse'
163
+ options[:parse_only] = true if cmd == 'parse'
155
164
  input ||= ARGV.empty? ? $stdin.read : RDF::Util::File.open_file(ARGV.first).read
156
165
  run(input, **options)
157
166
  when 'query'
@@ -43,6 +43,15 @@ class Object
43
43
  def deep_dup
44
44
  dup
45
45
  end
46
+
47
+ ##
48
+ #
49
+ # Returns a partial SPARQL grammar for this term.
50
+ #
51
+ # @return [String]
52
+ def to_sparql(**options)
53
+ to_sxp(**options)
54
+ end
46
55
  end
47
56
 
48
57
  ##
@@ -56,6 +65,16 @@ class Array
56
65
  map {|x| x.to_sxp_bin}
57
66
  end
58
67
 
68
+ ##
69
+ #
70
+ # Returns a partial SPARQL grammar for this array.
71
+ #
72
+ # @param [String] delimiter (" ")
73
+ # @return [String]
74
+ def to_sparql(delimiter: " ", **options)
75
+ map {|e| e.to_sparql(**options)}.join(delimiter)
76
+ end
77
+
59
78
  ##
60
79
  # Evaluates the array using the given variable `bindings`.
61
80
  #
@@ -216,15 +235,6 @@ end
216
235
  ##
217
236
  # Extensions for Ruby's `Hash` class.
218
237
  class Hash
219
- ##
220
- # Returns the SXP representation of this object, defaults to `self`.
221
- #
222
- # @return [String]
223
- def to_sxp_bin
224
- to_a.to_sxp_bin
225
- end
226
- def to_sxp; to_sxp_bin; end
227
-
228
238
  ##
229
239
  # A duplicate of this hash.
230
240
  #
@@ -278,24 +288,20 @@ module RDF::Term
278
288
  # @see SPARQL::Algebra::Expression#optimize
279
289
  def optimize(**options)
280
290
  optimized = self.deep_dup
281
- optimized.lexical = nil if optimized.respond_to?(:lexical=)
282
- optimized
291
+ #optimized.lexical = nil if optimized.respond_to?(:lexical=)
292
+ #optimized
283
293
  end
284
- end # RDF::Term
285
294
 
286
- class RDF::Literal::Double
287
295
  ##
288
- # Returns the SXP representation of this object.
296
+ #
297
+ # Returns a partial SPARQL grammar for this term.
289
298
  #
290
299
  # @return [String]
291
- def to_sxp
292
- case
293
- when nan? then 'nan.0'
294
- when infinite? then (infinite? > 0 ? '+inf.0' : '-inf.0')
295
- else canonicalize.to_s.downcase
296
- end
300
+ def to_sparql(**options)
301
+ to_sxp(**options)
297
302
  end
298
- end
303
+ end # RDF::Term
304
+
299
305
 
300
306
  # Override RDF::Queryable to execute against SPARQL::Algebra::Query elements as well as RDF::Query and RDF::Pattern
301
307
  module RDF::Queryable
@@ -343,6 +349,15 @@ module RDF::Queryable
343
349
  query_without_sparql(pattern, **options, &block)
344
350
  end
345
351
  end
352
+
353
+ ##
354
+ #
355
+ # Returns a partial SPARQL grammar for this term.
356
+ #
357
+ # @return [String]
358
+ def to_sparql(**options)
359
+ raise NotImplementedError, "SPARQL::Algebra '#{first}' operator not implemented"
360
+ end
346
361
  end
347
362
 
348
363
  class RDF::Statement
@@ -361,9 +376,29 @@ class RDF::Statement
361
376
  ##
362
377
  # Returns an S-Expression (SXP) representation
363
378
  #
379
+ # @param [Hash{Symbol => RDF::URI}] prefixes (nil)
380
+ # @param [RDF::URI] base_uri (nil)
364
381
  # @return [String]
365
- def to_sxp
366
- to_sxp_bin.to_sxp
382
+ def to_sxp(prefixes: nil, base_uri: nil)
383
+ to_sxp_bin.to_sxp(prefixes: prefixes, base_uri: base_uri)
384
+ end
385
+
386
+ ##
387
+ #
388
+ # Returns a partial SPARQL grammar for this term.
389
+ #
390
+ # @param [Boolean] as_statement (false) serialize as < ... >, otherwise TRIPLE(...)
391
+ # @return [String]
392
+ def to_sparql(as_statement: false, **options)
393
+ return "TRIPLE(#{to_triple.to_sparql(as_statement: true, **options)})" unless as_statement
394
+
395
+ to_triple.map do |term|
396
+ if term.is_a?(::RDF::Statement)
397
+ "<<" + term.to_sparql(**options) + ">>"
398
+ else
399
+ term.to_sparql(**options)
400
+ end
401
+ end.join(" ") + " ."
367
402
  end
368
403
 
369
404
  ##
@@ -411,6 +446,19 @@ class RDF::Query
411
446
  end
412
447
  end
413
448
 
449
+ ##
450
+ #
451
+ # Returns a partial SPARQL grammar for this term.
452
+ #
453
+ # @param [Boolean] top_level (true)
454
+ # Treat this as a top-level, generating SELECT ... WHERE {}
455
+ # @return [String]
456
+ def to_sparql(top_level: true, **options)
457
+ str = @patterns.map { |e| e.to_sparql(as_statement: true, top_level: false, **options) }.join("\n")
458
+ str = "GRAPH #{graph_name.to_sparql(**options)} {\n#{str}\n}\n" if graph_name
459
+ top_level ? SPARQL::Algebra::Operator.to_sparql(str, **options) : str
460
+ end
461
+
414
462
  ##
415
463
  # Binds the pattern to a solution, making it no longer variable if all variables are resolved to bound variables
416
464
  #
@@ -462,11 +510,11 @@ class RDF::Query
462
510
  def optimize!(**options)
463
511
  @patterns = @patterns.map do |pattern|
464
512
  components = pattern.to_quad.map do |term|
465
- if term.respond_to?(:lexical=)
466
- term.dup.instance_eval {@lexical = nil; self}
467
- else
513
+ #if term.respond_to?(:lexical=)
514
+ # term.dup.instance_eval {@lexical = nil; self}
515
+ #else
468
516
  term
469
- end
517
+ #end
470
518
  end
471
519
  RDF::Query::Pattern.from(components, **pattern.options)
472
520
  end
@@ -530,11 +578,15 @@ class RDF::Query::Variable
530
578
  self
531
579
  end
532
580
 
533
- # Display variable as SXP
534
- # @return [Array]
535
- def to_sxp
536
- prefix = distinguished? ? (existential? ? '$' : '?') : (existential? ? '$$' : '??')
537
- unbound? ? "#{prefix}#{name}".to_sym.to_sxp : ["#{prefix}#{name}".to_sym, value].to_sxp
581
+ ##
582
+ #
583
+ # Returns a partial SPARQL grammar for this term.
584
+ #
585
+ # The Non-distinguished form (`??xxx`) is not part of the grammar, so replace with a blank-node
586
+ #
587
+ # @return [String]
588
+ def to_sparql(**options)
589
+ self.distinguished? ? super : "_:_nd#{self.name}"
538
590
  end
539
591
  end # RDF::Query::Variable
540
592
 
@@ -576,5 +628,13 @@ class RDF::Query::Solution
576
628
  def to_sxp_bin
577
629
  to_a.to_sxp_bin
578
630
  end
579
- def to_sxp; to_sxp_bin; end
631
+
632
+ # Transform Solution into an SXP
633
+ #
634
+ # @param [Hash{Symbol => RDF::URI}] prefixes (nil)
635
+ # @param [RDF::URI] base_uri (nil)
636
+ # @return [String]
637
+ def to_sxp(prefixes: nil, base_uri: nil)
638
+ to_sxp_bin.to_sxp(prefixes: prefixes, base_uri: base_uri)
639
+ end
580
640
  end # RDF::Query::Solution
@@ -3,8 +3,19 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL logical `abs` operator.
5
5
  #
6
- # @example
7
- # (abs ?x)
6
+ # [121] BuiltInCall ::= ... | 'ABS' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Query
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT * WHERE {
11
+ # ?s :num ?num
12
+ # FILTER(ABS(?num) >= 2)
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/>))
17
+ # (filter (>= (abs ?num) 2)
18
+ # (bgp (triple ?s :num ?num))))
8
19
  #
9
20
  # @see https://www.w3.org/TR/sparql11-query/#func-abs
10
21
  # @see https://www.w3.org/TR/xpath-functions/#func-abs
@@ -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
+ "ABS(#{operands.first.to_sparql(**options)})"
48
+ end
29
49
  end # Abs
30
50
  end # Operator
31
51
  end; end # SPARQL::Algebra
@@ -6,8 +6,15 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # The ADD operation is a shortcut for inserting all data from an input graph into a destination graph. Data from the input graph is not affected, and initial data from the destination graph, if any, is kept intact.
8
8
  #
9
- # @example
10
- # (add default <a>)
9
+ # [35] Add ::= "ADD" "SILENT"? GraphOrDefault "TO" GraphOrDefault
10
+ #
11
+ # @example SPARQL Update
12
+ # PREFIX : <http://example.org/>
13
+ # ADD DEFAULT TO :g1
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/>))
17
+ # (update (add default :g1)))
11
18
  #
12
19
  # @see https://www.w3.org/TR/sparql11-update/#add
13
20
  class Add < Operator
@@ -51,6 +58,18 @@ module SPARQL; module Algebra
51
58
  end
52
59
  queryable
53
60
  end
61
+
62
+ ##
63
+ #
64
+ # Returns a partial SPARQL grammar for this operator.
65
+ #
66
+ # @return [String]
67
+ def to_sparql(**options)
68
+ *args, last = operands.dup
69
+ args += [:TO, last]
70
+
71
+ "ADD " + args.to_sparql(**options)
72
+ end
54
73
  end # Add
55
74
  end # Operator
56
75
  end; end # SPARQL::Algebra
@@ -7,8 +7,23 @@ module SPARQL; module Algebra
7
7
  #
8
8
  # eval(Path(X, alt(P,Q), Y)) = Union(eval(Path(X, P, Y)), eval(Path(X, Q, Y)))
9
9
  #
10
- # @example
11
- # (alt a b)
10
+ # [89] PathAlternative ::= PathSequence ( '|' PathSequence )*
11
+ #
12
+ # @example SPARQL Query
13
+ # PREFIX : <http://www.example.org/>
14
+ # SELECT ?t
15
+ # WHERE {
16
+ # :a :p1|:p2/:p3|:p4 ?t
17
+ # }
18
+ #
19
+ # @example SSE
20
+ # (prefix ((: <http://www.example.org/>))
21
+ # (project (?t)
22
+ # (path :a
23
+ # (alt
24
+ # (alt :p1 (seq :p2 :p3))
25
+ # :p4)
26
+ # ?t)))
12
27
  #
13
28
  # @see https://www.w3.org/TR/sparql11-query/#defn_evalPP_alternative
14
29
  class Alt < Operator::Binary
@@ -57,6 +72,15 @@ module SPARQL; module Algebra
57
72
  query = Union.new(qa, qb)
58
73
  queryable.query(query, depth: options[:depth].to_i + 1, **options, &block)
59
74
  end
75
+
76
+ ##
77
+ #
78
+ # Returns a partial SPARQL grammar for this operator.
79
+ #
80
+ # @return [String]
81
+ def to_sparql(**options)
82
+ "#{operands.first.to_sparql(**options)}|#{operands.last.to_sparql(**options)}"
83
+ end
60
84
  end # Alt
61
85
  end # Operator
62
86
  end; end # SPARQL::Algebra
@@ -3,9 +3,22 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL logical `and` operator.
5
5
  #
6
- # @example
7
- # (&& ?x ?y)
8
- # (and ?x ?y)
6
+ # [112] ConditionalAndExpression::= ValueLogical ( '&&' ValueLogical )*
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
10
+ # PREFIX : <http://example.org/ns#>
11
+ # SELECT ?a
12
+ # WHERE { ?a :p ?v .
13
+ # FILTER ("true"^^xsd:boolean && ?v) .
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix
18
+ # ((xsd: <http://www.w3.org/2001/XMLSchema#>) (: <http://example.org/ns#>))
19
+ # (project (?a)
20
+ # (filter (&& true ?v)
21
+ # (bgp (triple ?a :p ?v)))))
9
22
  #
10
23
  # @see https://www.w3.org/TR/sparql11-query/#func-logical-and
11
24
  # @see https://www.w3.org/TR/sparql11-query/#evaluation
@@ -60,6 +73,15 @@ module SPARQL; module Algebra
60
73
  else RDF::Literal(left && right)
61
74
  end
62
75
  end
76
+
77
+ ##
78
+ #
79
+ # Returns a partial SPARQL grammar for this operator.
80
+ #
81
+ # @return [String]
82
+ def to_sparql(**options)
83
+ "(#{operands.first.to_sparql(**options)} && #{operands.last.to_sparql(**options)})"
84
+ end
63
85
  end # And
64
86
  end # Operator
65
87
  end; end # SPARQL::Algebra
@@ -3,7 +3,15 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL ascending sort operator.
5
5
  #
6
- # @example
6
+ # [24] OrderCondition ::= ( ( 'ASC' | 'DESC' ) BrackettedExpression ) | ( Constraint | Var )
7
+ #
8
+ # @example SPARQL Query
9
+ # PREFIX foaf: <http://xmlns.com/foaf/0.1/>
10
+ # SELECT ?name
11
+ # WHERE { ?x foaf:name ?name }
12
+ # ORDER BY ASC(?name)
13
+ #
14
+ # @example SSE
7
15
  # (prefix ((foaf: <http://xmlns.com/foaf/0.1/>))
8
16
  # (project (?name)
9
17
  # (order ((asc ?name))
@@ -27,6 +35,17 @@ module SPARQL; module Algebra
27
35
  def evaluate(bindings, **options)
28
36
  operand(0).evaluate(bindings, depth: options[:depth].to_i + 1, **options)
29
37
  end
38
+
39
+ ##
40
+ #
41
+ # Returns a partial SPARQL grammar for this operator.
42
+ #
43
+ # Provides order to descendant query.
44
+ #
45
+ # @return [String]
46
+ def to_sparql(**options)
47
+ "ASC(#{operands.last.to_sparql(**options)})"
48
+ end
30
49
  end # Asc
31
50
  end # Operator
32
51
  end; end # SPARQL::Algebra
@@ -5,7 +5,13 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Applications can use the ASK form to test whether or not a query pattern has a solution. No information is returned about the possible query solutions, just whether or not a solution exists.
7
7
  #
8
- # @example
8
+ # [12] AskQuery ::= 'ASK' DatasetClause* WhereClause ValuesClause
9
+ #
10
+ # @example SPARQL Query
11
+ # PREFIX : <http://example/>
12
+ # ASK { :x :p ?x }
13
+ #
14
+ # @example SSE
9
15
  # (prefix ((: <http://example/>))
10
16
  # (ask
11
17
  # (bgp (triple :x :p ?x))))
@@ -41,6 +47,16 @@ module SPARQL; module Algebra
41
47
  def query_yields_boolean?
42
48
  true
43
49
  end
50
+
51
+ ##
52
+ #
53
+ # Returns a partial SPARQL grammar for this term.
54
+ #
55
+ # @return [String]
56
+ def to_sparql(**options)
57
+ "ASK\n" +
58
+ operands.first.to_sparql(top_level: true, project: nil, **options)
59
+ end
44
60
  end # Ask
45
61
  end # Operator
46
62
  end; end # SPARQL::Algebra
@@ -3,7 +3,14 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `avg` set function.
5
5
  #
6
- # @example
6
+ # [127] Aggregate::= ... | 'AVG' '(' 'DISTINCT'? Expression ')'
7
+ #
8
+ # @example SPARQL Query
9
+ # PREFIX : <http://www.example.org/>
10
+ # SELECT (AVG(?o) AS ?avg)
11
+ # WHERE { ?s :dec ?o }
12
+ #
13
+ # @example SSE
7
14
  # (prefix ((: <http://www.example.org/>))
8
15
  # (project (?avg)
9
16
  # (extend ((?avg ??.0))
@@ -40,6 +47,15 @@ module SPARQL; module Algebra
40
47
  raise TypeError, "Averaging non-numeric types: #{enum.flatten}"
41
48
  end
42
49
  end
50
+
51
+ ##
52
+ #
53
+ # Returns a partial SPARQL grammar for this operator.
54
+ #
55
+ # @return [String]
56
+ def to_sparql(**options)
57
+ "AVG(#{operands.to_sparql(**options)})"
58
+ end
43
59
  end # Avg
44
60
  end # Operator
45
61
  end; end # SPARQL::Algebra
@@ -3,7 +3,13 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `base` operator.
5
5
  #
6
- # @example
6
+ # [5] BaseDecl ::= 'BASE' IRIREF
7
+ #
8
+ # @example SPARQL Grammar
9
+ # BASE <http://example.org/>
10
+ # SELECT * { <a> <b> 123.0 }
11
+ #
12
+ # @example SSE
7
13
  # (base <http://example.org/>
8
14
  # (bgp (triple <a> <b> 123.0)))
9
15
  #
@@ -56,6 +62,17 @@ module SPARQL; module Algebra
56
62
  def query_yields_statements?
57
63
  operands.last.query_yields_statements?
58
64
  end
65
+
66
+ ##
67
+ #
68
+ # Returns a partial SPARQL grammar for this term.
69
+ #
70
+ # @return [String]
71
+ def to_sparql(**options)
72
+ str = "BASE #{operands.first.to_sparql}\n"
73
+
74
+ str << operands.last.to_sparql(base_uri: operands.first, **options)
75
+ end
59
76
  end # Base
60
77
  end # Operator
61
78
  end; end # SPARQL::Algebra
@@ -5,7 +5,11 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Query with `graph_name` set to false.
7
7
  #
8
- # @example
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example/>
10
+ # SELECT * { :s :p :o }
11
+ #
12
+ # @example SSE
9
13
  # (prefix ((: <http://example/>))
10
14
  # (bgp (triple ?s ?p ?o)))
11
15
  #