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
@@ -5,6 +5,29 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # If triple is an RDF-star triple, the function returns the object of this triple. Passing anything other than an RDF-star triple is an error.
7
7
  #
8
+ # [121] BuiltInCall ::= ... | 'OBJECT' '(' Expression ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.com/ns#>
12
+ # SELECT * {
13
+ # ?t :source :g
14
+ # FILTER(isTriple(?t))
15
+ # FILTER(SUBJECT(?t) = :s)
16
+ # FILTER(PREDICATE(?t) = :p)
17
+ # FILTER(OBJECT(?t) = :o)
18
+ # }
19
+ #
20
+ # @example SSE
21
+ # (prefix
22
+ # ((: <http://example.com/ns#>))
23
+ # (filter
24
+ # (exprlist
25
+ # (isTRIPLE ?t)
26
+ # (= (subject ?t) :s)
27
+ # (= (predicate ?t) :p)
28
+ # (= (object ?t) :o))
29
+ # (bgp (triple ?t :source :g))) )
30
+ #
8
31
  # @see https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#object
9
32
  class Object < Operator::Unary
10
33
  include Evaluatable
@@ -22,6 +45,15 @@ module SPARQL; module Algebra
22
45
  raise TypeError, "expected an RDF::Statement, but got #{operand.inspect}" unless operand.is_a?(RDF::Statement)
23
46
  operand.object
24
47
  end
48
+
49
+ ##
50
+ #
51
+ # Returns a partial SPARQL grammar for this operator.
52
+ #
53
+ # @return [String]
54
+ def to_sparql(**options)
55
+ "OBJECT(" + operands.last.to_sparql(**options) + ")"
56
+ end
25
57
  end # Object
26
58
  end # Operator
27
59
  end; end # SPARQL::Algebra
@@ -3,9 +3,23 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL logical `or` operator.
5
5
  #
6
- # @example
7
- # (|| ?x ?y)
8
- # (or ?x ?y)
6
+ # [111] ConditionalOrExpression ::= ConditionalAndExpression ( '||' ConditionalAndExpression )*
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 {
13
+ # ?a :p ?v .
14
+ # FILTER ("false"^^xsd:boolean || ?v) .
15
+ # }
16
+ #
17
+ # @example SSE
18
+ # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
19
+ # (: <http://example.org/ns#>))
20
+ # (project (?a)
21
+ # (filter (|| false ?v)
22
+ # (bgp (triple ?a :p ?v)))))
9
23
  #
10
24
  # @see https://www.w3.org/TR/sparql11-query/#func-logical-or
11
25
  # @see https://www.w3.org/TR/sparql11-query/#evaluation
@@ -63,6 +77,15 @@ module SPARQL; module Algebra
63
77
  else RDF::Literal(left || right)
64
78
  end
65
79
  end
80
+
81
+ ##
82
+ #
83
+ # Returns a partial SPARQL grammar for this operator.
84
+ #
85
+ # @return [String]
86
+ def to_sparql(**options)
87
+ "(#{operands.first.to_sparql(**options)} || #{operands.last.to_sparql(**options)})"
88
+ end
66
89
  end # Or
67
90
  end # Operator
68
91
  end; end # SPARQL::Algebra
@@ -3,7 +3,15 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `order` operator.
5
5
  #
6
- # @example
6
+ # [23] OrderClause ::= 'ORDER' 'BY' OrderCondition+
7
+ #
8
+ # @example SPARQL Grammar
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))
@@ -56,6 +64,17 @@ module SPARQL; module Algebra
56
64
  @solutions.each(&block) if block_given?
57
65
  @solutions
58
66
  end
67
+
68
+ ##
69
+ #
70
+ # Returns a partial SPARQL grammar for this operator.
71
+ #
72
+ # Provides order to descendant query.
73
+ #
74
+ # @return [String]
75
+ def to_sparql(**options)
76
+ operands.last.to_sparql(order_ops: operands.first, **options)
77
+ end
59
78
  end # Order
60
79
  end # Operator
61
80
  end; end # SPARQL::Algebra
@@ -3,8 +3,23 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL Property Path `path` operator.
5
5
  #
6
- # @example
7
- # (path :a (path+ :p) ?z)
6
+ # [88] Path ::= PathAlternative
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://www.example.org/>
10
+ # SELECT ?t
11
+ # WHERE {
12
+ # :a :p1|:p2/:p3|:p4 ?t
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://www.example.org/>))
17
+ # (project (?t)
18
+ # (path :a
19
+ # (alt
20
+ # (alt :p1 (seq :p2 :p3))
21
+ # :p4)
22
+ # ?t)))
8
23
  #
9
24
  # @see https://www.w3.org/TR/sparql11-query/#sparqlTranslatePathExpressions
10
25
  class Path < Operator::Ternary
@@ -45,6 +60,18 @@ module SPARQL; module Algebra
45
60
  @solutions.each(&block) if block_given?
46
61
  @solutions
47
62
  end
63
+
64
+ ##
65
+ #
66
+ # Returns a partial SPARQL grammar for this operator.
67
+ #
68
+ # @param [Boolean] top_level (true)
69
+ # Treat this as a top-level, generating SELECT ... WHERE {}
70
+ # @return [String]
71
+ def to_sparql(top_level: true, **options)
72
+ str = operands.to_sparql(top_level: false, **options) + " ."
73
+ top_level ? Operator.to_sparql(str, **options) : str
74
+ end
48
75
  end # Path
49
76
  end # Operator
50
77
  end; end # SPARQL::Algebra
@@ -3,8 +3,18 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL Property Path `path?` (ZeroOrOnePath) operator.
5
5
  #
6
- # @example
7
- # (path? :p)
6
+ # [91] PathElt ::= PathPrimary PathMod?
7
+ # [93] PathMod ::= '*' | '?' | '+'
8
+
9
+ # @example SPARQL Grammar
10
+ # PREFIX : <http://example/>
11
+ # SELECT * WHERE {
12
+ # :a (:p/:p)? ?t
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example/>))
17
+ # (path :a (path? (seq :p :p)) ?t))
8
18
  #
9
19
  # @see https://www.w3.org/TR/sparql11-query/#defn_evalPP_ZeroOrOnePath
10
20
  class PathOpt < Operator::Unary
@@ -107,6 +117,15 @@ module SPARQL; module Algebra
107
117
  solutions.each(&block) if block_given?
108
118
  solutions
109
119
  end
120
+
121
+ ##
122
+ #
123
+ # Returns a partial SPARQL grammar for this operator.
124
+ #
125
+ # @return [String]
126
+ def to_sparql(**options)
127
+ "(#{operands.first.to_sparql(**options)})?"
128
+ end
110
129
  end # PathOpt
111
130
  end # Operator
112
131
  end; end # SPARQL::Algebra
@@ -3,8 +3,18 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL Property Path `path+` (OneOrMorePath) operator.
5
5
  #
6
- # @example
7
- # (path+ :p)
6
+ # [91] PathElt ::= PathPrimary PathMod?
7
+ # [93] PathMod ::= '*' | '?' | '+'
8
+
9
+ # @example SPARQL Grammar
10
+ # PREFIX : <http://example/>
11
+ # SELECT * WHERE {
12
+ # :a :p+ ?z
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example/>))
17
+ # (path :a (path+ :p) ?z))
8
18
  #
9
19
  # @see https://www.w3.org/TR/sparql11-query/#defn_evalPP_OneOrMorePath
10
20
  class PathPlus < Operator::Unary
@@ -94,6 +104,15 @@ module SPARQL; module Algebra
94
104
  solutions.each(&block) if block_given? # Only at top-level
95
105
  solutions
96
106
  end
107
+
108
+ ##
109
+ #
110
+ # Returns a partial SPARQL grammar for this operator.
111
+ #
112
+ # @return [String]
113
+ def to_sparql(**options)
114
+ "(#{operands.first.to_sparql(**options)})+"
115
+ end
97
116
  end # PathPlus
98
117
  end # Operator
99
118
  end; end # SPARQL::Algebra
@@ -3,8 +3,18 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL Property Path `path*` (ZeroOrMorePath) operator.
5
5
  #
6
- # @example
7
- # (path* :p)
6
+ # [91] PathElt ::= PathPrimary PathMod?
7
+ # [93] PathMod ::= '*' | '?' | '+'
8
+
9
+ # @example SPARQL Grammar
10
+ # PREFIX : <http://example/>
11
+ # SELECT * WHERE {
12
+ # :a :p* ?z
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example/>))
17
+ # (path :a (path* :p) ?z))
8
18
  #
9
19
  # @see https://www.w3.org/TR/sparql11-query/#defn_evalPP_ZeroOrMorePath
10
20
  class PathStar < Operator::Unary
@@ -37,6 +47,14 @@ module SPARQL; module Algebra
37
47
  query = PathOpt.new(PathPlus.new(*operands))
38
48
  query.execute(queryable, depth: options[:depth].to_i + 1, **options, &block)
39
49
  end
50
+ ##
51
+ #
52
+ # Returns a partial SPARQL grammar for this operator.
53
+ #
54
+ # @return [String]
55
+ def to_sparql(**options)
56
+ "(#{operands.first.to_sparql(**options)})*"
57
+ end
40
58
  end # PathStar
41
59
  end # Operator
42
60
  end; end # SPARQL::Algebra
@@ -3,9 +3,39 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL numeric binary/unary `+` operator.
5
5
  #
6
- # @example
7
- # (+ ?x ?y)
8
- # (plus ?x ?y)
6
+ # [118] UnaryExpression ::= ... | '+' PrimaryExpression
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT ?s WHERE {
11
+ # ?s :p ?o .
12
+ # FILTER(-?o = +3) .
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/>))
17
+ # (project (?s)
18
+ # (filter (= (- ?o) +3)
19
+ # (bgp (triple ?s :p ?o)))))
20
+ #
21
+ # [116] AdditiveExpression ::= MultiplicativeExpression ( '+' MultiplicativeExpression )?
22
+ #
23
+ # @example SPARQL Grammar
24
+ # PREFIX : <http://example.org/>
25
+ # SELECT ?s WHERE {
26
+ # ?s :p ?o .
27
+ # ?s2 :p ?o2 .
28
+ # FILTER(?o + ?o2 = 3) .
29
+ # }
30
+ #
31
+ # @example SSE
32
+ # (prefix
33
+ # ((: <http://example.org/>))
34
+ # (project (?s)
35
+ # (filter (= (+ ?o ?o2) 3)
36
+ # (bgp
37
+ # (triple ?s :p ?o)
38
+ # (triple ?s2 :p ?o2)))))
9
39
  #
10
40
  # @see https://www.w3.org/TR/xpath-functions/#func-numeric-unary-plus
11
41
  # @see https://www.w3.org/TR/xpath-functions/#func-numeric-add
@@ -32,6 +62,15 @@ module SPARQL; module Algebra
32
62
  else raise TypeError, "expected two RDF::Literal::Numeric operands, but got #{left.inspect} and #{right.inspect}"
33
63
  end
34
64
  end
65
+
66
+ ##
67
+ #
68
+ # Returns a partial SPARQL grammar for this operator.
69
+ #
70
+ # @return [String]
71
+ def to_sparql(**options)
72
+ "#{operands.first.to_sparql(**options)} + #{operands.last.to_sparql(**options)}"
73
+ end
35
74
  end # Plus
36
75
  end # Operator
37
76
  end; end # SPARQL::Algebra
@@ -5,6 +5,29 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # If triple is an RDF-star triple, the function returns the predicate of this triple. Passing anything other than an RDF-star triple is an error.
7
7
  #
8
+ # [121] BuiltInCall ::= ... | 'PREDICATE' '(' Expression ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.com/ns#>
12
+ # SELECT * {
13
+ # ?t :source :g
14
+ # FILTER(isTriple(?t))
15
+ # FILTER(SUBJECT(?t) = :s)
16
+ # FILTER(PREDICATE(?t) = :p)
17
+ # FILTER(OBJECT(?t) = :o)
18
+ # }
19
+ #
20
+ # @example SSE
21
+ # (prefix
22
+ # ((: <http://example.com/ns#>))
23
+ # (filter
24
+ # (exprlist
25
+ # (isTRIPLE ?t)
26
+ # (= (subject ?t) :s)
27
+ # (= (predicate ?t) :p)
28
+ # (= (object ?t) :o))
29
+ # (bgp (triple ?t :source :g))) )
30
+ #
8
31
  # @see https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#predicate
9
32
  class Predicate < Operator::Unary
10
33
  include Evaluatable
@@ -22,6 +45,15 @@ module SPARQL; module Algebra
22
45
  raise TypeError, "expected an RDF::Statement, but got #{operand.inspect}" unless operand.is_a?(RDF::Statement)
23
46
  operand.predicate
24
47
  end
48
+
49
+ ##
50
+ #
51
+ # Returns a partial SPARQL grammar for this operator.
52
+ #
53
+ # @return [String]
54
+ def to_sparql(**options)
55
+ "PREDICATE(" + operands.last.to_sparql(**options) + ")"
56
+ end
25
57
  end # Predicate
26
58
  end # Operator
27
59
  end; end # SPARQL::Algebra
@@ -3,10 +3,15 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `prefix` operator.
5
5
  #
6
- # @example
6
+ # [6] PrefixDecl ::= 'PREFIX' PNAME_NS IRIREF
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example/>
10
+ # SELECT * { :s :p :o }
11
+ #
12
+ # @example SSE
7
13
  # (prefix ((: <http://example/>))
8
- # (graph ?g
9
- # (bgp (triple ?s ?p ?o))))
14
+ # (bgp (triple :s :p :o)))
10
15
  #
11
16
  # @see https://www.w3.org/TR/sparql11-query/#QSynIRI
12
17
  class Prefix < Binary
@@ -65,6 +70,22 @@ module SPARQL; module Algebra
65
70
  def query_yields_statements?
66
71
  operands.last.query_yields_statements?
67
72
  end
73
+
74
+ ##
75
+ #
76
+ # Returns a partial SPARQL grammar for this term.
77
+ #
78
+ # @return [String]
79
+ def to_sparql(**options)
80
+ prefixes = {}
81
+ str = operands.first.map do |(pfx, sfx)|
82
+ pfx = pfx.to_s.chomp(':').to_sym
83
+ prefixes[pfx] = sfx
84
+ "PREFIX #{pfx}: #{sfx.to_sparql}\n"
85
+ end.join("")
86
+
87
+ str << operands.last.to_sparql(prefixes: prefixes, **options)
88
+ end
68
89
  end # Prefix
69
90
  end # Operator
70
91
  end; end # SPARQL::Algebra
@@ -3,11 +3,36 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `project` operator.
5
5
  #
6
- # @example
7
- # (select (?v)
8
- # (project (?v)
9
- # (filter (= ?v 2)
10
- # (bgp (triple ?s <http://example/p> ?v)))))
6
+ # [9] SelectClause ::= 'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' )
7
+ #
8
+ # ## Basic Projection
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example/>
12
+ # SELECT ?v {
13
+ # ?s :p ?v .
14
+ # FILTER (?v = 2)
15
+ # }
16
+ #
17
+ # @example SSE
18
+ # (prefix ((: <http://example/>))
19
+ # (project (?v)
20
+ # (filter (= ?v 2)
21
+ # (bgp (triple ?s :p ?v)))))
22
+ #
23
+ # ## Sub select
24
+ #
25
+ # @example SPARQL Grammar
26
+ # SELECT (1 AS ?X ) {
27
+ # SELECT (2 AS ?Y ) {}
28
+ # }
29
+ #
30
+ # @example SSE
31
+ # (project (?X)
32
+ # (extend ((?X 1))
33
+ # (project (?Y)
34
+ # (extend ((?Y 2))
35
+ # (bgp)))))
11
36
  #
12
37
  # @see https://www.w3.org/TR/sparql11-query/#modProjection
13
38
  class Project < Operator::Binary
@@ -36,6 +61,27 @@ module SPARQL; module Algebra
36
61
  @solutions.each(&block) if block_given?
37
62
  @solutions
38
63
  end
64
+
65
+ ##
66
+ #
67
+ # Returns a partial SPARQL grammar for this operator.
68
+ #
69
+ # Extracts projections
70
+ #
71
+ # If there are already extensions or filters, then this is a sub-select.
72
+ #
73
+ # @return [String]
74
+ def to_sparql(**options)
75
+ vars = operands[0].empty? ? [:*] : operands[0]
76
+ if options[:extensions] || options[:filter_ops] || options[:project]
77
+ # Any of these options indicates we're in a sub-select
78
+ opts = options.dup.delete_if {|k,v| %I{extensions filter_ops project}.include?(k)}
79
+ content = operands.last.to_sparql(project: vars, **opts)
80
+ Operator.to_sparql(content, **options)
81
+ else
82
+ operands.last.to_sparql(project: vars, **options)
83
+ end
84
+ end
39
85
  end # Project
40
86
  end # Operator
41
87
  end; end # SPARQL::Algebra
@@ -5,8 +5,25 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Returns a pseudo-random number between 0 (inclusive) and 1.0e0 (exclusive). Different numbers can be produced every time this function is invoked. Numbers should be produced with approximately equal probability.
7
7
  #
8
- # @example
9
- # (rand)
8
+ # [121] BuiltInCall ::= ... | 'RAND' NIL
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
12
+ # ASK {
13
+ # BIND(RAND() AS ?r)
14
+ # FILTER(DATATYPE(?r) = xsd:double && ?r >= 0.0 && ?r < 1.0)
15
+ # }
16
+ #
17
+ # @example SSE
18
+ # (prefix
19
+ # ((xsd: <http://www.w3.org/2001/XMLSchema#>))
20
+ # (ask
21
+ # (filter
22
+ # (&&
23
+ # (&& (= (datatype ?r) xsd:double) (>= ?r 0.0))
24
+ # (< ?r 1.0))
25
+ # (extend ((?r (rand)))
26
+ # (bgp)))))
10
27
  #
11
28
  # @see https://www.w3.org/TR/sparql11-query/#idp2130040
12
29
  class Rand < Operator::Nullary
@@ -21,6 +38,17 @@ module SPARQL; module Algebra
21
38
  def apply(**options)
22
39
  RDF::Literal::Double.new(Random.rand)
23
40
  end
41
+
42
+ ##
43
+ #
44
+ # Returns a partial SPARQL grammar for this operator.
45
+ #
46
+ # Extracts projections
47
+ #
48
+ # @return [String]
49
+ def to_sparql(**options)
50
+ "RAND()"
51
+ end
24
52
  end # Rand
25
53
  end # Operator
26
54
  end; end # SPARQL::Algebra
@@ -3,7 +3,15 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `reduced` operator.
5
5
  #
6
- # @example
6
+ # [9] SelectClause ::= 'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' )
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
11
+ # SELECT DISTINCT ?v
12
+ # WHERE { ?x ?p ?v }
13
+ #
14
+ # @example SSE
7
15
  # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
8
16
  # (: <http://example/>))
9
17
  # (reduced
@@ -37,6 +45,15 @@ module SPARQL; module Algebra
37
45
  @solutions.each(&block) if block_given?
38
46
  @solutions
39
47
  end
48
+
49
+ ##
50
+ #
51
+ # Returns a partial SPARQL grammar for this operator.
52
+ #
53
+ # @return [String]
54
+ def to_sparql(**options)
55
+ operands.first.to_sparql(reduced: true, **options)
56
+ end
40
57
  end # Reduced
41
58
  end # Operator
42
59
  end; end # SPARQL::Algebra
@@ -3,33 +3,31 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `regex` operator.
5
5
  #
6
- # @example
6
+ # [122] RegexExpression ::= 'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
10
+ # PREFIX ex: <http://example.com/#>
11
+ # SELECT ?val
12
+ # WHERE {
13
+ # ex:foo rdf:value ?val .
14
+ # FILTER regex(?val, "GHI")
15
+ # }
16
+ #
17
+ # @example SSE
7
18
  # (prefix ((ex: <http://example.com/#>)
8
19
  # (rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>))
9
- # (project (?val)
10
- # (filter (regex ?val "GHI")
11
- # (bgp (triple ex:foo rdf:value ?val)))))
20
+ # (project (?val)
21
+ # (filter (regex ?val "GHI")
22
+ # (bgp (triple ex:foo rdf:value ?val)))))
12
23
  #
13
24
  # @see https://www.w3.org/TR/sparql11-query/#funcex-regex
14
25
  # @see https://www.w3.org/TR/xpath-functions/#func-matches
15
- class Regex < Operator::Ternary
26
+ class Regex < Operator
16
27
  include Evaluatable
17
28
 
18
29
  NAME = :regex
19
30
 
20
- ##
21
- # Initializes a new operator instance.
22
- #
23
- # @param [RDF::Term] text
24
- # @param [RDF::Term] pattern
25
- # @param [RDF::Term] flags
26
- # @param [Hash{Symbol => Object}] options
27
- # any additional options (see {Operator#initialize})
28
- # @raise [TypeError] if any operand is invalid
29
- def initialize(text, pattern, flags = RDF::Literal(''), **options)
30
- super
31
- end
32
-
33
31
  ##
34
32
  # Matches `text` against a regular expression `pattern`.
35
33
  #
@@ -65,6 +63,16 @@ module SPARQL; module Algebra
65
63
  options |= Regexp::EXTENDED if flags.include?(?x)
66
64
  RDF::Literal(Regexp.new(pattern, options) === text)
67
65
  end
66
+
67
+ ##
68
+ #
69
+ # Returns a partial SPARQL grammar for this operator.
70
+ #
71
+ # @return [String]
72
+ def to_sparql(**options)
73
+ ops = operands.last.to_s.empty? ? operands[0..-2] : operands
74
+ "regex(" + ops.to_sparql(delimiter: ', ', **options) + ")"
75
+ end
68
76
  end # Regex
69
77
  end # Operator
70
78
  end; end # SPARQL::Algebra
@@ -3,12 +3,22 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `replace` operator.
5
5
  #
6
- # @example
7
- # (prefix ((: <http://example.org/>)
8
- # (xsd: <http://www.w3.org/2001/XMLSchema#>))
9
- # (project (?s ?new)
10
- # (extend ((?new (replace ?str "[^a-z0-9]" "-")))
11
- # (bgp (triple ?s :str ?str)))))
6
+ # [124] StrReplaceExpression ::= 'REPLACE' '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
11
+ # SELECT ?s (REPLACE(?str,"[^a-z0-9]", "-") AS ?new)
12
+ # WHERE {
13
+ # ?s :str ?str
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix ((: <http://example.org/>)
18
+ # (xsd: <http://www.w3.org/2001/XMLSchema#>))
19
+ # (project (?s ?new)
20
+ # (extend ((?new (replace ?str "[^a-z0-9]" "-")))
21
+ # (bgp (triple ?s :str ?str)))))
12
22
  #
13
23
  # @see https://www.w3.org/TR/sparql11-query/#funcex-replace
14
24
  # @see https://www.w3.org/TR/xpath-functions/#func-replace
@@ -76,6 +86,16 @@ module SPARQL; module Algebra
76
86
  def to_sxp_bin
77
87
  [NAME] + operands.reject {|o| o.to_s == ""}
78
88
  end
89
+
90
+ ##
91
+ #
92
+ # Returns a partial SPARQL grammar for this operator.
93
+ #
94
+ # @return [String]
95
+ def to_sparql(**options)
96
+ ops = operands.last.to_s.empty? ? operands[0..-2] : operands
97
+ "REPLACE(" + ops.to_sparql(delimiter: ', ', **options) + ")"
98
+ end
79
99
  end # Replace
80
100
  end # Operator
81
101
  end; end # SPARQL::Algebra