sparql 3.0.2 → 3.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +189 -74
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/bin/sparql +44 -24
- data/lib/rack/sparql.rb +1 -1
- data/lib/rack/sparql/conneg.rb +3 -3
- data/lib/sinatra/sparql.rb +5 -5
- data/lib/sparql.rb +17 -16
- data/lib/sparql/algebra.rb +15 -23
- data/lib/sparql/algebra/aggregate.rb +4 -4
- data/lib/sparql/algebra/evaluatable.rb +2 -2
- data/lib/sparql/algebra/expression.rb +70 -44
- data/lib/sparql/algebra/extensions.rb +181 -34
- data/lib/sparql/algebra/operator.rb +44 -23
- data/lib/sparql/algebra/operator/abs.rb +2 -2
- data/lib/sparql/algebra/operator/add.rb +3 -3
- data/lib/sparql/algebra/operator/alt.rb +4 -4
- data/lib/sparql/algebra/operator/and.rb +7 -7
- data/lib/sparql/algebra/operator/asc.rb +3 -3
- data/lib/sparql/algebra/operator/ask.rb +4 -14
- data/lib/sparql/algebra/operator/avg.rb +13 -4
- data/lib/sparql/algebra/operator/base.rb +10 -10
- data/lib/sparql/algebra/operator/bgp.rb +2 -2
- data/lib/sparql/algebra/operator/bnode.rb +5 -5
- data/lib/sparql/algebra/operator/bound.rb +3 -3
- data/lib/sparql/algebra/operator/ceil.rb +2 -2
- data/lib/sparql/algebra/operator/clear.rb +3 -3
- data/lib/sparql/algebra/operator/coalesce.rb +3 -13
- data/lib/sparql/algebra/operator/compare.rb +8 -8
- data/lib/sparql/algebra/operator/concat.rb +4 -4
- data/lib/sparql/algebra/operator/construct.rb +4 -14
- data/lib/sparql/algebra/operator/contains.rb +2 -2
- data/lib/sparql/algebra/operator/copy.rb +3 -3
- data/lib/sparql/algebra/operator/count.rb +3 -3
- data/lib/sparql/algebra/operator/create.rb +3 -3
- data/lib/sparql/algebra/operator/dataset.rb +6 -17
- data/lib/sparql/algebra/operator/datatype.rb +1 -1
- data/lib/sparql/algebra/operator/day.rb +1 -1
- data/lib/sparql/algebra/operator/delete.rb +9 -7
- data/lib/sparql/algebra/operator/delete_data.rb +3 -3
- data/lib/sparql/algebra/operator/delete_where.rb +6 -6
- data/lib/sparql/algebra/operator/desc.rb +1 -1
- data/lib/sparql/algebra/operator/describe.rb +3 -13
- data/lib/sparql/algebra/operator/distinct.rb +4 -14
- data/lib/sparql/algebra/operator/divide.rb +1 -1
- data/lib/sparql/algebra/operator/drop.rb +3 -3
- data/lib/sparql/algebra/operator/encode_for_uri.rb +3 -3
- data/lib/sparql/algebra/operator/equal.rb +2 -2
- data/lib/sparql/algebra/operator/exists.rb +5 -5
- data/lib/sparql/algebra/operator/exprlist.rb +3 -13
- data/lib/sparql/algebra/operator/extend.rb +19 -18
- data/lib/sparql/algebra/operator/filter.rb +6 -16
- data/lib/sparql/algebra/operator/floor.rb +2 -2
- data/lib/sparql/algebra/operator/graph.rb +6 -17
- data/lib/sparql/algebra/operator/greater_than.rb +5 -5
- data/lib/sparql/algebra/operator/greater_than_or_equal.rb +5 -5
- data/lib/sparql/algebra/operator/group.rb +25 -25
- data/lib/sparql/algebra/operator/group_concat.rb +6 -6
- data/lib/sparql/algebra/operator/hours.rb +1 -1
- data/lib/sparql/algebra/operator/if.rb +5 -15
- data/lib/sparql/algebra/operator/in.rb +4 -14
- data/lib/sparql/algebra/operator/insert.rb +7 -5
- data/lib/sparql/algebra/operator/insert_data.rb +3 -3
- data/lib/sparql/algebra/operator/iri.rb +1 -1
- data/lib/sparql/algebra/operator/is_blank.rb +1 -1
- data/lib/sparql/algebra/operator/is_iri.rb +1 -1
- data/lib/sparql/algebra/operator/is_literal.rb +1 -1
- data/lib/sparql/algebra/operator/is_numeric.rb +1 -1
- data/lib/sparql/algebra/operator/join.rb +12 -10
- data/lib/sparql/algebra/operator/lang.rb +1 -1
- data/lib/sparql/algebra/operator/lang_matches.rb +3 -3
- data/lib/sparql/algebra/operator/lcase.rb +2 -2
- data/lib/sparql/algebra/operator/left_join.rb +19 -12
- data/lib/sparql/algebra/operator/less_than.rb +5 -5
- data/lib/sparql/algebra/operator/less_than_or_equal.rb +5 -5
- data/lib/sparql/algebra/operator/load.rb +3 -3
- data/lib/sparql/algebra/operator/max.rb +13 -4
- data/lib/sparql/algebra/operator/md5.rb +1 -1
- data/lib/sparql/algebra/operator/min.rb +13 -4
- data/lib/sparql/algebra/operator/minus.rb +12 -11
- data/lib/sparql/algebra/operator/minutes.rb +1 -1
- data/lib/sparql/algebra/operator/modify.rb +4 -4
- data/lib/sparql/algebra/operator/month.rb +1 -1
- data/lib/sparql/algebra/operator/move.rb +3 -3
- data/lib/sparql/algebra/operator/multiply.rb +1 -1
- data/lib/sparql/algebra/operator/negate.rb +1 -1
- data/lib/sparql/algebra/operator/not.rb +1 -1
- data/lib/sparql/algebra/operator/not_equal.rb +2 -2
- data/lib/sparql/algebra/operator/notexists.rb +4 -4
- data/lib/sparql/algebra/operator/notin.rb +4 -14
- data/lib/sparql/algebra/operator/notoneof.rb +5 -6
- data/lib/sparql/algebra/operator/now.rb +1 -1
- data/lib/sparql/algebra/operator/or.rb +7 -7
- data/lib/sparql/algebra/operator/order.rb +6 -16
- data/lib/sparql/algebra/operator/path.rb +6 -5
- data/lib/sparql/algebra/operator/path_opt.rb +16 -16
- data/lib/sparql/algebra/operator/path_plus.rb +8 -8
- data/lib/sparql/algebra/operator/path_star.rb +4 -4
- data/lib/sparql/algebra/operator/plus.rb +3 -3
- data/lib/sparql/algebra/operator/prefix.rb +10 -10
- data/lib/sparql/algebra/operator/project.rb +4 -14
- data/lib/sparql/algebra/operator/rand.rb +1 -1
- data/lib/sparql/algebra/operator/reduced.rb +4 -14
- data/lib/sparql/algebra/operator/regex.rb +6 -6
- data/lib/sparql/algebra/operator/replace.rb +4 -4
- data/lib/sparql/algebra/operator/reverse.rb +4 -4
- data/lib/sparql/algebra/operator/round.rb +2 -2
- data/lib/sparql/algebra/operator/same_term.rb +8 -5
- data/lib/sparql/algebra/operator/sample.rb +11 -4
- data/lib/sparql/algebra/operator/seconds.rb +1 -1
- data/lib/sparql/algebra/operator/seq.rb +5 -6
- data/lib/sparql/algebra/operator/sequence.rb +4 -4
- data/lib/sparql/algebra/operator/sha1.rb +1 -1
- data/lib/sparql/algebra/operator/sha256.rb +1 -1
- data/lib/sparql/algebra/operator/sha384.rb +1 -1
- data/lib/sparql/algebra/operator/sha512.rb +1 -1
- data/lib/sparql/algebra/operator/slice.rb +4 -14
- data/lib/sparql/algebra/operator/str.rb +1 -1
- data/lib/sparql/algebra/operator/strafter.rb +2 -2
- data/lib/sparql/algebra/operator/strbefore.rb +2 -2
- data/lib/sparql/algebra/operator/strdt.rb +2 -2
- data/lib/sparql/algebra/operator/strends.rb +2 -2
- data/lib/sparql/algebra/operator/strlang.rb +2 -2
- data/lib/sparql/algebra/operator/strlen.rb +2 -2
- data/lib/sparql/algebra/operator/strstarts.rb +2 -2
- data/lib/sparql/algebra/operator/struuid.rb +1 -1
- data/lib/sparql/algebra/operator/substr.rb +4 -4
- data/lib/sparql/algebra/operator/subtract.rb +1 -1
- data/lib/sparql/algebra/operator/sum.rb +6 -4
- data/lib/sparql/algebra/operator/table.rb +3 -3
- data/lib/sparql/algebra/operator/timezone.rb +1 -1
- data/lib/sparql/algebra/operator/tz.rb +1 -1
- data/lib/sparql/algebra/operator/ucase.rb +2 -2
- data/lib/sparql/algebra/operator/union.rb +9 -8
- data/lib/sparql/algebra/operator/update.rb +4 -4
- data/lib/sparql/algebra/operator/using.rb +4 -4
- data/lib/sparql/algebra/operator/uuid.rb +1 -1
- data/lib/sparql/algebra/operator/with.rb +7 -7
- data/lib/sparql/algebra/operator/year.rb +1 -1
- data/lib/sparql/algebra/query.rb +2 -2
- data/lib/sparql/algebra/update.rb +2 -2
- data/lib/sparql/algebra/version.rb +1 -1
- data/lib/sparql/extensions.rb +11 -17
- data/lib/sparql/grammar.rb +113 -13
- data/lib/sparql/grammar/meta.rb +2340 -907
- data/lib/sparql/grammar/parser11.rb +57 -52
- data/lib/sparql/grammar/terminals11.rb +2 -0
- data/lib/sparql/results.rb +73 -46
- data/lib/sparql/version.rb +1 -1
- metadata +46 -63
@@ -4,7 +4,7 @@ require 'json'
|
|
4
4
|
# Extensions for Ruby's `NilClass` class.
|
5
5
|
class NilClass
|
6
6
|
|
7
|
-
def evaluate(bindings, options
|
7
|
+
def evaluate(bindings, **options)
|
8
8
|
self
|
9
9
|
end
|
10
10
|
|
@@ -27,6 +27,22 @@ class Object
|
|
27
27
|
def to_sse
|
28
28
|
SXP::Generator.string(self.to_sxp_bin)
|
29
29
|
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# A duplicate of this object.
|
33
|
+
#
|
34
|
+
# @return [Object] a copy of `self`
|
35
|
+
# @see SPARQL::Algebra::Expression#optimize
|
36
|
+
def optimize(**options)
|
37
|
+
self.deep_dup
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Default for deep_dup is shallow dup
|
42
|
+
# @return [Object]
|
43
|
+
def deep_dup
|
44
|
+
dup
|
45
|
+
end
|
30
46
|
end
|
31
47
|
|
32
48
|
##
|
@@ -53,8 +69,8 @@ class Array
|
|
53
69
|
# options passed from query
|
54
70
|
# @return [RDF::Term]
|
55
71
|
# @see SPARQL::Algebra::Expression.evaluate
|
56
|
-
def evaluate(bindings, options
|
57
|
-
SPARQL::Algebra::Expression.extension(*self.map {|o| o.evaluate(bindings, options)})
|
72
|
+
def evaluate(bindings, **options)
|
73
|
+
SPARQL::Algebra::Expression.extension(*self.map {|o| o.evaluate(bindings, **options)})
|
58
74
|
end
|
59
75
|
|
60
76
|
##
|
@@ -66,11 +82,34 @@ class Array
|
|
66
82
|
# @param [Hash{Symbol => Object}] options
|
67
83
|
# @raise [NotImplementedError]
|
68
84
|
# If an attempt is made to perform an unsupported operation
|
69
|
-
# @see
|
70
|
-
def execute(queryable, options
|
85
|
+
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
86
|
+
def execute(queryable, **options)
|
71
87
|
raise NotImplementedError, "SPARQL::Algebra '#{first}' operator not implemented"
|
72
88
|
end
|
73
89
|
|
90
|
+
##
|
91
|
+
# Return an optimized version of this array.
|
92
|
+
#
|
93
|
+
# @return [Array] a copy of `self`
|
94
|
+
# @see SPARQL::Algebra::Expression#optimize
|
95
|
+
def optimize(**options)
|
96
|
+
self.map do |op|
|
97
|
+
op.optimize(**options) if op.respond_to?(:optimize)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# Binds the pattern to a solution, making it no longer variable if all variables are resolved to bound variables
|
103
|
+
#
|
104
|
+
# @param [RDF::Query::Solution] solution
|
105
|
+
# @return [self]
|
106
|
+
def bind(solution)
|
107
|
+
map! do |op|
|
108
|
+
op.respond_to?(:bind) ? op.bind(solution) : op
|
109
|
+
end
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
74
113
|
##
|
75
114
|
# Returns `true` if any of the operands are variables, `false`
|
76
115
|
# otherwise.
|
@@ -78,7 +117,7 @@ class Array
|
|
78
117
|
# @return [Boolean] `true` or `false`
|
79
118
|
# @see #constant?
|
80
119
|
def variable?
|
81
|
-
any?(
|
120
|
+
any? {|op| op.respond_to?(:variable?) && op.variable?}
|
82
121
|
end
|
83
122
|
def constant?; !(variable?); end
|
84
123
|
|
@@ -166,6 +205,12 @@ class Array
|
|
166
205
|
each {|e| e.validate! if e.respond_to?(:validate!)}
|
167
206
|
self
|
168
207
|
end
|
208
|
+
|
209
|
+
##
|
210
|
+
# Deep duplicate
|
211
|
+
def deep_dup
|
212
|
+
map(&:deep_dup)
|
213
|
+
end
|
169
214
|
end
|
170
215
|
|
171
216
|
##
|
@@ -179,6 +224,21 @@ class Hash
|
|
179
224
|
to_a.to_sxp_bin
|
180
225
|
end
|
181
226
|
def to_sxp; to_sxp_bin; end
|
227
|
+
|
228
|
+
##
|
229
|
+
# A duplicate of this hash.
|
230
|
+
#
|
231
|
+
# @return [Hash] a copy of `self`
|
232
|
+
# @see SPARQL::Algebra::Expression#optimize
|
233
|
+
def optimize(**options)
|
234
|
+
self.deep_dup
|
235
|
+
end
|
236
|
+
|
237
|
+
##
|
238
|
+
# Deep duplicate
|
239
|
+
def deep_dup
|
240
|
+
inject({}) {|memo, (k, v)| memo.merge(k => v.deep_dup)}
|
241
|
+
end
|
182
242
|
end
|
183
243
|
|
184
244
|
##
|
@@ -191,7 +251,7 @@ module RDF::Term
|
|
191
251
|
# @param [Hash{Symbol => Object}] options ({})
|
192
252
|
# options passed from query
|
193
253
|
# @return [RDF::Term]
|
194
|
-
def evaluate(bindings, options
|
254
|
+
def evaluate(bindings, **options)
|
195
255
|
self
|
196
256
|
end
|
197
257
|
|
@@ -210,8 +270,33 @@ module RDF::Term
|
|
210
270
|
def vars
|
211
271
|
variable? ? [self] : []
|
212
272
|
end
|
273
|
+
|
274
|
+
##
|
275
|
+
# A duplicate of this term.
|
276
|
+
#
|
277
|
+
# @return [RDF::Term] a copy of `self`
|
278
|
+
# @see SPARQL::Algebra::Expression#optimize
|
279
|
+
def optimize(**options)
|
280
|
+
optimized = self.deep_dup
|
281
|
+
optimized.lexical = nil if optimized.respond_to?(:lexical=)
|
282
|
+
optimized
|
283
|
+
end
|
213
284
|
end # RDF::Term
|
214
285
|
|
286
|
+
class RDF::Literal::Double
|
287
|
+
##
|
288
|
+
# Returns the SXP representation of this object.
|
289
|
+
#
|
290
|
+
# @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
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
215
300
|
# Override RDF::Queryable to execute against SPARQL::Algebra::Query elements as well as RDF::Query and RDF::Pattern
|
216
301
|
module RDF::Queryable
|
217
302
|
alias_method :query_without_sparql, :query
|
@@ -235,7 +320,7 @@ module RDF::Queryable
|
|
235
320
|
# @yieldreturn [void] ignored
|
236
321
|
# @return [Enumerator]
|
237
322
|
# @see RDF::Queryable#query_pattern
|
238
|
-
def query(pattern, options
|
323
|
+
def query(pattern, **options, &block)
|
239
324
|
raise TypeError, "#{self} is not queryable" if respond_to?(:queryable?) && !queryable?
|
240
325
|
|
241
326
|
if pattern.is_a?(SPARQL::Algebra::Operator) && pattern.respond_to?(:execute)
|
@@ -243,7 +328,7 @@ module RDF::Queryable
|
|
243
328
|
solutions = if method(:query_execute).arity == 1
|
244
329
|
query_execute(pattern, &block)
|
245
330
|
else
|
246
|
-
query_execute(pattern, options, &block)
|
331
|
+
query_execute(pattern, **options, &block)
|
247
332
|
end
|
248
333
|
after_query(pattern) if respond_to?(:after_query)
|
249
334
|
|
@@ -252,25 +337,45 @@ module RDF::Queryable
|
|
252
337
|
solutions
|
253
338
|
else
|
254
339
|
# Return an enumerator
|
255
|
-
enum_for(:query, pattern, options)
|
340
|
+
enum_for(:query, pattern, **options)
|
256
341
|
end
|
257
342
|
else
|
258
|
-
query_without_sparql(pattern, options, &block)
|
343
|
+
query_without_sparql(pattern, **options, &block)
|
259
344
|
end
|
260
345
|
end
|
261
|
-
|
262
346
|
end
|
263
347
|
|
264
348
|
class RDF::Statement
|
265
349
|
# Transform Statement Pattern into an SXP
|
266
350
|
# @return [Array]
|
267
351
|
def to_sxp_bin
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
352
|
+
[ (has_graph? ? :quad : :triple),
|
353
|
+
(:inferred if inferred?),
|
354
|
+
subject,
|
355
|
+
predicate,
|
356
|
+
object,
|
357
|
+
graph_name
|
358
|
+
].compact.map(&:to_sxp_bin)
|
273
359
|
end
|
360
|
+
|
361
|
+
##
|
362
|
+
# Returns an S-Expression (SXP) representation
|
363
|
+
#
|
364
|
+
# @return [String]
|
365
|
+
def to_sxp
|
366
|
+
to_sxp_bin.to_sxp
|
367
|
+
end
|
368
|
+
|
369
|
+
##
|
370
|
+
# A duplicate of this Statement.
|
371
|
+
#
|
372
|
+
# @return [RDF::Statement] a copy of `self`
|
373
|
+
# @see SPARQL::Algebra::Expression#optimize
|
374
|
+
def optimize(**options)
|
375
|
+
self.dup
|
376
|
+
end
|
377
|
+
|
378
|
+
def executable?; false; end
|
274
379
|
end
|
275
380
|
|
276
381
|
class RDF::Query
|
@@ -306,6 +411,16 @@ class RDF::Query
|
|
306
411
|
end
|
307
412
|
end
|
308
413
|
|
414
|
+
##
|
415
|
+
# Binds the pattern to a solution, making it no longer variable if all variables are resolved to bound variables
|
416
|
+
#
|
417
|
+
# @param [RDF::Query::Solution] solution
|
418
|
+
# @return [self]
|
419
|
+
def bind(solution)
|
420
|
+
patterns.each {|p| p.bind(solution)}
|
421
|
+
self
|
422
|
+
end
|
423
|
+
|
309
424
|
# Query results in a boolean result (e.g., ASK)
|
310
425
|
# @return [Boolean]
|
311
426
|
def query_yields_boolean?
|
@@ -338,25 +453,34 @@ class RDF::Query
|
|
338
453
|
variables.values
|
339
454
|
end
|
340
455
|
|
456
|
+
alias_method :optimize_without_expression!, :optimize!
|
341
457
|
##
|
342
|
-
#
|
343
|
-
# otherwise.
|
458
|
+
# Optimize the query, removing lexical shortcuts in URIs
|
344
459
|
#
|
345
|
-
# @return [
|
460
|
+
# @return [self]
|
461
|
+
# @see SPARQL::Algebra::Expression#optimize!
|
462
|
+
def optimize!(**options)
|
463
|
+
@patterns = @patterns.map do |pattern|
|
464
|
+
components = pattern.to_quad.map do |term|
|
465
|
+
if term.respond_to?(:lexical=)
|
466
|
+
term.dup.instance_eval {@lexical = nil; self}
|
467
|
+
else
|
468
|
+
term
|
469
|
+
end
|
470
|
+
end
|
471
|
+
RDF::Query::Pattern.from(components, **pattern.options)
|
472
|
+
end
|
473
|
+
self.optimize_without_expression!(**options)
|
474
|
+
end
|
475
|
+
|
476
|
+
##
|
477
|
+
# Returns `true` as this is executable.
|
478
|
+
#
|
479
|
+
# @return [Boolean] `true`
|
346
480
|
def executable?; true; end
|
347
481
|
end
|
348
482
|
|
349
483
|
class RDF::Query::Pattern
|
350
|
-
# Transform Query Pattern into an SXP
|
351
|
-
# @return [Array]
|
352
|
-
def to_sxp_bin
|
353
|
-
if has_graph?
|
354
|
-
[:quad, subject, predicate, object, graph_name]
|
355
|
-
else
|
356
|
-
[:triple, subject, predicate, object]
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
484
|
##
|
361
485
|
# Return the non-destinguished variables contained within this pattern
|
362
486
|
# @return [Array<RDF::Query::Variable>]
|
@@ -370,6 +494,12 @@ class RDF::Query::Pattern
|
|
370
494
|
def vars
|
371
495
|
variables.values
|
372
496
|
end
|
497
|
+
|
498
|
+
##
|
499
|
+
# Returns `true` as this is executable.
|
500
|
+
#
|
501
|
+
# @return [Boolean] `true`
|
502
|
+
def executable?; true; end
|
373
503
|
end
|
374
504
|
|
375
505
|
##
|
@@ -386,14 +516,18 @@ class RDF::Query::Variable
|
|
386
516
|
# options passed from query
|
387
517
|
# @return [RDF::Term] the value of this variable
|
388
518
|
# @raise [TypeError] if the variable is not bound
|
389
|
-
def evaluate(bindings, options
|
519
|
+
def evaluate(bindings, **options)
|
390
520
|
raise TypeError if bindings.respond_to?(:bound?) && !bindings.bound?(self)
|
391
521
|
bindings[name.to_sym]
|
392
522
|
end
|
393
523
|
|
394
|
-
|
395
|
-
|
396
|
-
|
524
|
+
##
|
525
|
+
# Return self
|
526
|
+
#
|
527
|
+
# @return [RDF::Query::Variable] a copy of `self`
|
528
|
+
# @see SPARQL::Algebra::Expression#optimize
|
529
|
+
def optimize(**options)
|
530
|
+
self
|
397
531
|
end
|
398
532
|
end # RDF::Query::Variable
|
399
533
|
|
@@ -424,3 +558,16 @@ class RDF::Query::Solutions
|
|
424
558
|
end
|
425
559
|
alias_method :filter!, :filter
|
426
560
|
end # RDF::Query::Solutions
|
561
|
+
|
562
|
+
##
|
563
|
+
# Extensions for `RDF::Query::Solution`.
|
564
|
+
class RDF::Query::Solution
|
565
|
+
##
|
566
|
+
# Returns the SXP representation of this object, defaults to `self`.
|
567
|
+
#
|
568
|
+
# @return [String]
|
569
|
+
def to_sxp_bin
|
570
|
+
to_a.to_sxp_bin
|
571
|
+
end
|
572
|
+
def to_sxp; to_sxp_bin; end
|
573
|
+
end # RDF::Query::Solution
|
@@ -146,8 +146,6 @@ module SPARQL; module Algebra
|
|
146
146
|
autoload :Using, 'sparql/algebra/operator/using'
|
147
147
|
autoload :With, 'sparql/algebra/operator/with'
|
148
148
|
|
149
|
-
|
150
|
-
|
151
149
|
##
|
152
150
|
# Returns an operator class for the given operator `name`.
|
153
151
|
#
|
@@ -331,15 +329,15 @@ module SPARQL; module Algebra
|
|
331
329
|
# @overload initialize(*operands)
|
332
330
|
# @param [Array<RDF::Term>] operands
|
333
331
|
#
|
334
|
-
# @overload initialize(*operands, options)
|
332
|
+
# @overload initialize(*operands, **options)
|
335
333
|
# @param [Array<RDF::Term>] operands
|
336
334
|
# @param [Hash{Symbol => Object}] options
|
337
335
|
# any additional options
|
338
336
|
# @option options [Boolean] :memoize (false)
|
339
337
|
# whether to memoize results for particular operands
|
340
338
|
# @raise [TypeError] if any operand is invalid
|
341
|
-
def initialize(*operands)
|
342
|
-
@options =
|
339
|
+
def initialize(*operands, **options)
|
340
|
+
@options = options.dup
|
343
341
|
@operands = operands.map! do |operand|
|
344
342
|
case operand
|
345
343
|
when Array
|
@@ -357,6 +355,22 @@ module SPARQL; module Algebra
|
|
357
355
|
end
|
358
356
|
end
|
359
357
|
|
358
|
+
##
|
359
|
+
# Deep duplicate operands
|
360
|
+
def deep_dup
|
361
|
+
self.class.new(*operands.map(&:deep_dup), **@options)
|
362
|
+
end
|
363
|
+
|
364
|
+
##
|
365
|
+
# Binds the pattern to a solution, making it no longer variable if all variables are resolved to bound variables
|
366
|
+
#
|
367
|
+
# @param [RDF::Query::Solution] solution
|
368
|
+
# @return [self]
|
369
|
+
def bind(solution)
|
370
|
+
@operands.each {|op| op.bind(solution)}
|
371
|
+
self
|
372
|
+
end
|
373
|
+
|
360
374
|
##
|
361
375
|
# Base URI used for reading data sources with relative URIs
|
362
376
|
#
|
@@ -434,7 +448,7 @@ module SPARQL; module Algebra
|
|
434
448
|
# @return [Boolean] `true` or `false`
|
435
449
|
# @see #constant?
|
436
450
|
def variable?
|
437
|
-
operands.any?(
|
451
|
+
operands.any? {|op| op.respond_to?(:variable?) && op.variable?}
|
438
452
|
end
|
439
453
|
|
440
454
|
##
|
@@ -491,23 +505,37 @@ module SPARQL; module Algebra
|
|
491
505
|
#
|
492
506
|
# For constant expressions containing no variables, returns the result
|
493
507
|
# of evaluating the expression with empty bindings; otherwise returns
|
494
|
-
# `self`.
|
508
|
+
# a copy of `self`.
|
495
509
|
#
|
496
510
|
# Optimization is not possible if the expression raises an exception,
|
497
511
|
# such as a `TypeError` or `ZeroDivisionError`, which must be conserved
|
498
512
|
# at runtime.
|
499
513
|
#
|
500
514
|
# @return [SPARQL::Algebra::Expression]
|
501
|
-
|
515
|
+
# @see RDF::Query#optimize
|
516
|
+
def optimize(**options)
|
502
517
|
if constant?
|
503
518
|
# Note that if evaluation results in a `TypeError` or other error,
|
504
519
|
# we must return `self` so that the error is conserved at runtime:
|
505
520
|
evaluate(RDF::Query::Solution.new) rescue self
|
506
521
|
else
|
507
|
-
super # returns `self`
|
522
|
+
super # returns a copy of `self`
|
508
523
|
end
|
509
524
|
end
|
510
525
|
|
526
|
+
##
|
527
|
+
# Optimizes this query by optimizing its constituent operands
|
528
|
+
# according to their cost estimates.
|
529
|
+
#
|
530
|
+
# @return [self]
|
531
|
+
# @see RDF::Query#optimize!
|
532
|
+
def optimize!(**options)
|
533
|
+
@operands.map! do |op|
|
534
|
+
op.optimize(**options) if op.respond_to?(:optimize)
|
535
|
+
end
|
536
|
+
self
|
537
|
+
end
|
538
|
+
|
511
539
|
##
|
512
540
|
# Rewrite operands by yielding each operand. Recursively descends
|
513
541
|
# through operands implementing this method.
|
@@ -532,7 +560,7 @@ module SPARQL; module Algebra
|
|
532
560
|
# Returns the SPARQL S-Expression (SSE) representation of this operator.
|
533
561
|
#
|
534
562
|
# @return [Array]
|
535
|
-
# @see
|
563
|
+
# @see https://openjena.org/wiki/SSE
|
536
564
|
def to_sxp_bin
|
537
565
|
operator = [self.class.const_get(:NAME)].flatten.first
|
538
566
|
[operator, *(operands || []).map(&:to_sxp_bin)]
|
@@ -543,13 +571,6 @@ module SPARQL; module Algebra
|
|
543
571
|
#
|
544
572
|
# @return [String]
|
545
573
|
def to_sxp
|
546
|
-
begin
|
547
|
-
require 'sxp' # @see http://rubygems.org/gems/sxp
|
548
|
-
rescue LoadError
|
549
|
-
abort "SPARQL::Algebra::Operator#to_sxp requires the SXP gem (hint: `gem install sxp')."
|
550
|
-
end
|
551
|
-
require 'sparql/algebra/sxp_extensions'
|
552
|
-
|
553
574
|
to_sxp_bin.to_sxp
|
554
575
|
end
|
555
576
|
|
@@ -647,7 +668,7 @@ module SPARQL; module Algebra
|
|
647
668
|
# @param [RDF::Literal] literal
|
648
669
|
# @return [RDF::Literal::Boolean] `true` or `false`
|
649
670
|
# @raise [TypeError] if the literal could not be coerced to an `RDF::Literal::Boolean`
|
650
|
-
# @see
|
671
|
+
# @see https://www.w3.org/TR/sparql11-query/#ebv
|
651
672
|
def boolean(literal)
|
652
673
|
case literal
|
653
674
|
when FalseClass then RDF::Literal::FALSE
|
@@ -724,7 +745,7 @@ module SPARQL; module Algebra
|
|
724
745
|
##
|
725
746
|
# @param [Hash{Symbol => Object}] options
|
726
747
|
# any additional options (see {Operator#initialize})
|
727
|
-
def initialize(options
|
748
|
+
def initialize(**options)
|
728
749
|
super
|
729
750
|
end
|
730
751
|
end # Nullary
|
@@ -743,7 +764,7 @@ module SPARQL; module Algebra
|
|
743
764
|
# the operand
|
744
765
|
# @param [Hash{Symbol => Object}] options
|
745
766
|
# any additional options (see {Operator#initialize})
|
746
|
-
def initialize(arg, options
|
767
|
+
def initialize(arg, **options)
|
747
768
|
super
|
748
769
|
end
|
749
770
|
end # Unary
|
@@ -764,7 +785,7 @@ module SPARQL; module Algebra
|
|
764
785
|
# the second operand
|
765
786
|
# @param [Hash{Symbol => Object}] options
|
766
787
|
# any additional options (see {Operator#initialize})
|
767
|
-
def initialize(arg1, arg2, options
|
788
|
+
def initialize(arg1, arg2, **options)
|
768
789
|
super
|
769
790
|
end
|
770
791
|
end # Binary
|
@@ -787,7 +808,7 @@ module SPARQL; module Algebra
|
|
787
808
|
# the third operand
|
788
809
|
# @param [Hash{Symbol => Object}] options
|
789
810
|
# any additional options (see {Operator#initialize})
|
790
|
-
def initialize(arg1, arg2, arg3, options
|
811
|
+
def initialize(arg1, arg2, arg3, **options)
|
791
812
|
super
|
792
813
|
end
|
793
814
|
end # Ternary
|
@@ -812,7 +833,7 @@ module SPARQL; module Algebra
|
|
812
833
|
# the forth operand
|
813
834
|
# @param [Hash{Symbol => Object}] options
|
814
835
|
# any additional options (see {Operator#initialize})
|
815
|
-
def initialize(arg1, arg2, arg3, arg4, options
|
836
|
+
def initialize(arg1, arg2, arg3, arg4, **options)
|
816
837
|
super
|
817
838
|
end
|
818
839
|
end # Ternary
|