sparql 3.1.6 → 3.2.1

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 (145) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +31 -22
  3. data/VERSION +1 -1
  4. data/bin/sparql +14 -4
  5. data/lib/sparql/algebra/aggregate.rb +1 -1
  6. data/lib/sparql/algebra/evaluatable.rb +4 -4
  7. data/lib/sparql/algebra/expression.rb +28 -3
  8. data/lib/sparql/algebra/extensions.rb +109 -45
  9. data/lib/sparql/algebra/operator/abs.rb +23 -3
  10. data/lib/sparql/algebra/operator/add.rb +21 -2
  11. data/lib/sparql/algebra/operator/alt.rb +26 -2
  12. data/lib/sparql/algebra/operator/and.rb +25 -3
  13. data/lib/sparql/algebra/operator/asc.rb +20 -1
  14. data/lib/sparql/algebra/operator/ask.rb +17 -1
  15. data/lib/sparql/algebra/operator/avg.rb +20 -2
  16. data/lib/sparql/algebra/operator/base.rb +18 -1
  17. data/lib/sparql/algebra/operator/bgp.rb +13 -1
  18. data/lib/sparql/algebra/operator/bnode.rb +34 -11
  19. data/lib/sparql/algebra/operator/bound.rb +22 -1
  20. data/lib/sparql/algebra/operator/ceil.rb +26 -3
  21. data/lib/sparql/algebra/operator/clear.rb +26 -2
  22. data/lib/sparql/algebra/operator/coalesce.rb +33 -11
  23. data/lib/sparql/algebra/operator/compare.rb +48 -40
  24. data/lib/sparql/algebra/operator/concat.rb +26 -2
  25. data/lib/sparql/algebra/operator/construct.rb +29 -6
  26. data/lib/sparql/algebra/operator/contains.rb +25 -3
  27. data/lib/sparql/algebra/operator/copy.rb +19 -2
  28. data/lib/sparql/algebra/operator/count.rb +53 -7
  29. data/lib/sparql/algebra/operator/create.rb +20 -2
  30. data/lib/sparql/algebra/operator/dataset.rb +27 -2
  31. data/lib/sparql/algebra/operator/datatype.rb +26 -7
  32. data/lib/sparql/algebra/operator/day.rb +24 -6
  33. data/lib/sparql/algebra/operator/delete.rb +29 -2
  34. data/lib/sparql/algebra/operator/delete_data.rb +23 -2
  35. data/lib/sparql/algebra/operator/delete_where.rb +24 -2
  36. data/lib/sparql/algebra/operator/desc.rb +20 -1
  37. data/lib/sparql/algebra/operator/describe.rb +27 -4
  38. data/lib/sparql/algebra/operator/distinct.rb +20 -3
  39. data/lib/sparql/algebra/operator/divide.rb +27 -3
  40. data/lib/sparql/algebra/operator/drop.rb +27 -3
  41. data/lib/sparql/algebra/operator/encode_for_uri.rb +23 -3
  42. data/lib/sparql/algebra/operator/equal.rb +13 -3
  43. data/lib/sparql/algebra/operator/exists.rb +28 -4
  44. data/lib/sparql/algebra/operator/exprlist.rb +15 -2
  45. data/lib/sparql/algebra/operator/extend.rb +64 -6
  46. data/lib/sparql/algebra/operator/filter.rb +27 -5
  47. data/lib/sparql/algebra/operator/floor.rb +26 -3
  48. data/lib/sparql/algebra/operator/function_call.rb +64 -0
  49. data/lib/sparql/algebra/operator/graph.rb +69 -6
  50. data/lib/sparql/algebra/operator/greater_than.rb +14 -4
  51. data/lib/sparql/algebra/operator/greater_than_or_equal.rb +14 -4
  52. data/lib/sparql/algebra/operator/group.rb +105 -8
  53. data/lib/sparql/algebra/operator/group_concat.rb +44 -8
  54. data/lib/sparql/algebra/operator/hours.rb +24 -6
  55. data/lib/sparql/algebra/operator/if.rb +20 -3
  56. data/lib/sparql/algebra/operator/in.rb +18 -1
  57. data/lib/sparql/algebra/operator/insert.rb +24 -2
  58. data/lib/sparql/algebra/operator/insert_data.rb +23 -2
  59. data/lib/sparql/algebra/operator/iri.rb +22 -5
  60. data/lib/sparql/algebra/operator/is_blank.rb +21 -4
  61. data/lib/sparql/algebra/operator/is_iri.rb +21 -4
  62. data/lib/sparql/algebra/operator/is_literal.rb +21 -4
  63. data/lib/sparql/algebra/operator/is_numeric.rb +23 -6
  64. data/lib/sparql/algebra/operator/is_triple.rb +33 -1
  65. data/lib/sparql/algebra/operator/join.rb +56 -1
  66. data/lib/sparql/algebra/operator/lang.rb +26 -1
  67. data/lib/sparql/algebra/operator/lang_matches.rb +23 -2
  68. data/lib/sparql/algebra/operator/lcase.rb +23 -3
  69. data/lib/sparql/algebra/operator/left_join.rb +42 -1
  70. data/lib/sparql/algebra/operator/less_than.rb +14 -4
  71. data/lib/sparql/algebra/operator/less_than_or_equal.rb +14 -4
  72. data/lib/sparql/algebra/operator/load.rb +25 -2
  73. data/lib/sparql/algebra/operator/max.rb +20 -2
  74. data/lib/sparql/algebra/operator/md5.rb +23 -6
  75. data/lib/sparql/algebra/operator/min.rb +22 -4
  76. data/lib/sparql/algebra/operator/minus.rb +65 -7
  77. data/lib/sparql/algebra/operator/minutes.rb +24 -6
  78. data/lib/sparql/algebra/operator/modify.rb +41 -5
  79. data/lib/sparql/algebra/operator/month.rb +24 -6
  80. data/lib/sparql/algebra/operator/move.rb +20 -2
  81. data/lib/sparql/algebra/operator/multiply.rb +27 -4
  82. data/lib/sparql/algebra/operator/negate.rb +24 -4
  83. data/lib/sparql/algebra/operator/not.rb +25 -4
  84. data/lib/sparql/algebra/operator/not_equal.rb +16 -1
  85. data/lib/sparql/algebra/operator/notexists.rb +30 -6
  86. data/lib/sparql/algebra/operator/notin.rb +20 -3
  87. data/lib/sparql/algebra/operator/notoneof.rb +21 -2
  88. data/lib/sparql/algebra/operator/now.rb +25 -6
  89. data/lib/sparql/algebra/operator/object.rb +33 -1
  90. data/lib/sparql/algebra/operator/or.rb +26 -3
  91. data/lib/sparql/algebra/operator/order.rb +71 -2
  92. data/lib/sparql/algebra/operator/path.rb +29 -2
  93. data/lib/sparql/algebra/operator/path_opt.rb +21 -2
  94. data/lib/sparql/algebra/operator/path_plus.rb +21 -2
  95. data/lib/sparql/algebra/operator/path_star.rb +20 -2
  96. data/lib/sparql/algebra/operator/plus.rb +43 -4
  97. data/lib/sparql/algebra/operator/predicate.rb +33 -1
  98. data/lib/sparql/algebra/operator/prefix.rb +24 -3
  99. data/lib/sparql/algebra/operator/project.rb +69 -5
  100. data/lib/sparql/algebra/operator/rand.rb +31 -3
  101. data/lib/sparql/algebra/operator/reduced.rb +20 -3
  102. data/lib/sparql/algebra/operator/regex.rb +27 -19
  103. data/lib/sparql/algebra/operator/replace.rb +27 -7
  104. data/lib/sparql/algebra/operator/reverse.rb +31 -2
  105. data/lib/sparql/algebra/operator/round.rb +26 -3
  106. data/lib/sparql/algebra/operator/same_term.rb +25 -7
  107. data/lib/sparql/algebra/operator/sample.rb +33 -9
  108. data/lib/sparql/algebra/operator/seconds.rb +24 -6
  109. data/lib/sparql/algebra/operator/seq.rb +20 -2
  110. data/lib/sparql/algebra/operator/sequence.rb +4 -11
  111. data/lib/sparql/algebra/operator/sha1.rb +19 -2
  112. data/lib/sparql/algebra/operator/sha256.rb +19 -2
  113. data/lib/sparql/algebra/operator/sha384.rb +19 -2
  114. data/lib/sparql/algebra/operator/sha512.rb +19 -2
  115. data/lib/sparql/algebra/operator/slice.rb +27 -5
  116. data/lib/sparql/algebra/operator/str.rb +22 -2
  117. data/lib/sparql/algebra/operator/strafter.rb +26 -3
  118. data/lib/sparql/algebra/operator/strbefore.rb +26 -3
  119. data/lib/sparql/algebra/operator/strdt.rb +23 -2
  120. data/lib/sparql/algebra/operator/strends.rb +26 -4
  121. data/lib/sparql/algebra/operator/strlang.rb +25 -7
  122. data/lib/sparql/algebra/operator/strlen.rb +24 -3
  123. data/lib/sparql/algebra/operator/strstarts.rb +26 -3
  124. data/lib/sparql/algebra/operator/struuid.rb +30 -10
  125. data/lib/sparql/algebra/operator/subject.rb +33 -1
  126. data/lib/sparql/algebra/operator/substr.rb +24 -3
  127. data/lib/sparql/algebra/operator/subtract.rb +29 -3
  128. data/lib/sparql/algebra/operator/sum.rb +25 -7
  129. data/lib/sparql/algebra/operator/table.rb +76 -4
  130. data/lib/sparql/algebra/operator/timezone.rb +24 -6
  131. data/lib/sparql/algebra/operator/tz.rb +23 -6
  132. data/lib/sparql/algebra/operator/ucase.rb +24 -3
  133. data/lib/sparql/algebra/operator/union.rb +29 -6
  134. data/lib/sparql/algebra/operator/update.rb +46 -4
  135. data/lib/sparql/algebra/operator/using.rb +49 -2
  136. data/lib/sparql/algebra/operator/uuid.rb +28 -9
  137. data/lib/sparql/algebra/operator/with.rb +38 -4
  138. data/lib/sparql/algebra/operator/year.rb +24 -6
  139. data/lib/sparql/algebra/operator.rb +135 -14
  140. data/lib/sparql/algebra/sxp_extensions.rb +3 -3
  141. data/lib/sparql/algebra.rb +20 -3
  142. data/lib/sparql/grammar/meta.rb +1103 -907
  143. data/lib/sparql/grammar/parser11.rb +63 -56
  144. metadata +43 -29
  145. data/lib/sparql/algebra/operator/triple.rb +0 -27
@@ -5,13 +5,34 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # GroupConcat is a set function which performs a string concatenation across the values of an expression with a group. The order of the strings is not specified. The separator character used in the concatenation may be given with the scalar argument SEPARATOR.
7
7
  #
8
- # @example
9
- # (prefix ((: <http://www.example.org/>))
10
- # (filter (|| (= ?g "1 22") (= ?g "22 1"))
11
- # (project (?g)
12
- # (extend ((?g ??.0))
13
- # (group () ((??.0 (group_concat ?o)))
14
- # (bgp (triple ??.0 :p1 ?o)))))))
8
+ # [127] Aggregate::= ... | 'GROUP_CONCAT' '(' 'DISTINCT'? Expression ( ';' 'SEPARATOR' '=' String )? ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # SELECT (GROUP_CONCAT(?x) AS ?y) {}
12
+ #
13
+ # @example SSE
14
+ # (project (?y)
15
+ # (extend ((?y ??.0))
16
+ # (group () ((??.0 (group_concat ?x)))
17
+ # (bgp))))
18
+ #
19
+ # @example SPARQL Grammar (DISTINCT)
20
+ # SELECT (GROUP_CONCAT(DISTINCT ?x) AS ?y) {}
21
+ #
22
+ # @example SSE (DISTINCT)
23
+ # (project (?y)
24
+ # (extend ((?y ??.0))
25
+ # (group () ((??.0 (group_concat distinct ?x)))
26
+ # (bgp))))
27
+ #
28
+ # @example SPARQL Grammar (SEPARATOR)
29
+ # SELECT (GROUP_CONCAT(?x; SEPARATOR=';') AS ?y) {}
30
+ #
31
+ # @example SSE (SEPARATOR)
32
+ # (project (?y)
33
+ # (extend ((?y ??.0))
34
+ # (group () ((??.0 (group_concat (separator ";") ?x)))
35
+ # (bgp))))
15
36
  #
16
37
  # @see https://www.w3.org/TR/sparql11-query/#defn_aggGroupConcat
17
38
  class GroupConcat < Operator
@@ -50,9 +71,24 @@ module SPARQL; module Algebra
50
71
  # enum of evaluated operand
51
72
  # @return [RDF::Term] An arbitrary term
52
73
  # @raise [TypeError] If enum is empty
53
- def apply(enum, separator)
74
+ def apply(enum, separator, **options)
54
75
  RDF::Literal(enum.flatten.map(&:to_s).join(separator.to_s))
55
76
  end
77
+
78
+ ##
79
+ #
80
+ # Returns a partial SPARQL grammar for this operator.
81
+ #
82
+ # @return [String]
83
+ def to_sparql(**options)
84
+ distinct = operands.first == :distinct
85
+ args = distinct ? operands[1..-1] : operands
86
+ separator = args.first.last if args.first.is_a?(Array) && args.first.first == :separator
87
+ args = args[1..-1] if separator
88
+ str = "GROUP_CONCAT(#{'DISTINCT ' if distinct}#{args.to_sparql(delimiter: ', ', **options)}"
89
+ str << "; SEPARATOR=#{separator.to_sparql}" if separator
90
+ str << ")"
91
+ end
56
92
  end # GroupConcat
57
93
  end # Operator
58
94
  end; end # SPARQL::Algebra
@@ -3,11 +3,20 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL logical `hours` operator.
5
5
  #
6
- # @example
7
- # (prefix ((: <http://example.org/>))
8
- # (project (?s ?x)
9
- # (extend ((?x (hours ?date)))
10
- # (bgp (triple ?s :date ?date)))))
6
+ # [121] BuiltInCall ::= ... | 'HOURS' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT ?s (HOURS(?date) AS ?x) WHERE {
11
+ # ?s :date ?date
12
+ # }
13
+ #
14
+ # @example SSE
15
+ # (prefix
16
+ # ((: <http://example.org/>))
17
+ # (project (?s ?x)
18
+ # (extend ((?x (hours ?date)))
19
+ # (bgp (triple ?s :date ?date)))))
11
20
  #
12
21
  # @see https://www.w3.org/TR/sparql11-query/#func-hours
13
22
  class Hours < Operator::Unary
@@ -22,10 +31,19 @@ module SPARQL; module Algebra
22
31
  # the operand
23
32
  # @return [RDF::Literal]
24
33
  # @raise [TypeError] if the operand is not a simple literal
25
- def apply(operand)
34
+ def apply(operand, **options)
26
35
  raise TypeError, "expected an RDF::Literal::DateTime, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::DateTime)
27
36
  RDF::Literal(operand.object.hour)
28
37
  end
38
+
39
+ ##
40
+ #
41
+ # Returns a partial SPARQL grammar for this operator.
42
+ #
43
+ # @return [String]
44
+ def to_sparql(**options)
45
+ "HOURS(#{operands.last.to_sparql(**options)})"
46
+ end
29
47
  end # Hours
30
48
  end # Operator
31
49
  end; end # SPARQL::Algebra
@@ -3,7 +3,15 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `if` function.
5
5
  #
6
- # @example
6
+ # [121] BuiltInCall ::= ... | 'IF' '(' Expression ',' Expression ',' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # BASE <http://example.org/>
10
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
11
+ # SELECT ?o (IF(lang(?o) = "ja", true, false) AS ?integer)
12
+ # WHERE { ?s ?p ?o }
13
+ #
14
+ # @example SSE
7
15
  # (base <http://example.org/>
8
16
  # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>))
9
17
  # (project (?o ?integer)
@@ -37,8 +45,17 @@ module SPARQL; module Algebra
37
45
  operand(0).evaluate(bindings, depth: options[:depth].to_i + 1, **options) == RDF::Literal::TRUE ?
38
46
  operand(1).evaluate(bindings, depth: options[:depth].to_i + 1, **options) :
39
47
  operand(2).evaluate(bindings, depth: options[:depth].to_i + 1, **options)
40
- rescue
41
- raise TypeError
48
+ rescue
49
+ raise TypeError
50
+ end
51
+
52
+ ##
53
+ #
54
+ # Returns a partial SPARQL grammar for this operator.
55
+ #
56
+ # @return [String]
57
+ def to_sparql(**options)
58
+ "IF(" + operands.to_sparql(delimiter: ', ', **options) + ")"
42
59
  end
43
60
  end # If
44
61
  end # Operator
@@ -3,7 +3,12 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `in` operator.
5
5
  #
6
- # @example
6
+ # [114] RelationalExpression ::= NumericExpression ('IN' ExpressionList)?
7
+ #
8
+ # @example SPARQL Grammar
9
+ # ASK { FILTER(2 IN (1, 2, 3)) }
10
+ #
11
+ # @example SSE
7
12
  # (ask (filter (in 2 1 2 3) (bgp)))
8
13
  #
9
14
  # @see https://www.w3.org/TR/sparql11-query/#func-in
@@ -54,6 +59,18 @@ module SPARQL; module Algebra
54
59
  else RDF::Literal::FALSE
55
60
  end
56
61
  end
62
+
63
+ ##
64
+ #
65
+ # Returns a partial SPARQL grammar for this operator.
66
+ #
67
+ # @return [String]
68
+ def to_sparql(**options)
69
+ "(" + operands.first.to_sparql(**options) +
70
+ " IN (" +
71
+ operands[1..-1].map {|e| e.to_sparql(**options)}.join(", ") +
72
+ "))"
73
+ end
57
74
  end # In
58
75
  end # Operator
59
76
  end; end # SPARQL::Algebra
@@ -6,8 +6,19 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # The INSERT operation is a form of the DELETE/INSERT operation having no DELETE section
8
8
  #
9
- # @example
10
- # (insert ((triple ?s ?p "q")))
9
+ # [43] InsertClause ::= 'INSERT' QuadPattern
10
+ #
11
+ # @example SPARQL Grammar
12
+ # PREFIX : <http://example.org/>
13
+ # INSERT { ?s ?p "q" }
14
+ # WHERE { ?s ?p ?o }
15
+ #
16
+ # @example SSE
17
+ # (prefix
18
+ # ((: <http://example.org/>))
19
+ # (update
20
+ # (modify (bgp (triple ?s ?p ?o))
21
+ # (insert ((triple ?s ?p "q"))))))
11
22
  #
12
23
  # @see https://www.w3.org/TR/sparql11-update/#insert
13
24
  class Insert < Operator::Unary
@@ -51,6 +62,17 @@ module SPARQL; module Algebra
51
62
  end
52
63
  queryable
53
64
  end
65
+
66
+ ##
67
+ #
68
+ # Returns a partial SPARQL grammar for this term.
69
+ #
70
+ # @return [String]
71
+ def to_sparql(**options)
72
+ "INSERT {\n" +
73
+ operands.first.to_sparql(as_statement: true, delimiter: " .\n", **options) +
74
+ "\n}"
75
+ end
54
76
  end # Insert
55
77
  end # Operator
56
78
  end; end # SPARQL::Algebra
@@ -6,8 +6,18 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # The INSERT DATA operation adds some triples, given inline in the request, into the Graph Store
8
8
  #
9
- # @example
10
- # (insertData ((graph <http://example.org/g1> ((triple :s :p :o)))))
9
+ # [38] InsertData ::= 'INSERT DATA' QuadData
10
+ #
11
+ # @example SPARQL Grammar
12
+ # PREFIX : <http://example.org/ns#>
13
+ # INSERT DATA { GRAPH <http://example.org/g1> { :s :p :o } }
14
+ #
15
+ # @example SSE
16
+ # (prefix
17
+ # ((: <http://example.org/ns#>))
18
+ # (update
19
+ # (insertData (
20
+ # (graph <http://example.org/g1> ((triple :s :p :o)))))))
11
21
  #
12
22
  # @see https://www.w3.org/TR/sparql11-update/#insertData
13
23
  class InsertData < Operator::Unary
@@ -36,6 +46,17 @@ module SPARQL; module Algebra
36
46
  end
37
47
  queryable
38
48
  end
49
+
50
+ ##
51
+ #
52
+ # Returns a partial SPARQL grammar for this term.
53
+ #
54
+ # @return [String]
55
+ def to_sparql(**options)
56
+ "INSERT DATA {\n" +
57
+ operands.first.to_sparql(as_statement: true, top_level: false, delimiter: ". \n", **options) +
58
+ "\n}"
59
+ end
39
60
  end # InsertData
40
61
  end # Operator
41
62
  end; end # SPARQL::Algebra
@@ -3,10 +3,18 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `iri` operator.
5
5
  #
6
- # @example
7
- # (base <http://example.org/> (project (?uri ?iri)
8
- # (extend ((?uri (uri "uri")) (?iri (iri "iri")))
9
- # (bgp))))
6
+ # [121] BuiltInCall ::= ... | 'IRI' '(' Expression ')' | 'URI' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # BASE <http://example.org/>
10
+ # SELECT (URI("uri") AS ?uri) (IRI("iri") AS ?iri)
11
+ # WHERE {}
12
+ #
13
+ # @example SSE
14
+ # (base <http://example.org/>
15
+ # (project (?uri ?iri)
16
+ # (extend ((?uri (iri "uri")) (?iri (iri "iri")))
17
+ # (bgp))))
10
18
  #
11
19
  # @see https://www.w3.org/TR/sparql11-query/#func-iri
12
20
  class IRI < Operator::Unary
@@ -29,12 +37,21 @@ module SPARQL; module Algebra
29
37
  # a simple literal
30
38
  # @return [RDF::URI]
31
39
  # @raise [TypeError] if the operand is not a simple literal
32
- def apply(literal)
40
+ def apply(literal, **options)
33
41
  raise TypeError, "expected an simple literal, but got #{literal.inspect}" unless literal.literal? && literal.simple?
34
42
  base = Operator.base_uri || RDF::URI("")
35
43
  base.join(literal.to_s)
36
44
  end
37
45
 
46
+ ##
47
+ #
48
+ # Returns a partial SPARQL grammar for this operator.
49
+ #
50
+ # @return [String]
51
+ def to_sparql(**options)
52
+ "IRI(" + operands.last.to_sparql(**options) + ")"
53
+ end
54
+
38
55
  Operator::URI = IRI
39
56
  end # IRI
40
57
  end # Operator
@@ -3,9 +3,17 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `isBlank` operator.
5
5
  #
6
- # @example
7
- # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
8
- # (: <http://example.org/things#>))
6
+ # [121] BuiltInCall ::= ... | 'isBlank' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/things#>
10
+ # SELECT ?x ?v WHERE {
11
+ # ?x :p ?v .
12
+ # FILTER isBlank(?v) .
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/things#>))
9
17
  # (project (?x ?v)
10
18
  # (filter (isBlank ?v)
11
19
  # (bgp (triple ?x :p ?v)))))
@@ -23,13 +31,22 @@ module SPARQL; module Algebra
23
31
  # an RDF term
24
32
  # @return [RDF::Literal::Boolean] `true` or `false`
25
33
  # @raise [TypeError] if the operand is not an RDF term
26
- def apply(term)
34
+ def apply(term, **options)
27
35
  case term
28
36
  when RDF::Node then RDF::Literal::TRUE
29
37
  when RDF::Term then RDF::Literal::FALSE
30
38
  else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
31
39
  end
32
40
  end
41
+
42
+ ##
43
+ #
44
+ # Returns a partial SPARQL grammar for this operator.
45
+ #
46
+ # @return [String]
47
+ def to_sparql(**options)
48
+ "isBlank(" + operands.first.to_sparql(**options) + ")"
49
+ end
33
50
  end # IsBlank
34
51
  end # Operator
35
52
  end; end # SPARQL::Algebra
@@ -3,9 +3,17 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `isIRI`/`isURI` operator.
5
5
  #
6
- # @example
7
- # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
8
- # (: <http://example.org/things#>))
6
+ # [121] BuiltInCall ::= ... | 'isIRI' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/things#>
10
+ # SELECT ?x ?v WHERE {
11
+ # ?x :p ?v .
12
+ # FILTER isIRI(?v) .
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/things#>))
9
17
  # (project (?x ?v)
10
18
  # (filter (isIRI ?v)
11
19
  # (bgp (triple ?x :p ?v)))))
@@ -23,7 +31,7 @@ module SPARQL; module Algebra
23
31
  # an RDF term
24
32
  # @return [RDF::Literal::Boolean] `true` or `false`
25
33
  # @raise [TypeError] if the operand is not an RDF term
26
- def apply(term)
34
+ def apply(term, **options)
27
35
  case term
28
36
  when RDF::URI then RDF::Literal::TRUE
29
37
  when RDF::Term then RDF::Literal::FALSE
@@ -32,6 +40,15 @@ module SPARQL; module Algebra
32
40
  end
33
41
 
34
42
  Operator::IsURI = IsIRI
43
+
44
+ ##
45
+ #
46
+ # Returns a partial SPARQL grammar for this operator.
47
+ #
48
+ # @return [String]
49
+ def to_sparql(**options)
50
+ "isIRI(" + operands.first.to_sparql(**options) + ")"
51
+ end
35
52
  end # IsIRI
36
53
  end # Operator
37
54
  end; end # SPARQL::Algebra
@@ -3,9 +3,17 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `isLiteral` operator.
5
5
  #
6
- # @example
7
- # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
8
- # (: <http://example.org/things#>))
6
+ # [121] BuiltInCall ::= ... | 'isLiteral' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example.org/things#>
10
+ # SELECT ?x ?v WHERE {
11
+ # ?x :p ?v .
12
+ # FILTER isLiteral(?v) .
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/things#>))
9
17
  # (project (?x ?v)
10
18
  # (filter (isLiteral ?v)
11
19
  # (bgp (triple ?x :p ?v)))))
@@ -24,13 +32,22 @@ module SPARQL; module Algebra
24
32
  # an RDF term
25
33
  # @return [RDF::Literal::Boolean] `true` or `false`
26
34
  # @raise [TypeError] if the operand is not an RDF term
27
- def apply(term)
35
+ def apply(term, **options)
28
36
  case term
29
37
  when RDF::Literal then RDF::Literal::TRUE
30
38
  when RDF::Term then RDF::Literal::FALSE
31
39
  else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
32
40
  end
33
41
  end
42
+
43
+ ##
44
+ #
45
+ # Returns a partial SPARQL grammar for this operator.
46
+ #
47
+ # @return [String]
48
+ def to_sparql(**options)
49
+ "isLiteral(" + operands.first.to_sparql(**options) + ")"
50
+ end
34
51
  end # IsLiteral
35
52
  end # Operator
36
53
  end; end # SPARQL::Algebra
@@ -3,11 +3,19 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `isNumeric` operator.
5
5
  #
6
- # Note numeric denotes typed literals with datatypes xsd:integer, xsd:decimal, xsd:float, and xsd:double, not derived types.
6
+ # Note numeric denotes typed literals with datatypes `xsd:integer`, `xsd:decimal`, `xsd:float`, and `xsd:double`, not derived types.
7
7
  #
8
- # @example
9
- # (prefix ((xsd: <http://www.w3.org/2001/XMLSchema#>)
10
- # (: <http://example.org/things#>))
8
+ # [121] BuiltInCall ::= ... | 'isNumeric' '(' Expression ')'
9
+ #
10
+ # @example SPARQL Grammar
11
+ # PREFIX : <http://example.org/things#>
12
+ # SELECT ?x ?v WHERE {
13
+ # ?x :p ?v .
14
+ # FILTER isNumeric(?v) .
15
+ # }
16
+ #
17
+ # @example SSE
18
+ # (prefix ((: <http://example.org/things#>))
11
19
  # (project (?x ?v)
12
20
  # (filter (isNumeric ?v)
13
21
  # (bgp (triple ?x :p ?v)))))
@@ -16,7 +24,7 @@ module SPARQL; module Algebra
16
24
  class IsNumeric < Operator::Unary
17
25
  include Evaluatable
18
26
 
19
- NAME = :isnumeric
27
+ NAME = :isNumeric
20
28
 
21
29
  ##
22
30
  # Returns `true` if the operand is an `RDF::Literal::Numeric`, `false`
@@ -26,7 +34,7 @@ module SPARQL; module Algebra
26
34
  # an RDF term
27
35
  # @return [RDF::Literal::Boolean] `true` or `false`
28
36
  # @raise [TypeError] if the operand is not an RDF term
29
- def apply(term)
37
+ def apply(term, **options)
30
38
  case term
31
39
  when RDF::Literal::NonPositiveInteger then RDF::Literal::FALSE
32
40
  when RDF::Literal::NonNegativeInteger then RDF::Literal::FALSE
@@ -36,6 +44,15 @@ module SPARQL; module Algebra
36
44
  else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
37
45
  end
38
46
  end
47
+
48
+ ##
49
+ #
50
+ # Returns a partial SPARQL grammar for this operator.
51
+ #
52
+ # @return [String]
53
+ def to_sparql(**options)
54
+ "isNumeric(" + operands.first.to_sparql(**options) + ")"
55
+ end
39
56
  end # IsNumeric
40
57
  end # Operator
41
58
  end; end # SPARQL::Algebra
@@ -5,6 +5,29 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Returns true if term is an RDF-star triple. Returns false otherwise.
7
7
  #
8
+ # [121] BuiltInCall ::= ... | 'isTreiple' '(' 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#istriple
9
32
  class IsTriple < Operator::Unary
10
33
  include Evaluatable
@@ -18,13 +41,22 @@ module SPARQL; module Algebra
18
41
  # an RDF term
19
42
  # @return [RDF::Literal::Boolean] `true` or `false`
20
43
  # @raise [TypeError] if the operand is not an RDF term
21
- def apply(term)
44
+ def apply(term, **options)
22
45
  case term
23
46
  when RDF::Statement then RDF::Literal::TRUE
24
47
  when RDF::Term then RDF::Literal::FALSE
25
48
  else raise TypeError, "expected an RDF::Term, but got #{term.inspect}"
26
49
  end
27
50
  end
51
+
52
+ ##
53
+ #
54
+ # Returns a partial SPARQL grammar for this operator.
55
+ #
56
+ # @return [String]
57
+ def to_sparql(**options)
58
+ "isTRIPLE(" + operands.first.to_sparql(**options) + ")"
59
+ end
28
60
  end # IsTriple
29
61
  end # Operator
30
62
  end; end # SPARQL::Algebra
@@ -3,13 +3,38 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `join` operator.
5
5
  #
6
- # @example
6
+ # [54] GroupGraphPatternSub ::= TriplesBlock? (GraphPatternNotTriples "."? TriplesBlock? )*
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example/>
10
+ # SELECT * {
11
+ # ?s ?p ?o
12
+ # GRAPH ?g { ?s ?q ?v }
13
+ # }
14
+ #
15
+ # @example SSE
7
16
  # (prefix ((: <http://example/>))
8
17
  # (join
9
18
  # (bgp (triple ?s ?p ?o))
10
19
  # (graph ?g
11
20
  # (bgp (triple ?s ?q ?v)))))
12
21
  #
22
+ # @example SPARQL Grammar (inline filter)
23
+ # PREFIX : <http://xmlns.com/foaf/0.1/>
24
+ # ASK {
25
+ # :who :homepage ?homepage
26
+ # FILTER REGEX(?homepage, "^http://example.org/")
27
+ # :who :schoolHomepage ?schoolPage
28
+ # }
29
+ #
30
+ # @example SSE (inline filter)
31
+ # (prefix ((: <http://xmlns.com/foaf/0.1/>))
32
+ # (ask
33
+ # (filter (regex ?homepage "^http://example.org/")
34
+ # (join
35
+ # (bgp (triple :who :homepage ?homepage))
36
+ # (bgp (triple :who :schoolHomepage ?schoolPage))))))
37
+ #
13
38
  # @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
14
39
  class Join < Operator::Binary
15
40
  include Query
@@ -82,6 +107,36 @@ module SPARQL; module Algebra
82
107
  @operands = ops
83
108
  self
84
109
  end
110
+
111
+ ##
112
+ #
113
+ # Returns a partial SPARQL grammar for this operator.
114
+ #
115
+ # @param [Boolean] top_level (true)
116
+ # Treat this as a top-level, generating SELECT ... WHERE {}
117
+ # @param [Hash{Symbol => Operator}] extensions
118
+ # Variable bindings
119
+ # @param [Array<Operator>] filter_ops ([])
120
+ # Filter Operations
121
+ # @return [String]
122
+ def to_sparql(top_level: true, filter_ops: [], extensions: {}, **options)
123
+ # If this is top-level, and the last operand is a Table (values), put the values at the outer-level
124
+ str = "{\n" + operands.first.to_sparql(top_level: false, extensions: {}, **options)
125
+
126
+ # Any accrued filters go here.
127
+ filter_ops.each do |op|
128
+ str << "\nFILTER (#{op.to_sparql(**options)}) ."
129
+ end
130
+
131
+ if top_level && operands.last.is_a?(Table)
132
+ str << "\n}"
133
+ options = options.merge(values_clause: operands.last)
134
+ else
135
+ str << "\n{\n" + operands.last.to_sparql(top_level: false, extensions: {}, **options) + "\n}\n}"
136
+ end
137
+
138
+ top_level ? Operator.to_sparql(str, extensions: extensions, **options) : str
139
+ end
85
140
  end # Join
86
141
  end # Operator
87
142
  end; end # SPARQL::Algebra
@@ -3,6 +3,22 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `lang` operator.
5
5
  #
6
+ # [121] BuiltInCall ::= ... | 'LANG' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example/>
10
+ #
11
+ # SELECT ?x
12
+ # { ?x :p ?v .
13
+ # FILTER ( lang(?v) != '@NotALangTag@' )
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix ((: <http://example/>))
18
+ # (project (?x)
19
+ # (filter (!= (lang ?v) "@NotALangTag@")
20
+ # (bgp (triple ?x :p ?v)))))
21
+ #
6
22
  # @see https://www.w3.org/TR/sparql11-query/#func-lang
7
23
  class Lang < Operator::Unary
8
24
  include Evaluatable
@@ -18,12 +34,21 @@ module SPARQL; module Algebra
18
34
  # a literal
19
35
  # @return [RDF::Literal] a simple literal
20
36
  # @raise [TypeError] if the operand is not a literal
21
- def apply(literal)
37
+ def apply(literal, **options)
22
38
  case literal
23
39
  when RDF::Literal then RDF::Literal(literal.language.to_s)
24
40
  else raise TypeError, "expected an RDF::Literal, but got #{literal.inspect}"
25
41
  end
26
42
  end
43
+
44
+ ##
45
+ #
46
+ # Returns a partial SPARQL grammar for this operator.
47
+ #
48
+ # @return [String]
49
+ def to_sparql(**options)
50
+ "lang(" + operands.first.to_sparql(**options) + ")"
51
+ end
27
52
  end # Lang
28
53
  end # Operator
29
54
  end; end # SPARQL::Algebra