sparql 1.0.6 → 1.0.7
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.
- data/README.md +11 -4
- data/VERSION +1 -1
- data/lib/sparql/algebra/extensions.rb +36 -0
- data/lib/sparql/algebra/operator.rb +197 -87
- data/lib/sparql/algebra/operator/abs.rb +31 -0
- data/lib/sparql/algebra/operator/base.rb +1 -0
- data/lib/sparql/algebra/operator/bnode.rb +88 -0
- data/lib/sparql/algebra/operator/bound.rb +2 -1
- data/lib/sparql/algebra/operator/ceil.rb +31 -0
- data/lib/sparql/algebra/operator/coalesce.rb +65 -0
- data/lib/sparql/algebra/operator/concat.rb +49 -0
- data/lib/sparql/algebra/operator/contains.rb +44 -0
- data/lib/sparql/algebra/operator/dataset.rb +11 -48
- data/lib/sparql/algebra/operator/datatype.rb +4 -2
- data/lib/sparql/algebra/operator/day.rb +31 -0
- data/lib/sparql/algebra/operator/encode_for_uri.rb +38 -0
- data/lib/sparql/algebra/operator/extend.rb +31 -2
- data/lib/sparql/algebra/operator/floor.rb +33 -0
- data/lib/sparql/algebra/operator/hours.rb +31 -0
- data/lib/sparql/algebra/operator/if.rb +55 -0
- data/lib/sparql/algebra/operator/in.rb +68 -0
- data/lib/sparql/algebra/operator/iri.rb +40 -0
- data/lib/sparql/algebra/operator/is_numeric.rb +41 -0
- data/lib/sparql/algebra/operator/lang_matches.rb +2 -2
- data/lib/sparql/algebra/operator/lcase.rb +31 -0
- data/lib/sparql/algebra/operator/md5.rb +34 -0
- data/lib/sparql/algebra/operator/minutes.rb +31 -0
- data/lib/sparql/algebra/operator/month.rb +31 -0
- data/lib/sparql/algebra/operator/not.rb +2 -2
- data/lib/sparql/algebra/operator/notin.rb +70 -0
- data/lib/sparql/algebra/operator/now.rb +29 -0
- data/lib/sparql/algebra/operator/order.rb +9 -13
- data/lib/sparql/algebra/operator/rand.rb +24 -0
- data/lib/sparql/algebra/operator/replace.rb +81 -0
- data/lib/sparql/algebra/operator/round.rb +31 -0
- data/lib/sparql/algebra/operator/seconds.rb +31 -0
- data/lib/sparql/algebra/operator/sha1.rb +34 -0
- data/lib/sparql/algebra/operator/sha256.rb +34 -0
- data/lib/sparql/algebra/operator/sha384.rb +34 -0
- data/lib/sparql/algebra/operator/sha512.rb +34 -0
- data/lib/sparql/algebra/operator/strafter.rb +57 -0
- data/lib/sparql/algebra/operator/strbefore.rb +59 -0
- data/lib/sparql/algebra/operator/strdt.rb +33 -0
- data/lib/sparql/algebra/operator/strends.rb +46 -0
- data/lib/sparql/algebra/operator/strlang.rb +34 -0
- data/lib/sparql/algebra/operator/strlen.rb +34 -0
- data/lib/sparql/algebra/operator/strstarts.rb +46 -0
- data/lib/sparql/algebra/operator/struuid.rb +32 -0
- data/lib/sparql/algebra/operator/substr.rb +80 -0
- data/lib/sparql/algebra/operator/timezone.rb +34 -0
- data/lib/sparql/algebra/operator/tz.rb +31 -0
- data/lib/sparql/algebra/operator/ucase.rb +31 -0
- data/lib/sparql/algebra/operator/uuid.rb +32 -0
- data/lib/sparql/algebra/operator/year.rb +31 -0
- data/lib/sparql/grammar/parser11.rb +128 -70
- data/lib/sparql/grammar/terminals11.rb +4 -5
- metadata +62 -7
@@ -0,0 +1,31 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL logical `abs` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (abs ?x)
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-abs
|
10
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-abs
|
11
|
+
class Abs < Operator::Unary
|
12
|
+
include Evaluatable
|
13
|
+
|
14
|
+
NAME = [:abs]
|
15
|
+
|
16
|
+
##
|
17
|
+
# Returns the absolute value of the operand. An error is raised if operand is not a numeric value
|
18
|
+
#
|
19
|
+
# @param [RDF::Literal] operand
|
20
|
+
# the operand
|
21
|
+
# @return [RDF::Literal] literal of same type
|
22
|
+
# @raise [TypeError] if the operand is not a numeric value
|
23
|
+
def apply(operand)
|
24
|
+
case operand
|
25
|
+
when RDF::Literal::Numeric then operand.abs
|
26
|
+
else raise TypeError, "expected an RDF::Literal::Numeric, but got #{operand.inspect}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end # Abs
|
30
|
+
end # Operator
|
31
|
+
end; end # SPARQL::Algebra
|
@@ -27,6 +27,7 @@ module SPARQL; module Algebra
|
|
27
27
|
# @see http://www.w3.org/TR/rdf-sparql-query/#sparqlAlgebra
|
28
28
|
def execute(queryable, options = {})
|
29
29
|
debug(options) {"Base #{operands.first}"}
|
30
|
+
Operator.base_uri = operands.first
|
30
31
|
@solutions = operands.last.execute(queryable, options.merge(:depth => options[:depth].to_i + 1))
|
31
32
|
debug(options) {"=> #{@solutions.inspect}"}
|
32
33
|
@solutions
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL `bnode` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (prefix ((: <http://example.org/>)
|
8
|
+
# (xsd: <http://www.w3.org/2001/XMLSchema#>))
|
9
|
+
# (project (?s1 ?s2 ?b1 ?b2)
|
10
|
+
# (extend ((?b1 (bnode ?s1)) (?b2 (bnode ?s2)))
|
11
|
+
# (filter (exprlist (|| (= ?a :s1) (= ?a :s3)) (|| (= ?b :s1) (= ?b :s3)))
|
12
|
+
# (bgp
|
13
|
+
# (triple ?a :str ?s1)
|
14
|
+
# (triple ?b :str ?s2)
|
15
|
+
# )))))
|
16
|
+
#
|
17
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-bnode
|
18
|
+
class BNode < Operator::Unary
|
19
|
+
include Evaluatable
|
20
|
+
|
21
|
+
NAME = :bnode
|
22
|
+
|
23
|
+
|
24
|
+
##
|
25
|
+
# Initializes a new operator instance.
|
26
|
+
#
|
27
|
+
# @param [RDF::Literal] literal (false)
|
28
|
+
# @param [Hash{Symbol => Object}] options
|
29
|
+
# any additional options (see {Operator#initialize})
|
30
|
+
# @raise [TypeError] if any operand is invalid
|
31
|
+
def initialize(literal = false, options = {})
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Evaluates this operator using the given variable `bindings`.
|
37
|
+
#
|
38
|
+
# @param [RDF::Query::Solution, #[]] bindings
|
39
|
+
# a query solution containing zero or more variable bindings
|
40
|
+
# @return [RDF::Term]
|
41
|
+
# @abstract
|
42
|
+
def evaluate(bindings = {})
|
43
|
+
args = operands.map { |operand| operand.evaluate(bindings) }
|
44
|
+
apply(args.first, bindings)
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# The BNODE function constructs a blank node that is distinct from all blank nodes in the dataset being queried and distinct from all blank nodes created by calls to this constructor for other query solutions. If the no argument form is used, every call results in a distinct blank node. If the form with a simple literal is used, every call results in distinct blank nodes for different simple literals, and the same blank node for calls with the same simple literal within expressions for one solution mapping.
|
49
|
+
#
|
50
|
+
# This functionality is compatible with the treatment of blank nodes in SPARQL CONSTRUCT templates.
|
51
|
+
#
|
52
|
+
# @param [RDF::Literal] literal (nil)
|
53
|
+
# @param [RDF::Query::Solution, #[]] bindings
|
54
|
+
# a query solution containing zero or more variable bindings
|
55
|
+
# @return [RDF::Node]
|
56
|
+
# @raise [TypeError] if the operand is not a simple literal or nil
|
57
|
+
def apply(literal, bindings)
|
58
|
+
@@bnode_base ||= "b0"
|
59
|
+
@@bindings ||= bindings
|
60
|
+
@@bnodes ||= {}
|
61
|
+
|
62
|
+
if literal == RDF::Literal::FALSE
|
63
|
+
l, @@bnode_base = @@bnode_base, @@bnode_base.succ
|
64
|
+
RDF::Node.new(l)
|
65
|
+
else
|
66
|
+
raise TypeError, "expected an simple literal, but got #{literal.inspect}" unless literal.literal? && literal.simple?
|
67
|
+
# Return the same BNode if used with the same binding
|
68
|
+
@@bnodes, @@bindings = {}, bindings unless @@bindings == bindings
|
69
|
+
@@bnodes[literal.to_s.to_sym] ||= begin
|
70
|
+
l, @@bnode_base = @@bnode_base, @@bnode_base.succ
|
71
|
+
RDF::Node.new(l)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Returns the SPARQL S-Expression (SSE) representation of this expression.
|
78
|
+
#
|
79
|
+
# Remove the optional argument.
|
80
|
+
#
|
81
|
+
# @return [Array] `self`
|
82
|
+
# @see http://openjena.org/wiki/SSE
|
83
|
+
def to_sxp_bin
|
84
|
+
[NAME] + operands.reject {|o| o == false}
|
85
|
+
end
|
86
|
+
end # BNode
|
87
|
+
end # Operator
|
88
|
+
end; end # SPARQL::Algebra
|
@@ -39,7 +39,8 @@ module SPARQL; module Algebra
|
|
39
39
|
def evaluate(bindings = {})
|
40
40
|
case var = operand
|
41
41
|
when Variable
|
42
|
-
|
42
|
+
bindings.respond_to?(:bound?) && bindings.bound?(var) ?
|
43
|
+
RDF::Literal::TRUE : RDF::Literal::FALSE
|
43
44
|
else raise TypeError, "expected an RDF::Query::Variable, but got #{var.inspect}"
|
44
45
|
end
|
45
46
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL logical `ceil` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (ceil ?x)
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-ceil
|
10
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-ceil
|
11
|
+
class Ceil < Operator::Unary
|
12
|
+
include Evaluatable
|
13
|
+
|
14
|
+
NAME = [:ceil]
|
15
|
+
|
16
|
+
##
|
17
|
+
# Returns the smallest (closest to negative infinity) number with no fractional part that is not less than the value of arg. An error is raised if arg is not a numeric value.
|
18
|
+
#
|
19
|
+
# @param [RDF::Literal] operand
|
20
|
+
# the operand
|
21
|
+
# @return [RDF::Literal] literal of same type
|
22
|
+
# @raise [TypeError] if the operand is not a numeric value
|
23
|
+
def apply(operand)
|
24
|
+
case operand
|
25
|
+
when RDF::Literal::Numeric then operand.ceil
|
26
|
+
else raise TypeError, "expected an RDF::Literal::Numeric, but got #{operand.inspect}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end # Ceil
|
30
|
+
end # Operator
|
31
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL `coalesce` function.
|
5
|
+
#
|
6
|
+
# Used for filters with more than one expression.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# (prefix ((: <http://example.org/>)
|
10
|
+
# (xsd: <http://www.w3.org/2001/XMLSchema#>))
|
11
|
+
# (project (?cx ?div ?def ?err)
|
12
|
+
# (extend ((?cx (coalesce ?x -1))
|
13
|
+
# (?div (coalesce (/ ?o ?x) -2))
|
14
|
+
# (?def (coalesce ?z -3))
|
15
|
+
# (?err (coalesce ?z)))
|
16
|
+
# (leftjoin
|
17
|
+
# (bgp (triple ?s :p ?o))
|
18
|
+
# (bgp (triple ?s :q ?x))))))
|
19
|
+
#
|
20
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-coalesce
|
21
|
+
class Coalesce < Operator
|
22
|
+
include Evaluatable
|
23
|
+
|
24
|
+
NAME = :coalesce
|
25
|
+
|
26
|
+
##
|
27
|
+
# The COALESCE function form returns the RDF term value of the first expression that evaluates without error. In SPARQL, evaluating an unbound variable raises an error.
|
28
|
+
#
|
29
|
+
# If none of the arguments evaluates to an RDF term, an error is raised. If no expressions are evaluated without error, an error is raised.
|
30
|
+
#
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# Suppose ?x = 2 and ?y is not bound in some query solution:
|
34
|
+
#
|
35
|
+
# COALESCE(?x, 1/0) #=> 2, the value of x
|
36
|
+
# COALESCE(1/0, ?x) #=> 2
|
37
|
+
# COALESCE(5, ?x) #=> 5
|
38
|
+
# COALESCE(?y, 3) #=> 3
|
39
|
+
# COALESCE(?y) #=> raises an error because y is not bound.
|
40
|
+
#
|
41
|
+
# @param [RDF::Query::Solution, #[]] bindings
|
42
|
+
# @return [RDF::Term]
|
43
|
+
# @raise [TypeError] if none of the operands succeeds
|
44
|
+
def evaluate(bindings = {})
|
45
|
+
operands.each do |op|
|
46
|
+
begin
|
47
|
+
return op.evaluate(bindings)
|
48
|
+
rescue
|
49
|
+
end
|
50
|
+
end
|
51
|
+
raise TypeError, "None of the operands evaluated"
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Returns an optimized version of this query.
|
56
|
+
#
|
57
|
+
# Return optimized query
|
58
|
+
#
|
59
|
+
# @return [Union, RDF::Query] `self`
|
60
|
+
def optimize
|
61
|
+
operands = operands.map(&:optimize)
|
62
|
+
end
|
63
|
+
end # Coalesce
|
64
|
+
end # Operator
|
65
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# A SPARQL `concat` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (concat ?a ?b)
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-concat
|
10
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-concat
|
11
|
+
class Concat < Operator::Binary
|
12
|
+
include Evaluatable
|
13
|
+
|
14
|
+
NAME = :concat
|
15
|
+
|
16
|
+
##
|
17
|
+
# The lexical form of the returned literal is obtained by concatenating the lexical forms of its inputs. If all input literals are typed literals of type xsd:string, then the returned literal is also of type xsd:string, if all input literals are plain literals with identical language tag, then the returned literal is a plain literal with the same language tag, in all other cases, the returned literal is a simple literal.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# concat("foo", "bar") #=> "foobar"
|
21
|
+
# concat("foo"@en, "bar"@en) #=> "foobar"@en
|
22
|
+
# concat("foo"^^xsd:string, "bar"^^xsd:string) #=> "foobar"^^xsd:string
|
23
|
+
# concat("foo", "bar"^^xsd:string) #=> "foobar"
|
24
|
+
# concat("foo"@en, "bar") #=> "foobar"
|
25
|
+
# concat("foo"@en, "bar"^^xsd:string) #=> "foobar"
|
26
|
+
#
|
27
|
+
# @param [RDF::Literal] left
|
28
|
+
# a literal
|
29
|
+
# @param [RDF::Literal] right
|
30
|
+
# a literal
|
31
|
+
# @return [RDF::Literal]
|
32
|
+
# @raise [TypeError] if either operand is not a literal
|
33
|
+
def apply(left, right)
|
34
|
+
case
|
35
|
+
when !left.literal? || !right.literal?
|
36
|
+
raise TypeError, "expected two plain literal operands, but got #{left.inspect} and #{right.inspect}"
|
37
|
+
when ![left.datatype, right.datatype].compact.all? {|dt| dt == RDF::XSD.string}
|
38
|
+
raise TypeError, "expected two plain literal operands, but got #{left.inspect} and #{right.inspect}"
|
39
|
+
when left.datatype == RDF::XSD.string && right.datatype == RDF::XSD.string
|
40
|
+
RDF::Literal.new("#{left}#{right}", :datatype => RDF::XSD.string)
|
41
|
+
when left.has_language? && left.language == right.language
|
42
|
+
RDF::Literal.new("#{left}#{right}", :language => left.language)
|
43
|
+
else
|
44
|
+
RDF::Literal.new("#{left}#{right}")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end # Concat
|
48
|
+
end # Operator
|
49
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# A SPARQL `contains` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (contains ?x ?y)
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-contains
|
10
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-contains
|
11
|
+
class Contains < Operator::Binary
|
12
|
+
include Evaluatable
|
13
|
+
|
14
|
+
NAME = :contains
|
15
|
+
|
16
|
+
##
|
17
|
+
# The CONTAINS function corresponds to the XPath fn:contains. The arguments must be argument compatible otherwise an error is raised.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# contains("foobar", "bar") #=> true
|
21
|
+
# contains("foobar"@en, "foo"@en) #=> true
|
22
|
+
# contains("foobar"^^xsd:string, "bar"^^xsd:string) #=> true
|
23
|
+
# contains("foobar"^^xsd:string, "foo") #=> true
|
24
|
+
# contains("foobar", "bar"^^xsd:string) #=> true
|
25
|
+
# contains("foobar"@en, "foo") #=> true
|
26
|
+
# contains("foobar"@en, "bar"^^xsd:string) #=> true
|
27
|
+
#
|
28
|
+
# @param [RDF::Literal] left
|
29
|
+
# a literal
|
30
|
+
# @param [RDF::Literal] right
|
31
|
+
# a literal
|
32
|
+
# @return [RDF::Literal::Boolean]
|
33
|
+
# @raise [TypeError] if operands are not compatible
|
34
|
+
def apply(left, right)
|
35
|
+
case
|
36
|
+
when !left.compatible?(right)
|
37
|
+
raise TypeError, "expected two RDF::Literal operands, but got #{left.inspect} and #{right.inspect}"
|
38
|
+
when left.to_s.include?(right.to_s) then RDF::Literal::TRUE
|
39
|
+
else RDF::Literal::FALSE
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end # Contains
|
43
|
+
end # Operator
|
44
|
+
end; end # SPARQL::Algebra
|
@@ -3,9 +3,8 @@ begin
|
|
3
3
|
rescue LoadError => e
|
4
4
|
require 'rdf/ntriples'
|
5
5
|
end
|
6
|
+
require 'rdf/aggregate_repo'
|
6
7
|
|
7
|
-
# FIXME: This version uses named graphs for default graphs, which violates the condition in RDF::Repository#query_pattern, where it specifically does not match variables against the default graph. To work properly, RDF.rb will need to allow some way to specify a set of graphs as being default, and affect the matching within #query_pattern so that variables don't match against this.
|
8
|
-
# Note that a graph may be both default and named, so the context of the query is significant.
|
9
8
|
module SPARQL; module Algebra
|
10
9
|
class Operator
|
11
10
|
##
|
@@ -168,53 +167,17 @@ module SPARQL; module Algebra
|
|
168
167
|
queryable.load(uri.to_s, load_opts)
|
169
168
|
end
|
170
169
|
end
|
171
|
-
|
172
|
-
|
170
|
+
debug(options) {
|
171
|
+
require 'rdf/nquads'
|
172
|
+
queryable.dump(:nquads)
|
173
|
+
}
|
173
174
|
|
174
|
-
#
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
# operations.
|
181
|
-
debug(options) {"=> #{op.to_sxp} => (bgp)"}
|
182
|
-
Operator::BGP.new
|
183
|
-
elsif (name = op.operand(0)).is_a?(RDF::Resource)
|
184
|
-
# It must match one of the named_datasets
|
185
|
-
debug(options) {"=> #{op.to_sxp} => (bgp)"}
|
186
|
-
named_datasets.include?(name) ? op : Operator::BGP.new
|
187
|
-
else
|
188
|
-
# Name is a variable, replace op with a filter on that
|
189
|
-
# variable and op
|
190
|
-
filter_expressions = named_datasets.map {|u| Operator::Equal.new(name, u)}
|
191
|
-
debug(options) {"=> #{op.to_sxp} => (filter (...) #{op.to_sxp})"}
|
192
|
-
filt = to_binary(Operator::Or, *filter_expressions)
|
193
|
-
Operator::Filter.new(filt, op)
|
194
|
-
end
|
195
|
-
when RDF::Query # Operator::BGP
|
196
|
-
case default_datasets.length
|
197
|
-
when 0
|
198
|
-
# No Default Datasets, no query to run
|
199
|
-
debug(options) {"=> #{op.to_sxp} => (bgp)"}
|
200
|
-
Operator::BGP.new
|
201
|
-
when 1
|
202
|
-
# A single dataset, write as (graph <dataset> (bgp))
|
203
|
-
debug(options) {"=> #{op.to_sxp} => (graph <#{default_datasets.first}> #{op.to_sxp})"}
|
204
|
-
Operator::Graph.new(default_datasets.first, op)
|
205
|
-
else
|
206
|
-
# Several, rewrite as Union
|
207
|
-
debug(options) {"=> #{op.to_sxp} => (union ...)"}
|
208
|
-
to_binary(Operator::Union, *default_datasets.map {|u| Operator::Graph.new(u, op.dup)})
|
209
|
-
end
|
210
|
-
else
|
211
|
-
nil
|
212
|
-
end
|
213
|
-
end
|
214
|
-
executable = operator.operands.last
|
215
|
-
debug(options) {"=> rewritten: #{executable.to_sxp}"}
|
216
|
-
|
217
|
-
@solutions = executable.execute(queryable, options.merge(:depth => options[:depth].to_i + 1))
|
175
|
+
# Create an aggregate based on queryable having just the bits we want
|
176
|
+
aggregate = RDF::AggregateRepo.new(queryable)
|
177
|
+
named_datasets.each {|name| aggregate.named(name) if queryable.has_context?(name)}
|
178
|
+
aggregate.default(*default_datasets.select {|name| queryable.has_context?(name)})
|
179
|
+
executable = operands.last
|
180
|
+
@solutions = executable.execute(aggregate, options.merge(:depth => options[:depth].to_i + 1))
|
218
181
|
end
|
219
182
|
|
220
183
|
##
|
@@ -30,9 +30,11 @@ module SPARQL; module Algebra
|
|
30
30
|
def apply(literal)
|
31
31
|
case literal
|
32
32
|
when RDF::Literal then case
|
33
|
-
when
|
33
|
+
when RDF::VERSION.to_s >= "1.1" then literal.datatype
|
34
34
|
when literal.simple? then RDF::XSD.string
|
35
|
-
|
35
|
+
when literal.datatype == RDF::XSD.string then RDF::XSD.string
|
36
|
+
when literal.plain? then RDF.langString
|
37
|
+
else RDF::URI(literal.datatype)
|
36
38
|
end
|
37
39
|
else raise TypeError, "expected an RDF::Literal, but got #{literal.inspect}"
|
38
40
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL logical `day` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (prefix ((: <http://example.org/>))
|
8
|
+
# (project (?s ?x)
|
9
|
+
# (extend ((?x (day ?date)))
|
10
|
+
# (bgp (triple ?s :date ?date)))))
|
11
|
+
#
|
12
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-day
|
13
|
+
class Day < Operator::Unary
|
14
|
+
include Evaluatable
|
15
|
+
|
16
|
+
NAME = :day
|
17
|
+
|
18
|
+
##
|
19
|
+
# Returns the day part of arg as an integer.
|
20
|
+
#
|
21
|
+
# @param [RDF::Literal] operand
|
22
|
+
# the operand
|
23
|
+
# @return [RDF::Literal]
|
24
|
+
# @raise [TypeError] if the operand is not a simple literal
|
25
|
+
def apply(operand)
|
26
|
+
raise TypeError, "expected an RDF::Literal::DateTime, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::DateTime)
|
27
|
+
RDF::Literal(operand.object.day)
|
28
|
+
end
|
29
|
+
end # Day
|
30
|
+
end # Operator
|
31
|
+
end; end # SPARQL::Algebra
|