sparql 3.1.8 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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