sparql 3.1.5 → 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.
- checksums.yaml +4 -4
- data/README.md +35 -28
- data/VERSION +1 -1
- data/bin/sparql +14 -4
- data/lib/sparql/algebra/aggregate.rb +1 -1
- data/lib/sparql/algebra/evaluatable.rb +4 -4
- data/lib/sparql/algebra/expression.rb +4 -1
- data/lib/sparql/algebra/extensions.rb +96 -29
- data/lib/sparql/algebra/operator/abs.rb +23 -3
- data/lib/sparql/algebra/operator/add.rb +21 -2
- data/lib/sparql/algebra/operator/alt.rb +26 -2
- data/lib/sparql/algebra/operator/and.rb +25 -3
- data/lib/sparql/algebra/operator/asc.rb +20 -1
- data/lib/sparql/algebra/operator/ask.rb +17 -1
- data/lib/sparql/algebra/operator/avg.rb +18 -2
- data/lib/sparql/algebra/operator/base.rb +18 -1
- data/lib/sparql/algebra/operator/bgp.rb +5 -1
- data/lib/sparql/algebra/operator/bnode.rb +34 -11
- data/lib/sparql/algebra/operator/bound.rb +22 -1
- data/lib/sparql/algebra/operator/ceil.rb +26 -3
- data/lib/sparql/algebra/operator/clear.rb +16 -2
- data/lib/sparql/algebra/operator/coalesce.rb +33 -11
- data/lib/sparql/algebra/operator/compare.rb +48 -33
- data/lib/sparql/algebra/operator/concat.rb +26 -2
- data/lib/sparql/algebra/operator/construct.rb +31 -7
- data/lib/sparql/algebra/operator/contains.rb +25 -3
- data/lib/sparql/algebra/operator/copy.rb +19 -2
- data/lib/sparql/algebra/operator/count.rb +18 -2
- data/lib/sparql/algebra/operator/create.rb +19 -2
- data/lib/sparql/algebra/operator/dataset.rb +17 -0
- data/lib/sparql/algebra/operator/datatype.rb +26 -7
- data/lib/sparql/algebra/operator/day.rb +24 -6
- data/lib/sparql/algebra/operator/delete.rb +27 -2
- data/lib/sparql/algebra/operator/delete_data.rb +23 -2
- data/lib/sparql/algebra/operator/delete_where.rb +24 -2
- data/lib/sparql/algebra/operator/desc.rb +20 -1
- data/lib/sparql/algebra/operator/describe.rb +27 -4
- data/lib/sparql/algebra/operator/distinct.rb +18 -1
- data/lib/sparql/algebra/operator/divide.rb +27 -3
- data/lib/sparql/algebra/operator/drop.rb +17 -2
- data/lib/sparql/algebra/operator/encode_for_uri.rb +25 -3
- data/lib/sparql/algebra/operator/equal.rb +13 -3
- data/lib/sparql/algebra/operator/exists.rb +28 -4
- data/lib/sparql/algebra/operator/exprlist.rb +12 -1
- data/lib/sparql/algebra/operator/extend.rb +33 -18
- data/lib/sparql/algebra/operator/filter.rb +27 -5
- data/lib/sparql/algebra/operator/floor.rb +26 -3
- data/lib/sparql/algebra/operator/graph.rb +13 -0
- data/lib/sparql/algebra/operator/greater_than.rb +14 -4
- data/lib/sparql/algebra/operator/greater_than_or_equal.rb +14 -4
- data/lib/sparql/algebra/operator/group.rb +34 -8
- data/lib/sparql/algebra/operator/group_concat.rb +20 -8
- data/lib/sparql/algebra/operator/hours.rb +24 -6
- data/lib/sparql/algebra/operator/if.rb +21 -4
- data/lib/sparql/algebra/operator/in.rb +18 -1
- data/lib/sparql/algebra/operator/insert.rb +22 -2
- data/lib/sparql/algebra/operator/insert_data.rb +23 -2
- data/lib/sparql/algebra/operator/iri.rb +22 -5
- data/lib/sparql/algebra/operator/is_blank.rb +20 -2
- data/lib/sparql/algebra/operator/is_iri.rb +20 -2
- data/lib/sparql/algebra/operator/is_literal.rb +20 -2
- data/lib/sparql/algebra/operator/is_numeric.rb +22 -4
- data/lib/sparql/algebra/operator/is_triple.rb +62 -0
- data/lib/sparql/algebra/operator/join.rb +22 -1
- data/lib/sparql/algebra/operator/lang.rb +26 -1
- data/lib/sparql/algebra/operator/lang_matches.rb +23 -2
- data/lib/sparql/algebra/operator/lcase.rb +24 -3
- data/lib/sparql/algebra/operator/left_join.rb +29 -1
- data/lib/sparql/algebra/operator/less_than.rb +14 -4
- data/lib/sparql/algebra/operator/less_than_or_equal.rb +14 -4
- data/lib/sparql/algebra/operator/load.rb +25 -2
- data/lib/sparql/algebra/operator/max.rb +18 -2
- data/lib/sparql/algebra/operator/md5.rb +23 -6
- data/lib/sparql/algebra/operator/min.rb +19 -3
- data/lib/sparql/algebra/operator/minus.rb +25 -7
- data/lib/sparql/algebra/operator/minutes.rb +24 -6
- data/lib/sparql/algebra/operator/modify.rb +41 -5
- data/lib/sparql/algebra/operator/month.rb +24 -6
- data/lib/sparql/algebra/operator/move.rb +20 -2
- data/lib/sparql/algebra/operator/multiply.rb +27 -4
- data/lib/sparql/algebra/operator/negate.rb +24 -4
- data/lib/sparql/algebra/operator/not.rb +25 -4
- data/lib/sparql/algebra/operator/not_equal.rb +16 -1
- data/lib/sparql/algebra/operator/notexists.rb +30 -6
- data/lib/sparql/algebra/operator/notin.rb +20 -3
- data/lib/sparql/algebra/operator/notoneof.rb +12 -2
- data/lib/sparql/algebra/operator/now.rb +25 -6
- data/lib/sparql/algebra/operator/object.rb +59 -0
- data/lib/sparql/algebra/operator/or.rb +26 -3
- data/lib/sparql/algebra/operator/order.rb +27 -2
- data/lib/sparql/algebra/operator/path.rb +29 -2
- data/lib/sparql/algebra/operator/path_opt.rb +21 -2
- data/lib/sparql/algebra/operator/path_plus.rb +21 -2
- data/lib/sparql/algebra/operator/path_star.rb +20 -2
- data/lib/sparql/algebra/operator/plus.rb +43 -4
- data/lib/sparql/algebra/operator/predicate.rb +59 -0
- data/lib/sparql/algebra/operator/prefix.rb +24 -3
- data/lib/sparql/algebra/operator/project.rb +51 -5
- data/lib/sparql/algebra/operator/rand.rb +31 -3
- data/lib/sparql/algebra/operator/reduced.rb +18 -1
- data/lib/sparql/algebra/operator/regex.rb +27 -19
- data/lib/sparql/algebra/operator/replace.rb +27 -7
- data/lib/sparql/algebra/operator/reverse.rb +20 -2
- data/lib/sparql/algebra/operator/round.rb +26 -3
- data/lib/sparql/algebra/operator/same_term.rb +25 -7
- data/lib/sparql/algebra/operator/sample.rb +31 -9
- data/lib/sparql/algebra/operator/seconds.rb +24 -6
- data/lib/sparql/algebra/operator/seq.rb +20 -2
- data/lib/sparql/algebra/operator/sequence.rb +0 -10
- data/lib/sparql/algebra/operator/sha1.rb +19 -2
- data/lib/sparql/algebra/operator/sha256.rb +19 -2
- data/lib/sparql/algebra/operator/sha384.rb +19 -2
- data/lib/sparql/algebra/operator/sha512.rb +19 -2
- data/lib/sparql/algebra/operator/slice.rb +27 -5
- data/lib/sparql/algebra/operator/str.rb +22 -2
- data/lib/sparql/algebra/operator/strafter.rb +26 -3
- data/lib/sparql/algebra/operator/strbefore.rb +26 -3
- data/lib/sparql/algebra/operator/strdt.rb +23 -2
- data/lib/sparql/algebra/operator/strends.rb +26 -4
- data/lib/sparql/algebra/operator/strlang.rb +26 -7
- data/lib/sparql/algebra/operator/strlen.rb +24 -3
- data/lib/sparql/algebra/operator/strstarts.rb +26 -3
- data/lib/sparql/algebra/operator/struuid.rb +30 -10
- data/lib/sparql/algebra/operator/subject.rb +61 -0
- data/lib/sparql/algebra/operator/substr.rb +24 -3
- data/lib/sparql/algebra/operator/subtract.rb +29 -3
- data/lib/sparql/algebra/operator/sum.rb +18 -2
- data/lib/sparql/algebra/operator/table.rb +42 -4
- data/lib/sparql/algebra/operator/timezone.rb +24 -6
- data/lib/sparql/algebra/operator/tz.rb +23 -6
- data/lib/sparql/algebra/operator/ucase.rb +24 -3
- data/lib/sparql/algebra/operator/union.rb +29 -6
- data/lib/sparql/algebra/operator/update.rb +25 -4
- data/lib/sparql/algebra/operator/using.rb +32 -2
- data/lib/sparql/algebra/operator/uuid.rb +28 -9
- data/lib/sparql/algebra/operator/with.rb +38 -4
- data/lib/sparql/algebra/operator/year.rb +24 -6
- data/lib/sparql/algebra/operator.rb +112 -7
- data/lib/sparql/algebra/sxp_extensions.rb +3 -3
- data/lib/sparql/grammar/meta.rb +5390 -2410
- data/lib/sparql/grammar/parser11.rb +119 -53
- data/lib/sparql/grammar/terminals11.rb +2 -0
- data/lib/sparql/grammar.rb +0 -25
- metadata +40 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ecbe9289bf43f7fa28940a82545ec08b19c54d8bdf64693934405e83ddb4cc53
|
4
|
+
data.tar.gz: 24ab0942be18a9d9d281452ba9a7195dcad2a31755bda6d84afe4f49fe7c34c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89a77c749eb99b0fe83f27d5f413556ac2f6cf22af7e06b8e0588155bbf5a50eb053b1f87ffe11a13b5fd873d5fcaaee1166cdf336aacd3029380898a82da382
|
7
|
+
data.tar.gz: 13be95c405b9fdf7e678bc9bbaf6dcc45075a692a08e1762deacc0779948996fdc992376f3a564644f50270282c76a759023d7393e28db07ec7828a73324a948
|
data/README.md
CHANGED
@@ -23,10 +23,9 @@ 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.
|
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
|
-
* Provisional support for [SPARQL
|
28
|
+
* Provisional support for [SPARQL-star][].
|
30
29
|
|
31
30
|
## Description
|
32
31
|
|
@@ -96,9 +95,9 @@ Then, use the function in a query:
|
|
96
95
|
|
97
96
|
See {SPARQL::Algebra::Expression.register_extension} for details.
|
98
97
|
|
99
|
-
### SPARQLStar (SPARQL
|
98
|
+
### SPARQLStar (SPARQL-star)
|
100
99
|
|
101
|
-
The gem supports [SPARQL
|
100
|
+
The gem supports [SPARQL-star][] where patterns may include sub-patterns recursively, for a kind of Reification.
|
102
101
|
|
103
102
|
For example, the following Turtle* file uses a statement as the subject of another statement:
|
104
103
|
|
@@ -159,7 +158,7 @@ As well as a `CONSTRUCT`:
|
|
159
158
|
<<?bob foaf:age ?age>> ?b ?c .
|
160
159
|
}
|
161
160
|
|
162
|
-
Note that results can be serialized only when the format supports [RDF
|
161
|
+
Note that results can be serialized only when the format supports [RDF-star][].
|
163
162
|
|
164
163
|
#### SPARQL results
|
165
164
|
|
@@ -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
|
-
|
252
|
-
queryable.query(
|
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
|
-
|
260
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
281
|
-
|
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.
|
372
|
-
* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.
|
373
|
-
* [SPARQL::Client](https://rubygems.org/gems/sparql-client) (~> 3.
|
374
|
-
* [SXP](https://rubygems.org/gems/sxp) (~> 1.
|
375
|
-
* [Builder](https://rubygems.org/gems/builder) (
|
376
|
-
* [JSON](https://rubygems.org/gems/json) (
|
377
|
-
* Soft dependency on [Linked Data][] (>= 3.
|
378
|
-
* Soft dependency on [Nokogiri](https://rubygems.org/gems/nokogiri) (
|
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.
|
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][] (
|
383
|
-
* Soft dependency on [Sinatra][] (
|
390
|
+
* Soft dependency on [Rack][] (~> 2.2)
|
391
|
+
* Soft dependency on [Sinatra][] (~> 2.1)
|
384
392
|
|
385
393
|
## Installation
|
386
394
|
|
@@ -448,9 +456,8 @@ A copy of the [SPARQL 1.0 tests][] and [SPARQL 1.1 tests][] are also included in
|
|
448
456
|
[grammar]: https://www.w3.org/TR/sparql11-query/#grammar
|
449
457
|
[RDF 1.1]: https://www.w3.org/TR/rdf11-concepts
|
450
458
|
[RDF.rb]: https://rubydoc.info/github/ruby-rdf/rdf
|
451
|
-
[RDF
|
452
|
-
[SPARQL
|
453
|
-
[Backports]: https://rubygems.org/gems/backports
|
459
|
+
[RDF-star]: https://w3c.github.io/rdf-star/rdf-star-cg-spec.html
|
460
|
+
[SPARQL-star]: https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#sparql-query-language
|
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
|
+
3.2.0
|
data/bin/sparql
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'rubygems'
|
3
3
|
$:.unshift("../../lib", __FILE__)
|
4
|
+
require 'logger'
|
4
5
|
require 'sparql'
|
5
6
|
begin
|
6
7
|
require 'linkeddata'
|
@@ -44,9 +45,18 @@ def run(input, **options)
|
|
44
45
|
SPARQL::Grammar.parse(input, **options)
|
45
46
|
end
|
46
47
|
|
47
|
-
puts ("\nSSE:\n" + query.to_sse) if options[:debug]
|
48
|
+
puts ("\nSSE:\n" + query.to_sse) if options[:debug]
|
48
49
|
|
49
|
-
|
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
|
50
60
|
res = query.execute(options[:dataset], logger: options[:logger])
|
51
61
|
display_results(res, **options)
|
52
62
|
end
|
@@ -97,7 +107,7 @@ def usage
|
|
97
107
|
puts " --dataset: File containing RDF graph or dataset"
|
98
108
|
puts " --debug: Display detailed debug output"
|
99
109
|
puts " --execute,-e: Use option argument as the SPARQL input if no query-file given"
|
100
|
-
puts " --format: Output format for results"
|
110
|
+
puts " --format: Output format for results (json, xml, csv, tsv, html, sparql, sse, or another RDF format)"
|
101
111
|
puts " --port,-p Port on which to run server; defaults to 9292"
|
102
112
|
puts " --sse: Query input is in SSE format"
|
103
113
|
puts " --update: Process query as a SPARQL Update"
|
@@ -150,7 +160,7 @@ end
|
|
150
160
|
|
151
161
|
case cmd
|
152
162
|
when 'execute', 'parse'
|
153
|
-
options[:
|
163
|
+
options[:parse_only] = true if cmd == 'parse'
|
154
164
|
input ||= ARGV.empty? ? $stdin.read : RDF::Util::File.open_file(ARGV.first).read
|
155
165
|
run(input, **options)
|
156
166
|
when 'query'
|
@@ -44,7 +44,7 @@ module SPARQL; module Algebra
|
|
44
44
|
# Enumerable yielding evaluated operands
|
45
45
|
# @return [RDF::Term]
|
46
46
|
# @abstract
|
47
|
-
def apply(enum)
|
47
|
+
def apply(enum, **options)
|
48
48
|
raise NotImplementedError, "#{self.class}#apply(#{operands.map(&:class).join(', ')})"
|
49
49
|
end
|
50
50
|
|
@@ -15,16 +15,16 @@ module SPARQL; module Algebra
|
|
15
15
|
# @abstract
|
16
16
|
def evaluate(bindings, **options)
|
17
17
|
args = operands.map { |operand| operand.evaluate(bindings, depth: options[:depth].to_i + 1, **options) }
|
18
|
-
options[:memoize] ? memoize(*args) : apply(*args)
|
18
|
+
options[:memoize] ? memoize(*args, **options) : apply(*args, **options)
|
19
19
|
end
|
20
20
|
|
21
21
|
##
|
22
22
|
# @param [Array<RDF::Term>] operands
|
23
23
|
# evaluated operands
|
24
24
|
# @return [RDF::Term] the memoized result
|
25
|
-
def memoize(*operands)
|
25
|
+
def memoize(*operands, **options)
|
26
26
|
@cache ||= RDF::Util::Cache.new(options[:memoize].is_a?(Integer) ? options[:memoize] : -1)
|
27
|
-
@cache[operands] ||= apply(*operands)
|
27
|
+
@cache[operands] ||= apply(*operands, **options)
|
28
28
|
end
|
29
29
|
|
30
30
|
##
|
@@ -32,7 +32,7 @@ module SPARQL; module Algebra
|
|
32
32
|
# evaluated operands
|
33
33
|
# @return [RDF::Term]
|
34
34
|
# @abstract
|
35
|
-
def apply(*operands)
|
35
|
+
def apply(*operands, **options)
|
36
36
|
raise NotImplementedError, "#{self.class}#apply(#{operands.map(&:class).join(', ')})"
|
37
37
|
end
|
38
38
|
|
@@ -4,6 +4,8 @@ module SPARQL; module Algebra
|
|
4
4
|
#
|
5
5
|
# @abstract
|
6
6
|
module Expression
|
7
|
+
include RDF::Util::Logger
|
8
|
+
|
7
9
|
##
|
8
10
|
# @example
|
9
11
|
# Expression.parse('(isLiteral 3.1415)')
|
@@ -410,7 +412,8 @@ module SPARQL; module Algebra
|
|
410
412
|
end
|
411
413
|
|
412
414
|
def debug(*args, &block)
|
413
|
-
|
415
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
416
|
+
log_debug(*args, **options, &block)
|
414
417
|
end
|
415
418
|
end # Expression
|
416
419
|
end; end # SPARQL::Algebra
|
@@ -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
|
-
#
|
296
|
+
#
|
297
|
+
# Returns a partial SPARQL grammar for this term.
|
289
298
|
#
|
290
299
|
# @return [String]
|
291
|
-
def
|
292
|
-
|
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
|
@@ -308,7 +314,7 @@ module RDF::Queryable
|
|
308
314
|
#
|
309
315
|
# @example
|
310
316
|
# queryable.query([nil, RDF::DOAP.developer, nil])
|
311
|
-
# queryable.query(predicate: RDF::DOAP.developer)
|
317
|
+
# queryable.query({predicate: RDF::DOAP.developer})
|
312
318
|
#
|
313
319
|
# op = SPARQL::Algebra::Expression.parse(%q((bgp (triple ?a doap:developer ?b))))
|
314
320
|
# queryable.query(op)
|
@@ -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
|
-
|
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
|
@@ -529,6 +577,17 @@ class RDF::Query::Variable
|
|
529
577
|
def optimize(**options)
|
530
578
|
self
|
531
579
|
end
|
580
|
+
|
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}"
|
590
|
+
end
|
532
591
|
end # RDF::Query::Variable
|
533
592
|
|
534
593
|
##
|
@@ -569,5 +628,13 @@ class RDF::Query::Solution
|
|
569
628
|
def to_sxp_bin
|
570
629
|
to_a.to_sxp_bin
|
571
630
|
end
|
572
|
-
|
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
|
573
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
|
-
#
|
7
|
-
#
|
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
|
@@ -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 numeric value
|
23
|
-
def apply(operand)
|
34
|
+
def apply(operand, **options)
|
24
35
|
case operand
|
25
36
|
when RDF::Literal::Numeric then operand.abs
|
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
|
-
#
|
10
|
-
#
|
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
|
-
#
|
11
|
-
#
|
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
|
-
#
|
7
|
-
#
|
8
|
-
#
|
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
|
-
#
|
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
|