sparql 3.0.2 → 3.1.5

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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +189 -74
  3. data/UNLICENSE +1 -1
  4. data/VERSION +1 -1
  5. data/bin/sparql +44 -24
  6. data/lib/rack/sparql.rb +1 -1
  7. data/lib/rack/sparql/conneg.rb +3 -3
  8. data/lib/sinatra/sparql.rb +5 -5
  9. data/lib/sparql.rb +17 -16
  10. data/lib/sparql/algebra.rb +15 -23
  11. data/lib/sparql/algebra/aggregate.rb +4 -4
  12. data/lib/sparql/algebra/evaluatable.rb +2 -2
  13. data/lib/sparql/algebra/expression.rb +70 -44
  14. data/lib/sparql/algebra/extensions.rb +181 -34
  15. data/lib/sparql/algebra/operator.rb +44 -23
  16. data/lib/sparql/algebra/operator/abs.rb +2 -2
  17. data/lib/sparql/algebra/operator/add.rb +3 -3
  18. data/lib/sparql/algebra/operator/alt.rb +4 -4
  19. data/lib/sparql/algebra/operator/and.rb +7 -7
  20. data/lib/sparql/algebra/operator/asc.rb +3 -3
  21. data/lib/sparql/algebra/operator/ask.rb +4 -14
  22. data/lib/sparql/algebra/operator/avg.rb +13 -4
  23. data/lib/sparql/algebra/operator/base.rb +10 -10
  24. data/lib/sparql/algebra/operator/bgp.rb +2 -2
  25. data/lib/sparql/algebra/operator/bnode.rb +5 -5
  26. data/lib/sparql/algebra/operator/bound.rb +3 -3
  27. data/lib/sparql/algebra/operator/ceil.rb +2 -2
  28. data/lib/sparql/algebra/operator/clear.rb +3 -3
  29. data/lib/sparql/algebra/operator/coalesce.rb +3 -13
  30. data/lib/sparql/algebra/operator/compare.rb +8 -8
  31. data/lib/sparql/algebra/operator/concat.rb +4 -4
  32. data/lib/sparql/algebra/operator/construct.rb +4 -14
  33. data/lib/sparql/algebra/operator/contains.rb +2 -2
  34. data/lib/sparql/algebra/operator/copy.rb +3 -3
  35. data/lib/sparql/algebra/operator/count.rb +3 -3
  36. data/lib/sparql/algebra/operator/create.rb +3 -3
  37. data/lib/sparql/algebra/operator/dataset.rb +6 -17
  38. data/lib/sparql/algebra/operator/datatype.rb +1 -1
  39. data/lib/sparql/algebra/operator/day.rb +1 -1
  40. data/lib/sparql/algebra/operator/delete.rb +9 -7
  41. data/lib/sparql/algebra/operator/delete_data.rb +3 -3
  42. data/lib/sparql/algebra/operator/delete_where.rb +6 -6
  43. data/lib/sparql/algebra/operator/desc.rb +1 -1
  44. data/lib/sparql/algebra/operator/describe.rb +3 -13
  45. data/lib/sparql/algebra/operator/distinct.rb +4 -14
  46. data/lib/sparql/algebra/operator/divide.rb +1 -1
  47. data/lib/sparql/algebra/operator/drop.rb +3 -3
  48. data/lib/sparql/algebra/operator/encode_for_uri.rb +3 -3
  49. data/lib/sparql/algebra/operator/equal.rb +2 -2
  50. data/lib/sparql/algebra/operator/exists.rb +5 -5
  51. data/lib/sparql/algebra/operator/exprlist.rb +3 -13
  52. data/lib/sparql/algebra/operator/extend.rb +19 -18
  53. data/lib/sparql/algebra/operator/filter.rb +6 -16
  54. data/lib/sparql/algebra/operator/floor.rb +2 -2
  55. data/lib/sparql/algebra/operator/graph.rb +6 -17
  56. data/lib/sparql/algebra/operator/greater_than.rb +5 -5
  57. data/lib/sparql/algebra/operator/greater_than_or_equal.rb +5 -5
  58. data/lib/sparql/algebra/operator/group.rb +25 -25
  59. data/lib/sparql/algebra/operator/group_concat.rb +6 -6
  60. data/lib/sparql/algebra/operator/hours.rb +1 -1
  61. data/lib/sparql/algebra/operator/if.rb +5 -15
  62. data/lib/sparql/algebra/operator/in.rb +4 -14
  63. data/lib/sparql/algebra/operator/insert.rb +7 -5
  64. data/lib/sparql/algebra/operator/insert_data.rb +3 -3
  65. data/lib/sparql/algebra/operator/iri.rb +1 -1
  66. data/lib/sparql/algebra/operator/is_blank.rb +1 -1
  67. data/lib/sparql/algebra/operator/is_iri.rb +1 -1
  68. data/lib/sparql/algebra/operator/is_literal.rb +1 -1
  69. data/lib/sparql/algebra/operator/is_numeric.rb +1 -1
  70. data/lib/sparql/algebra/operator/join.rb +12 -10
  71. data/lib/sparql/algebra/operator/lang.rb +1 -1
  72. data/lib/sparql/algebra/operator/lang_matches.rb +3 -3
  73. data/lib/sparql/algebra/operator/lcase.rb +2 -2
  74. data/lib/sparql/algebra/operator/left_join.rb +19 -12
  75. data/lib/sparql/algebra/operator/less_than.rb +5 -5
  76. data/lib/sparql/algebra/operator/less_than_or_equal.rb +5 -5
  77. data/lib/sparql/algebra/operator/load.rb +3 -3
  78. data/lib/sparql/algebra/operator/max.rb +13 -4
  79. data/lib/sparql/algebra/operator/md5.rb +1 -1
  80. data/lib/sparql/algebra/operator/min.rb +13 -4
  81. data/lib/sparql/algebra/operator/minus.rb +12 -11
  82. data/lib/sparql/algebra/operator/minutes.rb +1 -1
  83. data/lib/sparql/algebra/operator/modify.rb +4 -4
  84. data/lib/sparql/algebra/operator/month.rb +1 -1
  85. data/lib/sparql/algebra/operator/move.rb +3 -3
  86. data/lib/sparql/algebra/operator/multiply.rb +1 -1
  87. data/lib/sparql/algebra/operator/negate.rb +1 -1
  88. data/lib/sparql/algebra/operator/not.rb +1 -1
  89. data/lib/sparql/algebra/operator/not_equal.rb +2 -2
  90. data/lib/sparql/algebra/operator/notexists.rb +4 -4
  91. data/lib/sparql/algebra/operator/notin.rb +4 -14
  92. data/lib/sparql/algebra/operator/notoneof.rb +5 -6
  93. data/lib/sparql/algebra/operator/now.rb +1 -1
  94. data/lib/sparql/algebra/operator/or.rb +7 -7
  95. data/lib/sparql/algebra/operator/order.rb +6 -16
  96. data/lib/sparql/algebra/operator/path.rb +6 -5
  97. data/lib/sparql/algebra/operator/path_opt.rb +16 -16
  98. data/lib/sparql/algebra/operator/path_plus.rb +8 -8
  99. data/lib/sparql/algebra/operator/path_star.rb +4 -4
  100. data/lib/sparql/algebra/operator/plus.rb +3 -3
  101. data/lib/sparql/algebra/operator/prefix.rb +10 -10
  102. data/lib/sparql/algebra/operator/project.rb +4 -14
  103. data/lib/sparql/algebra/operator/rand.rb +1 -1
  104. data/lib/sparql/algebra/operator/reduced.rb +4 -14
  105. data/lib/sparql/algebra/operator/regex.rb +6 -6
  106. data/lib/sparql/algebra/operator/replace.rb +4 -4
  107. data/lib/sparql/algebra/operator/reverse.rb +4 -4
  108. data/lib/sparql/algebra/operator/round.rb +2 -2
  109. data/lib/sparql/algebra/operator/same_term.rb +8 -5
  110. data/lib/sparql/algebra/operator/sample.rb +11 -4
  111. data/lib/sparql/algebra/operator/seconds.rb +1 -1
  112. data/lib/sparql/algebra/operator/seq.rb +5 -6
  113. data/lib/sparql/algebra/operator/sequence.rb +4 -4
  114. data/lib/sparql/algebra/operator/sha1.rb +1 -1
  115. data/lib/sparql/algebra/operator/sha256.rb +1 -1
  116. data/lib/sparql/algebra/operator/sha384.rb +1 -1
  117. data/lib/sparql/algebra/operator/sha512.rb +1 -1
  118. data/lib/sparql/algebra/operator/slice.rb +4 -14
  119. data/lib/sparql/algebra/operator/str.rb +1 -1
  120. data/lib/sparql/algebra/operator/strafter.rb +2 -2
  121. data/lib/sparql/algebra/operator/strbefore.rb +2 -2
  122. data/lib/sparql/algebra/operator/strdt.rb +2 -2
  123. data/lib/sparql/algebra/operator/strends.rb +2 -2
  124. data/lib/sparql/algebra/operator/strlang.rb +2 -2
  125. data/lib/sparql/algebra/operator/strlen.rb +2 -2
  126. data/lib/sparql/algebra/operator/strstarts.rb +2 -2
  127. data/lib/sparql/algebra/operator/struuid.rb +1 -1
  128. data/lib/sparql/algebra/operator/substr.rb +4 -4
  129. data/lib/sparql/algebra/operator/subtract.rb +1 -1
  130. data/lib/sparql/algebra/operator/sum.rb +6 -4
  131. data/lib/sparql/algebra/operator/table.rb +3 -3
  132. data/lib/sparql/algebra/operator/timezone.rb +1 -1
  133. data/lib/sparql/algebra/operator/tz.rb +1 -1
  134. data/lib/sparql/algebra/operator/ucase.rb +2 -2
  135. data/lib/sparql/algebra/operator/union.rb +9 -8
  136. data/lib/sparql/algebra/operator/update.rb +4 -4
  137. data/lib/sparql/algebra/operator/using.rb +4 -4
  138. data/lib/sparql/algebra/operator/uuid.rb +1 -1
  139. data/lib/sparql/algebra/operator/with.rb +7 -7
  140. data/lib/sparql/algebra/operator/year.rb +1 -1
  141. data/lib/sparql/algebra/query.rb +2 -2
  142. data/lib/sparql/algebra/update.rb +2 -2
  143. data/lib/sparql/algebra/version.rb +1 -1
  144. data/lib/sparql/extensions.rb +11 -17
  145. data/lib/sparql/grammar.rb +113 -13
  146. data/lib/sparql/grammar/meta.rb +2340 -907
  147. data/lib/sparql/grammar/parser11.rb +57 -52
  148. data/lib/sparql/grammar/terminals11.rb +2 -0
  149. data/lib/sparql/results.rb +73 -46
  150. data/lib/sparql/version.rb +1 -1
  151. metadata +46 -63
@@ -10,7 +10,7 @@ module SPARQL; module Algebra
10
10
  # (filter (isLiteral ?v)
11
11
  # (bgp (triple ?x :p ?v)))))
12
12
  #
13
- # @see http://www.w3.org/TR/sparql11-query/#func-isLiteral
13
+ # @see https://www.w3.org/TR/sparql11-query/#func-isLiteral
14
14
  class IsLiteral < Operator::Unary
15
15
  include Evaluatable
16
16
 
@@ -12,7 +12,7 @@ module SPARQL; module Algebra
12
12
  # (filter (isNumeric ?v)
13
13
  # (bgp (triple ?x :p ?v)))))
14
14
  #
15
- # @see http://www.w3.org/TR/sparql11-query/#func-isNumeric
15
+ # @see https://www.w3.org/TR/sparql11-query/#func-isNumeric
16
16
  class IsNumeric < Operator::Unary
17
17
  include Evaluatable
18
18
 
@@ -10,7 +10,7 @@ module SPARQL; module Algebra
10
10
  # (graph ?g
11
11
  # (bgp (triple ?s ?q ?v)))))
12
12
  #
13
- # @see http://www.w3.org/TR/sparql11-query/#sparqlAlgebra
13
+ # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
14
14
  class Join < Operator::Binary
15
15
  include Query
16
16
 
@@ -31,20 +31,20 @@ module SPARQL; module Algebra
31
31
  # @yieldreturn [void] ignored
32
32
  # @return [RDF::Query::Solutions]
33
33
  # the resulting solution sequence
34
- # @see http://www.w3.org/TR/sparql11-query/#sparqlAlgebra
35
- # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#merge-instance_method
36
- # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#compatible%3F-instance_method
37
- def execute(queryable, options = {}, &block)
34
+ # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
35
+ # @see https://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#merge-instance_method
36
+ # @see https://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#compatible%3F-instance_method
37
+ def execute(queryable, **options, &block)
38
38
  # Join(Ω1, Ω2) = { merge(μ1, μ2) | μ1 in Ω1 and μ2 in Ω2, and μ1 and μ2 are compatible }
39
39
  # eval(D(G), Join(P1, P2)) = Join(eval(D(G), P1), eval(D(G), P2))
40
40
  #
41
41
  # Generate solutions independently, merge based on solution compatibility
42
42
  debug(options) {"Join #{operands.to_sse}"}
43
43
 
44
- left = queryable.query(operand(0), options.merge(depth: options[:depth].to_i + 1))
44
+ left = queryable.query(operand(0), depth: options[:depth].to_i + 1, **options)
45
45
  debug(options) {"(join)=>(left) #{left.map(&:to_h).to_sse}"}
46
46
 
47
- right = queryable.query(operand(1), options.merge(depth: options[:depth].to_i + 1))
47
+ right = queryable.query(operand(1), depth: options[:depth].to_i + 1, **options)
48
48
  debug(options) {"(join)=>(right) #{right.map(&:to_h).to_sse}"}
49
49
 
50
50
  @solutions = RDF::Query::Solutions(left.map do |s1|
@@ -67,7 +67,7 @@ module SPARQL; module Algebra
67
67
  end
68
68
 
69
69
  ##
70
- # Returns an optimized version of this query.
70
+ # Optimizes this query.
71
71
  #
72
72
  # Groups of one graph pattern (not a filter) become join(Z, A) and can be replaced by A.
73
73
  # The empty graph pattern Z is the identity for join:
@@ -75,8 +75,10 @@ module SPARQL; module Algebra
75
75
  # Replace join(A, Z) by A
76
76
  #
77
77
  # @return [Join, RDF::Query] `self`
78
- def optimize
79
- ops = operands.map {|o| o.optimize }.select {|o| o.respond_to?(:empty?) && !o.empty?}
78
+ # @return [self]
79
+ # @see SPARQL::Algebra::Expression#optimize!
80
+ def optimize!(**options)
81
+ ops = operands.map {|o| o.optimize(**options) }.select {|o| o.respond_to?(:empty?) && !o.empty?}
80
82
  @operands = ops
81
83
  self
82
84
  end
@@ -3,7 +3,7 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `lang` operator.
5
5
  #
6
- # @see http://www.w3.org/TR/sparql11-query/#func-lang
6
+ # @see https://www.w3.org/TR/sparql11-query/#func-lang
7
7
  class Lang < Operator::Unary
8
8
  include Evaluatable
9
9
 
@@ -8,8 +8,8 @@ module SPARQL; module Algebra
8
8
  # (filter (langMatches (lang ?v) "en-GB")
9
9
  # (bgp (triple :x ?p ?v))))
10
10
  #
11
- # @see http://www.w3.org/TR/sparql11-query/#func-langMatches
12
- # @see http://tools.ietf.org/html/rfc4647#section-3.3.1
11
+ # @see https://www.w3.org/TR/sparql11-query/#func-langMatches
12
+ # @see https://tools.ietf.org/html/rfc4647#section-3.3.1
13
13
  class LangMatches < Operator::Binary
14
14
  include Evaluatable
15
15
 
@@ -23,7 +23,7 @@ module SPARQL; module Algebra
23
23
  # a simple literal containing a language tag
24
24
  # @param [RDF::Literal] language_range
25
25
  # a simple literal containing a language range, per
26
- # [RFC 4647 section 2.1](http://tools.ietf.org/html/rfc4647#section-2.1)
26
+ # [RFC 4647 section 2.1](https://tools.ietf.org/html/rfc4647#section-2.1)
27
27
  # @return [RDF::Literal::Boolean] `true` or `false`
28
28
  # @raise [TypeError] if either operand is unbound
29
29
  # @raise [TypeError] if either operand is not a simple literal
@@ -6,8 +6,8 @@ module SPARQL; module Algebra
6
6
  # @example
7
7
  # (lcase ?x)
8
8
  #
9
- # @see http://www.w3.org/TR/sparql11-query/#func-lcase
10
- # @see http://www.w3.org/TR/xpath-functions/#func-lcase
9
+ # @see https://www.w3.org/TR/sparql11-query/#func-lcase
10
+ # @see https://www.w3.org/TR/xpath-functions/#func-lcase
11
11
  class LCase < Operator::Unary
12
12
  include Evaluatable
13
13
 
@@ -10,7 +10,7 @@ module SPARQL; module Algebra
10
10
  # (bgp (triple ?y :q ?w))
11
11
  # (= ?v 2)))
12
12
  #
13
- # @see http://www.w3.org/TR/sparql11-query/#sparqlAlgebra
13
+ # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
14
14
  class LeftJoin < Operator
15
15
  include Query
16
16
 
@@ -31,17 +31,21 @@ module SPARQL; module Algebra
31
31
  # @yieldreturn [void] ignored
32
32
  # @return [RDF::Query::Solutions]
33
33
  # the resulting solution sequence
34
- # @see http://www.w3.org/TR/sparql11-query/#sparqlAlgebra
35
- # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#merge-instance_method
36
- # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#compatible%3F-instance_method
37
- def execute(queryable, options = {}, &block)
34
+ # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
35
+ # @see https://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#merge-instance_method
36
+ # @see https://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Query/Solution#compatible%3F-instance_method
37
+ def execute(queryable, **options, &block)
38
38
  filter = operand(2)
39
39
 
40
+ raise ArgumentError,
41
+ "leftjoin operator accepts at most two arguments with an optional filter" if
42
+ operands.length < 2 || operands.length > 3
43
+
40
44
  debug(options) {"LeftJoin"}
41
- left = queryable.query(operand(0), options.merge(depth: options[:depth].to_i + 1))
45
+ left = queryable.query(operand(0), depth: options[:depth].to_i + 1, **options)
42
46
  debug(options) {"=>(leftjoin left) #{left.inspect}"}
43
47
 
44
- right = queryable.query(operand(1), options.merge(depth: options[:depth].to_i + 1))
48
+ right = queryable.query(operand(1), depth: options[:depth].to_i + 1, **options)
45
49
  debug(options) {"=>(leftjoin right) #{right.inspect}"}
46
50
 
47
51
  # LeftJoin(Ω1, Ω2, expr) =
@@ -83,14 +87,17 @@ module SPARQL; module Algebra
83
87
  end
84
88
 
85
89
  ##
86
- # Returns an optimized version of this query.
90
+ # Optimizes this query.
87
91
  #
88
92
  # If optimize operands, and if the first two operands are both Queries, replace
89
93
  # with the unique sum of the query elements
90
94
  #
91
- # @return [Union, RDF::Query] `self`
92
- def optimize
93
- ops = operands.map {|o| o.optimize }.select {|o| o.respond_to?(:empty?) && !o.empty?}
95
+ # @return [Object] a copy of `self`
96
+ # @see SPARQL::Algebra::Expression#optimize
97
+ # FIXME
98
+ def optimize!(**options)
99
+ return self
100
+ ops = operands.map {|o| o.optimize(**options) }.select {|o| o.respond_to?(:empty?) && !o.empty?}
94
101
  expr = ops.pop unless ops.last.executable?
95
102
  expr = nil if expr.respond_to?(:true?) && expr.true?
96
103
 
@@ -102,7 +109,7 @@ module SPARQL; module Algebra
102
109
  when 1
103
110
  expr ? Filter.new(expr, ops.first) : ops.first
104
111
  else
105
- expr ? LeftJoin(ops[0], ops[1], expr) : LeftJoin(ops[0], ops[1])
112
+ expr ? LeftJoin.new(ops[0], ops[1], expr) : LeftJoin.new(ops[0], ops[1])
106
113
  end
107
114
  end
108
115
  end # LeftJoin
@@ -6,11 +6,11 @@ module SPARQL; module Algebra
6
6
  # @example
7
7
  # (< ?x ?y)
8
8
  #
9
- # @see http://www.w3.org/TR/sparql11-query/#OperatorMapping
10
- # @see http://www.w3.org/TR/xpath-functions/#func-compare
11
- # @see http://www.w3.org/TR/xpath-functions/#func-numeric-less-than
12
- # @see http://www.w3.org/TR/xpath-functions/#func-boolean-less-than
13
- # @see http://www.w3.org/TR/xpath-functions/#func-dateTime-less-than
9
+ # @see https://www.w3.org/TR/sparql11-query/#OperatorMapping
10
+ # @see https://www.w3.org/TR/xpath-functions/#func-compare
11
+ # @see https://www.w3.org/TR/xpath-functions/#func-numeric-less-than
12
+ # @see https://www.w3.org/TR/xpath-functions/#func-boolean-less-than
13
+ # @see https://www.w3.org/TR/xpath-functions/#func-dateTime-less-than
14
14
  class LessThan < Compare
15
15
  NAME = :<
16
16
 
@@ -6,11 +6,11 @@ module SPARQL; module Algebra
6
6
  # @example
7
7
  # (<= ?x ?y)
8
8
  #
9
- # @see http://www.w3.org/TR/sparql11-query/#OperatorMapping
10
- # @see http://www.w3.org/TR/xpath-functions/#func-compare
11
- # @see http://www.w3.org/TR/xpath-functions/#func-numeric-less-than
12
- # @see http://www.w3.org/TR/xpath-functions/#func-boolean-less-than
13
- # @see http://www.w3.org/TR/xpath-functions/#func-dateTime-less-than
9
+ # @see https://www.w3.org/TR/sparql11-query/#OperatorMapping
10
+ # @see https://www.w3.org/TR/xpath-functions/#func-compare
11
+ # @see https://www.w3.org/TR/xpath-functions/#func-numeric-less-than
12
+ # @see https://www.w3.org/TR/xpath-functions/#func-boolean-less-than
13
+ # @see https://www.w3.org/TR/xpath-functions/#func-dateTime-less-than
14
14
  class LessThanOrEqual < Compare
15
15
  NAME = :<=
16
16
 
@@ -9,7 +9,7 @@ module SPARQL; module Algebra
9
9
  # @example
10
10
  # (load <remote> <g>)
11
11
  #
12
- # @see http://www.w3.org/TR/sparql11-update/#load
12
+ # @see https://www.w3.org/TR/sparql11-update/#load
13
13
  class Load < Operator
14
14
  include SPARQL::Algebra::Update
15
15
 
@@ -28,8 +28,8 @@ module SPARQL; module Algebra
28
28
  # Returns queryable.
29
29
  # @raise [IOError]
30
30
  # If `from` does not exist, unless the `silent` operator is present
31
- # @see http://www.w3.org/TR/sparql11-update/
32
- def execute(queryable, options = {})
31
+ # @see https://www.w3.org/TR/sparql11-update/
32
+ def execute(queryable, **options)
33
33
  debug(options) {"Load"}
34
34
  silent = operands.first == :silent
35
35
  operands.shift if silent
@@ -6,16 +6,23 @@ module SPARQL; module Algebra
6
6
  # @example
7
7
  # (prefix ((: <http://www.example.org/>))
8
8
  # (project (?max)
9
- # (extend ((?max ?.0))
10
- # (group () ((?.0 (max ?o)))
9
+ # (extend ((?max ??.0))
10
+ # (group () ((??.0 (max ?o)))
11
11
  # (bgp (triple ?s ?p ?o))))))
12
12
  #
13
- # @see http://www.w3.org/TR/sparql11-query/#defn_aggMax
14
- class Max < Operator::Unary
13
+ # @see https://www.w3.org/TR/sparql11-query/#defn_aggMax
14
+ class Max < Operator
15
15
  include Aggregate
16
16
 
17
17
  NAME = :max
18
18
 
19
+ def initialize(*operands, **options)
20
+ raise ArgumentError,
21
+ "max operator accepts at most one argument with an optional :distinct" if
22
+ (operands - %i{distinct}).length != 1
23
+ super
24
+ end
25
+
19
26
  ##
20
27
  # Max is a SPARQL set function that return the maximum value from a group respectively.
21
28
  #
@@ -25,6 +32,8 @@ module SPARQL; module Algebra
25
32
  # enum of evaluated operand
26
33
  # @return [RDF::Literal] The maximum value of the terms
27
34
  def apply(enum)
35
+ # FIXME: we don't actually do anything with distinct
36
+ operands.shift if distinct = (operands.first == :distinct)
28
37
  if enum.empty?
29
38
  raise TypeError, "Maximum of an empty multiset"
30
39
  elsif enum.flatten.all? {|n| n.literal?}
@@ -13,7 +13,7 @@ module SPARQL; module Algebra
13
13
  # (extend ((?hash (md5 ?l)))
14
14
  # (bgp (triple :s1 :str ?l)))))
15
15
  #
16
- # @see http://www.w3.org/TR/sparql11-query/#func-md5
16
+ # @see https://www.w3.org/TR/sparql11-query/#func-md5
17
17
  class MD5 < Operator::Unary
18
18
  include Evaluatable
19
19
 
@@ -6,16 +6,23 @@ module SPARQL; module Algebra
6
6
  # @example
7
7
  # (prefix ((: <http://www.example.org/>))
8
8
  # (project (?max)
9
- # (extend ((?min ?.0))
10
- # (group () ((?.0 (min ?o)))
9
+ # (extend ((?min ??.0))
10
+ # (group () ((??.0 (min ?o)))
11
11
  # (bgp (triple ?s ?p ?o))))))
12
12
  #
13
- # @see http://www.w3.org/TR/sparql11-query/#defn_aggMin
14
- class Min < Operator::Unary
13
+ # @see https://www.w3.org/TR/sparql11-query/#defn_aggMin
14
+ class Min < Operator
15
15
  include Aggregate
16
16
 
17
17
  NAME = :min
18
18
 
19
+ def initialize(*operands, **options)
20
+ raise ArgumentError,
21
+ "min operator accepts at most one argument with an optional :distinct" if
22
+ (operands - %i{distinct}).length != 1
23
+ super
24
+ end
25
+
19
26
  ##
20
27
  # Min is a SPARQL set function that return the minimum value from a group respectively.
21
28
  #
@@ -25,6 +32,8 @@ module SPARQL; module Algebra
25
32
  # enum of evaluated operand
26
33
  # @return [RDF::Literal] The maximum value of the terms
27
34
  def apply(enum)
35
+ # FIXME: we don't actually do anything with distinct
36
+ operands.shift if distinct = (operands.first == :distinct)
28
37
  if enum.empty?
29
38
  raise TypeError, "Minumuim of an empty multiset"
30
39
  elsif enum.flatten.all? {|n| n.literal?}
@@ -11,8 +11,8 @@ module SPARQL; module Algebra
11
11
  # (filter (|| (= ?type ex:Reptile) (= ?type ex:Insect))
12
12
  # (bgp (triple ?animal <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type))))))
13
13
  #
14
- # @see http://www.w3.org/TR/xpath-functions/#func-numeric-unary-minus
15
- # @see http://www.w3.org/TR/sparql11-query/#sparqlAlgebra
14
+ # @see https://www.w3.org/TR/xpath-functions/#func-numeric-unary-minus
15
+ # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
16
16
  class Minus < Operator::Binary
17
17
  include Query
18
18
 
@@ -33,18 +33,18 @@ module SPARQL; module Algebra
33
33
  # @yieldreturn [void] ignored
34
34
  # @return [RDF::Query::Solutions]
35
35
  # the resulting solution sequence
36
- # @see http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#defn_algMinus
37
- # @see http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#negation
38
- def execute(queryable, options = {}, &block)
36
+ # @see https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#defn_algMinus
37
+ # @see https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#negation
38
+ def execute(queryable, **options, &block)
39
39
  # Let Ω1 and Ω2 be multisets of solution mappings. We define:
40
40
  #
41
41
  # Minus(Ω1, Ω2) = { μ | μ in Ω1 . ∀ μ' in Ω2, either μ and μ' are not compatible or dom(μ) and dom(μ') are disjoint }
42
42
  #
43
43
  # card[Minus(Ω1, Ω2)](μ) = card[Ω1](μ)
44
44
  debug(options) {"Minus"}
45
- left = queryable.query(operand(0), options.merge(depth: options[:depth].to_i + 1))
45
+ left = queryable.query(operand(0), depth: options[:depth].to_i + 1, **options)
46
46
  debug(options) {"(minus left) #{left.inspect}"}
47
- right = queryable.query(operand(1), options.merge(depth: options[:depth].to_i + 1))
47
+ right = queryable.query(operand(1), depth: options[:depth].to_i + 1, **options)
48
48
  debug(options) {"(minus right) #{right.inspect}"}
49
49
  @solutions = left.minus(right)
50
50
  @solutions.each(&block) if block_given?
@@ -52,16 +52,17 @@ module SPARQL; module Algebra
52
52
  end
53
53
 
54
54
  ##
55
- # Returns an optimized version of this query.
55
+ # Optimizes this query.
56
56
  #
57
57
  # Groups of one graph pattern (not a filter) become join(Z, A) and can be replaced by A.
58
58
  # The empty graph pattern Z is the identity for join:
59
59
  # Replace join(Z, A) by A
60
60
  # Replace join(A, Z) by A
61
61
  #
62
- # @return [Join, RDF::Query] `self`
63
- def optimize
64
- ops = operands.map {|o| o.optimize }.select {|o| o.respond_to?(:empty?) && !o.empty?}
62
+ # @return [self]
63
+ # @see SPARQL::Algebra::Expression#optimize!
64
+ def optimize!(**options)
65
+ ops = operands.map {|o| o.optimize(**options) }.select {|o| o.respond_to?(:empty?) && !o.empty?}
65
66
  @operands = ops
66
67
  self
67
68
  end
@@ -11,7 +11,7 @@ module SPARQL; module Algebra
11
11
  # (extend ((?x (minutes ?date)))
12
12
  # (bgp (triple ?s :date ?date)))))
13
13
  #
14
- # @see http://www.w3.org/TR/sparql11-query/#func-minutes
14
+ # @see https://www.w3.org/TR/sparql11-query/#func-minutes
15
15
  class Minutes < Operator::Unary
16
16
  include Evaluatable
17
17
 
@@ -33,17 +33,17 @@ module SPARQL; module Algebra
33
33
  # Returns queryable.
34
34
  # @raise [IOError]
35
35
  # If `from` does not exist, unless the `silent` operator is present
36
- # @see http://www.w3.org/TR/sparql11-update/
37
- def execute(queryable, options = {})
36
+ # @see https://www.w3.org/TR/sparql11-update/
37
+ def execute(queryable, **options)
38
38
  debug(options) {"Modify"}
39
39
  query = operands.shift
40
40
 
41
- queryable.query(query, options.merge(depth: options[:depth].to_i + 1)) do |solution|
41
+ queryable.query(query, depth: options[:depth].to_i + 1, **options) do |solution|
42
42
  debug(options) {"(solution)=>#{solution.inspect}"}
43
43
 
44
44
  # Execute each operand with queryable and solution
45
45
  operands.each do |op|
46
- op.execute(queryable, solution, options.merge(depth: options[:depth].to_i + 1))
46
+ op.execute(queryable, solutions: solution, depth: options[:depth].to_i + 1, **options)
47
47
  end
48
48
  end
49
49
  queryable
@@ -11,7 +11,7 @@ module SPARQL; module Algebra
11
11
  # (extend ((?x (month ?date)))
12
12
  # (bgp (triple ?s :date ?date)))))
13
13
  #
14
- # @see http://www.w3.org/TR/sparql11-query/#func-month
14
+ # @see https://www.w3.org/TR/sparql11-query/#func-month
15
15
  class Month < Operator::Unary
16
16
  include Evaluatable
17
17
 
@@ -9,7 +9,7 @@ module SPARQL; module Algebra
9
9
  # @example
10
10
  # (move silent <iri> to default)
11
11
  #
12
- # @see http://www.w3.org/TR/sparql11-update/#move
12
+ # @see https://www.w3.org/TR/sparql11-update/#move
13
13
  class Move < Operator
14
14
  include SPARQL::Algebra::Update
15
15
 
@@ -28,8 +28,8 @@ module SPARQL; module Algebra
28
28
  # Returns queryable.
29
29
  # @raise [IOError]
30
30
  # If `from` does not exist, unless the `silent` operator is present
31
- # @see http://www.w3.org/TR/sparql11-update/
32
- def execute(queryable, options = {})
31
+ # @see https://www.w3.org/TR/sparql11-update/
32
+ def execute(queryable, **options)
33
33
  debug(options) {"Move"}
34
34
  silent = operands.first == :silent
35
35
  operands.shift if silent
@@ -7,7 +7,7 @@ module SPARQL; module Algebra
7
7
  # (* ?x ?y)
8
8
  # (multiply ?x ?y)
9
9
  #
10
- # @see http://www.w3.org/TR/xpath-functions/#func-numeric-multiply
10
+ # @see https://www.w3.org/TR/xpath-functions/#func-numeric-multiply
11
11
  class Multiply < Operator::Binary
12
12
  include Evaluatable
13
13