sparql 1.1.6 → 1.1.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.
- checksums.yaml +4 -4
 - data/README.md +4 -6
 - data/VERSION +1 -1
 - data/lib/sparql/algebra/expression.rb +28 -2
 - data/lib/sparql/algebra/extensions.rb +73 -0
 - data/lib/sparql/algebra/operator.rb +73 -9
 - data/lib/sparql/algebra/operator/alt.rb +58 -0
 - data/lib/sparql/algebra/operator/extend.rb +15 -3
 - data/lib/sparql/algebra/operator/filter.rb +18 -1
 - data/lib/sparql/algebra/operator/group.rb +22 -1
 - data/lib/sparql/algebra/operator/join.rb +16 -5
 - data/lib/sparql/algebra/operator/left_join.rb +12 -1
 - data/lib/sparql/algebra/operator/notin.rb +1 -1
 - data/lib/sparql/algebra/operator/notoneof.rb +52 -0
 - data/lib/sparql/algebra/operator/path.rb +49 -0
 - data/lib/sparql/algebra/operator/path_opt.rb +112 -0
 - data/lib/sparql/algebra/operator/path_plus.rb +99 -0
 - data/lib/sparql/algebra/operator/path_star.rb +42 -0
 - data/lib/sparql/algebra/operator/reverse.rb +54 -0
 - data/lib/sparql/algebra/operator/seq.rb +73 -0
 - data/lib/sparql/algebra/operator/sequence.rb +63 -0
 - data/lib/sparql/algebra/operator/union.rb +12 -1
 - data/lib/sparql/algebra/query.rb +1 -0
 - data/lib/sparql/grammar/meta.rb +4593 -4582
 - data/lib/sparql/grammar/parser11.rb +301 -107
 - metadata +13 -4
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: f8e188130c333370c626f037f5c2312a222b5f3d
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 61c0398d56e8e2891dc97d4a8843411c5912e0d6
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 9398d997c21707cfaeef51fb8fd5dd11008e0d23bcc81ee8f9027d98ee37297b19735b4c4a6202cbf241c7faf811510af0dbf588742bcaf2389cfdda1488027a
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 03a7de12fa45056026eff0a2d93bfc92d375173c6afabfc462e223f10f5ea75f4ef943d22a9621aa84836b07703be4d4ee2206b917206edba70648af30f79723
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -9,7 +9,7 @@ This is a [Ruby][] implementation of [SPARQL][] for [RDF.rb][]. 
     | 
|
| 
       9 
9 
     | 
    
         
             
            ## Features
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
            * 100% free and unencumbered [public domain](http://unlicense.org/) software.
         
     | 
| 
       12 
     | 
    
         
            -
            * [SPARQL 1.1 Query][] parsing and execution 
     | 
| 
      
 12 
     | 
    
         
            +
            * Complete [SPARQL 1.1 Query][] parsing and execution
         
     | 
| 
       13 
13 
     | 
    
         
             
            * SPARQL results as [XML][SPARQL XML], [JSON][SPARQL JSON],
         
     | 
| 
       14 
14 
     | 
    
         
             
              [CSV][SPARQL 1.1 Query Results CSV and TSV Formats],
         
     | 
| 
       15 
15 
     | 
    
         
             
              [TSV][SPARQL 1.1 Query Results CSV and TSV Formats]
         
     | 
| 
         @@ -21,6 +21,7 @@ This is a [Ruby][] implementation of [SPARQL][] for [RDF.rb][]. 
     | 
|
| 
       21 
21 
     | 
    
         
             
            * [Rack][] and [Sinatra][] middleware to perform [HTTP content negotiation][conneg] for result formats
         
     | 
| 
       22 
22 
     | 
    
         
             
              * Compatible with any [Rack][] or [Sinatra][] application and any Rack-based framework.
         
     | 
| 
       23 
23 
     | 
    
         
             
              * Helper method for describing [SPARQL Service Description][SSD]
         
     | 
| 
      
 24 
     | 
    
         
            +
            * Implementation Report: {file:etc/earl.html EARL}
         
     | 
| 
       24 
25 
     | 
    
         
             
            * Compatible with Ruby >= 1.9.3.
         
     | 
| 
       25 
26 
     | 
    
         
             
            * Compatible with older Ruby versions with the help of the [Backports][] gem.
         
     | 
| 
       26 
27 
     | 
    
         
             
            * Supports Unicode query strings both on all versions of Ruby.
         
     | 
| 
         @@ -30,8 +31,6 @@ This is a [Ruby][] implementation of [SPARQL][] for [RDF.rb][]. 
     | 
|
| 
       30 
31 
     | 
    
         
             
            The {SPARQL} gem implements [SPARQL 1.1 Query][], and [SPARQL 1.1 Update][], and provides [Rack][] and [Sinatra][] middleware to provide results using [HTTP Content Negotiation][conneg].
         
     | 
| 
       31 
32 
     | 
    
         | 
| 
       32 
33 
     | 
    
         
             
            * {SPARQL::Grammar} implements a [SPARQL 1.1 Query][] and [SPARQL 1.1 Update][] parser generating [SPARQL S-Expressions (SSE)][SSE].
         
     | 
| 
       33 
     | 
    
         
            -
              * Support for [Property Paths][] is excluded.
         
     | 
| 
       34 
     | 
    
         
            -
                See the section on [SPARQL 1.1 Query][] extensions and limitations for further detail.
         
     | 
| 
       35 
34 
     | 
    
         
             
            * {SPARQL::Algebra} executes SSE against Any `RDF::Graph` or `RDF::Repository`, including compliant [RDF.rb][] repository adaptors such as [RDF::DO][] and [RDF::Mongo][].
         
     | 
| 
       36 
35 
     | 
    
         
             
            * {Rack::SPARQL} and {Sinatra::SPARQL} provide middleware components to format results using an appropriate format based on [HTTP content negotiation][conneg].
         
     | 
| 
       37 
36 
     | 
    
         | 
| 
         @@ -53,13 +52,13 @@ The SPARQL gem now implements the following [SPARQL 1.1 Query][] operations: 
     | 
|
| 
       53 
52 
     | 
    
         
             
            * [Inline Data](http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#inline-data)
         
     | 
| 
       54 
53 
     | 
    
         
             
            * [Exists](http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-filter-exists)
         
     | 
| 
       55 
54 
     | 
    
         
             
            * [Negation](http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#negation)
         
     | 
| 
      
 55 
     | 
    
         
            +
            * [Property Paths](http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#propertypaths)
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
       57 
57 
     | 
    
         
             
            The gem also includes the following [SPARQL 1.1 Update][] operations:
         
     | 
| 
       58 
58 
     | 
    
         
             
            * [Graph Update](http://www.w3.org/TR/sparql11-update/#graphUpdate)
         
     | 
| 
       59 
59 
     | 
    
         
             
            * [Graph Management](http://www.w3.org/TR/sparql11-update/#graphManagement)
         
     | 
| 
       60 
60 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
            [Property Paths][], which will be in later release along with:
         
     | 
| 
      
 61 
     | 
    
         
            +
            Not supported:
         
     | 
| 
       63 
62 
     | 
    
         | 
| 
       64 
63 
     | 
    
         
             
            * [Federated Query][SPARQL 1.1 Federated Query],
         
     | 
| 
       65 
64 
     | 
    
         
             
            * [Entailment Regimes][SPARQL 1.1 Entailment Regimes],
         
     | 
| 
         @@ -337,7 +336,6 @@ A copy of the [SPARQL 1.0 tests][] and [SPARQL 1.1 tests][] are also included in 
     | 
|
| 
       337 
336 
     | 
    
         
             
            [SPARQL XML]:       http://www.w3.org/TR/rdf-sparql-XMLres/
         
     | 
| 
       338 
337 
     | 
    
         
             
            [SPARQL JSON]:      http://www.w3.org/TR/rdf-sparql-json-res/
         
     | 
| 
       339 
338 
     | 
    
         
             
            [SPARQL EBNF]:      http://www.w3.org/TR/sparql11-query/#sparqlGrammar
         
     | 
| 
       340 
     | 
    
         
            -
            [Property Paths]:   http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#propertypaths
         
     | 
| 
       341 
339 
     | 
    
         | 
| 
       342 
340 
     | 
    
         
             
            [SSD]:              http://www.w3.org/TR/sparql11-service-description/
         
     | 
| 
       343 
341 
     | 
    
         
             
            [Rack]:             http://rack.rubyforge.org/
         
     | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            1.1. 
     | 
| 
      
 1 
     | 
    
         
            +
            1.1.7
         
     | 
| 
         @@ -120,7 +120,7 @@ module SPARQL; module Algebra 
     | 
|
| 
       120 
120 
     | 
    
         
             
                  end
         
     | 
| 
       121 
121 
     | 
    
         | 
| 
       122 
122 
     | 
    
         
             
                  debug(options) {"#{operator.inspect}(#{operands.map(&:inspect).join(',')})"}
         
     | 
| 
       123 
     | 
    
         
            -
                  options.delete_if {|k, v| [:debug, :depth, :prefixes, :base_uri, :update].include?(k) }
         
     | 
| 
      
 123 
     | 
    
         
            +
                  options.delete_if {|k, v| [:debug, :depth, :prefixes, :base_uri, :update, :validate].include?(k) }
         
     | 
| 
       124 
124 
     | 
    
         
             
                  operands << options unless options.empty?
         
     | 
| 
       125 
125 
     | 
    
         
             
                  operator.new(*operands)
         
     | 
| 
       126 
126 
     | 
    
         
             
                end
         
     | 
| 
         @@ -317,7 +317,33 @@ module SPARQL; module Algebra 
     | 
|
| 
       317 
317 
     | 
    
         
             
                def to_sxp_bin
         
     | 
| 
       318 
318 
     | 
    
         
             
                  self
         
     | 
| 
       319 
319 
     | 
    
         
             
                end
         
     | 
| 
       320 
     | 
    
         
            -
             
     | 
| 
      
 320 
     | 
    
         
            +
             
     | 
| 
      
 321 
     | 
    
         
            +
                ##
         
     | 
| 
      
 322 
     | 
    
         
            +
                # Is this value valid, and composed only of valid components?
         
     | 
| 
      
 323 
     | 
    
         
            +
                #
         
     | 
| 
      
 324 
     | 
    
         
            +
                # @return [Boolean] `true` or `false`
         
     | 
| 
      
 325 
     | 
    
         
            +
                def valid?
         
     | 
| 
      
 326 
     | 
    
         
            +
                  true
         
     | 
| 
      
 327 
     | 
    
         
            +
                end
         
     | 
| 
      
 328 
     | 
    
         
            +
             
     | 
| 
      
 329 
     | 
    
         
            +
                ##
         
     | 
| 
      
 330 
     | 
    
         
            +
                # Is this value invalid, or is it composed of any invalid components?
         
     | 
| 
      
 331 
     | 
    
         
            +
                #
         
     | 
| 
      
 332 
     | 
    
         
            +
                # @return [Boolean] `true` or `false`
         
     | 
| 
      
 333 
     | 
    
         
            +
                def invalid?
         
     | 
| 
      
 334 
     | 
    
         
            +
                  !valid?
         
     | 
| 
      
 335 
     | 
    
         
            +
                end
         
     | 
| 
      
 336 
     | 
    
         
            +
             
     | 
| 
      
 337 
     | 
    
         
            +
                ##
         
     | 
| 
      
 338 
     | 
    
         
            +
                # Default validate! implementation, overridden in concrete classes
         
     | 
| 
      
 339 
     | 
    
         
            +
                # @return [SPARQL::Algebra::Expression] `self`
         
     | 
| 
      
 340 
     | 
    
         
            +
                # @raise  [ArgumentError] if the value is invalid
         
     | 
| 
      
 341 
     | 
    
         
            +
                def validate!
         
     | 
| 
      
 342 
     | 
    
         
            +
                  raise ArgumentError if invalid?
         
     | 
| 
      
 343 
     | 
    
         
            +
                  self
         
     | 
| 
      
 344 
     | 
    
         
            +
                end
         
     | 
| 
      
 345 
     | 
    
         
            +
                alias_method :validate, :validate!
         
     | 
| 
      
 346 
     | 
    
         
            +
             
     | 
| 
       321 
347 
     | 
    
         
             
                private
         
     | 
| 
       322 
348 
     | 
    
         
             
                # @overload: May be called with node, message and an option hash
         
     | 
| 
       323 
349 
     | 
    
         
             
                #   @param [String] node processing node
         
     | 
| 
         @@ -135,6 +135,37 @@ class Array 
     | 
|
| 
       135 
135 
     | 
    
         
             
                end
         
     | 
| 
       136 
136 
     | 
    
         
             
                self
         
     | 
| 
       137 
137 
     | 
    
         
             
              end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
              ##
         
     | 
| 
      
 140 
     | 
    
         
            +
              # Return the non-destinguished variables contained within this Array
         
     | 
| 
      
 141 
     | 
    
         
            +
              # @return [Array<RDF::Query::Variable>]
         
     | 
| 
      
 142 
     | 
    
         
            +
              def ndvars
         
     | 
| 
      
 143 
     | 
    
         
            +
                vars.reject(&:distinguished?)
         
     | 
| 
      
 144 
     | 
    
         
            +
              end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
              ##
         
     | 
| 
      
 147 
     | 
    
         
            +
              # Return the variables contained within this Array
         
     | 
| 
      
 148 
     | 
    
         
            +
              # @return [Array<RDF::Query::Variable>]
         
     | 
| 
      
 149 
     | 
    
         
            +
              def vars
         
     | 
| 
      
 150 
     | 
    
         
            +
                select {|o| o.respond_to?(:vars)}.map(&:vars).flatten.compact
         
     | 
| 
      
 151 
     | 
    
         
            +
              end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
              ##
         
     | 
| 
      
 154 
     | 
    
         
            +
              # Is this value composed only of valid components?
         
     | 
| 
      
 155 
     | 
    
         
            +
              #
         
     | 
| 
      
 156 
     | 
    
         
            +
              # @return [Boolean] `true` or `false`
         
     | 
| 
      
 157 
     | 
    
         
            +
              def valid?
         
     | 
| 
      
 158 
     | 
    
         
            +
                all? {|e| e.respond_to?(:valid?) ? e.valid? : true}
         
     | 
| 
      
 159 
     | 
    
         
            +
              end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
              ##
         
     | 
| 
      
 162 
     | 
    
         
            +
              # Validate all components.
         
     | 
| 
      
 163 
     | 
    
         
            +
              # @return [Array] `self`
         
     | 
| 
      
 164 
     | 
    
         
            +
              # @raise  [ArgumentError] if the value is invalid
         
     | 
| 
      
 165 
     | 
    
         
            +
              def validate!
         
     | 
| 
      
 166 
     | 
    
         
            +
                each {|e| e.validate! if e.respond_to?(:validate!)}
         
     | 
| 
      
 167 
     | 
    
         
            +
                self
         
     | 
| 
      
 168 
     | 
    
         
            +
              end
         
     | 
| 
       138 
169 
     | 
    
         
             
            end
         
     | 
| 
       139 
170 
     | 
    
         | 
| 
       140 
171 
     | 
    
         
             
            ##
         
     | 
| 
         @@ -199,6 +230,20 @@ module RDF::Term 
     | 
|
| 
       199 
230 
     | 
    
         
             
                  (language == other.language || dtr == RDF::XSD.string) :
         
     | 
| 
       200 
231 
     | 
    
         
             
                  dtr == RDF::XSD.string
         
     | 
| 
       201 
232 
     | 
    
         
             
              end
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
              ##
         
     | 
| 
      
 235 
     | 
    
         
            +
              # Return the non-destinguished variables contained within this operator
         
     | 
| 
      
 236 
     | 
    
         
            +
              # @return [Array<RDF::Query::Variable>]
         
     | 
| 
      
 237 
     | 
    
         
            +
              def ndvars
         
     | 
| 
      
 238 
     | 
    
         
            +
                vars.reject(&:distinguished?)
         
     | 
| 
      
 239 
     | 
    
         
            +
              end
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
      
 241 
     | 
    
         
            +
              ##
         
     | 
| 
      
 242 
     | 
    
         
            +
              # Return the variables contained within this operator
         
     | 
| 
      
 243 
     | 
    
         
            +
              # @return [Array<RDF::Query::Variable>]
         
     | 
| 
      
 244 
     | 
    
         
            +
              def vars
         
     | 
| 
      
 245 
     | 
    
         
            +
                variable? ? [self] : []
         
     | 
| 
      
 246 
     | 
    
         
            +
              end
         
     | 
| 
       202 
247 
     | 
    
         
             
            end # RDF::Term
         
     | 
| 
       203 
248 
     | 
    
         | 
| 
       204 
249 
     | 
    
         
             
            # Override RDF::Queryable to execute against SPARQL::Algebra::Query elements as well as RDF::Query and RDF::Pattern
         
     | 
| 
         @@ -311,6 +356,20 @@ class RDF::Query 
     | 
|
| 
       311 
356 
     | 
    
         
             
              def query_yields_solutions?
         
     | 
| 
       312 
357 
     | 
    
         
             
                true
         
     | 
| 
       313 
358 
     | 
    
         
             
              end
         
     | 
| 
      
 359 
     | 
    
         
            +
             
     | 
| 
      
 360 
     | 
    
         
            +
              ##
         
     | 
| 
      
 361 
     | 
    
         
            +
              # Return the non-destinguished variables contained within patterns
         
     | 
| 
      
 362 
     | 
    
         
            +
              # @return [Array<RDF::Query::Variable>]
         
     | 
| 
      
 363 
     | 
    
         
            +
              def ndvars
         
     | 
| 
      
 364 
     | 
    
         
            +
                patterns.map(&:ndvars).flatten
         
     | 
| 
      
 365 
     | 
    
         
            +
              end
         
     | 
| 
      
 366 
     | 
    
         
            +
             
     | 
| 
      
 367 
     | 
    
         
            +
              ##
         
     | 
| 
      
 368 
     | 
    
         
            +
              # Return the variables contained within patterns
         
     | 
| 
      
 369 
     | 
    
         
            +
              # @return [Array<RDF::Query::Variable>]
         
     | 
| 
      
 370 
     | 
    
         
            +
              def vars
         
     | 
| 
      
 371 
     | 
    
         
            +
                patterns.map(&:vars).flatten
         
     | 
| 
      
 372 
     | 
    
         
            +
              end
         
     | 
| 
       314 
373 
     | 
    
         
             
            end
         
     | 
| 
       315 
374 
     | 
    
         | 
| 
       316 
375 
     | 
    
         
             
            class RDF::Query::Pattern
         
     | 
| 
         @@ -323,6 +382,20 @@ class RDF::Query::Pattern 
     | 
|
| 
       323 
382 
     | 
    
         
             
                  [:triple, subject, predicate, object]
         
     | 
| 
       324 
383 
     | 
    
         
             
                end
         
     | 
| 
       325 
384 
     | 
    
         
             
              end
         
     | 
| 
      
 385 
     | 
    
         
            +
             
     | 
| 
      
 386 
     | 
    
         
            +
              ##
         
     | 
| 
      
 387 
     | 
    
         
            +
              # Return the non-destinguished variables contained within this pattern
         
     | 
| 
      
 388 
     | 
    
         
            +
              # @return [Array<RDF::Query::Variable>]
         
     | 
| 
      
 389 
     | 
    
         
            +
              def ndvars
         
     | 
| 
      
 390 
     | 
    
         
            +
                vars.reject(&:distinguished?)
         
     | 
| 
      
 391 
     | 
    
         
            +
              end
         
     | 
| 
      
 392 
     | 
    
         
            +
             
     | 
| 
      
 393 
     | 
    
         
            +
              ##
         
     | 
| 
      
 394 
     | 
    
         
            +
              # Return the variables contained within this pattern
         
     | 
| 
      
 395 
     | 
    
         
            +
              # @return [Array<RDF::Query::Variable>]
         
     | 
| 
      
 396 
     | 
    
         
            +
              def vars
         
     | 
| 
      
 397 
     | 
    
         
            +
                variables.values
         
     | 
| 
      
 398 
     | 
    
         
            +
              end
         
     | 
| 
       326 
399 
     | 
    
         
             
            end
         
     | 
| 
       327 
400 
     | 
    
         | 
| 
       328 
401 
     | 
    
         
             
            ##
         
     | 
| 
         @@ -85,6 +85,17 @@ module SPARQL; module Algebra 
     | 
|
| 
       85 
85 
     | 
    
         
             
                autoload :Subtract,           'sparql/algebra/operator/subtract'
         
     | 
| 
       86 
86 
     | 
    
         
             
                autoload :UCase,              'sparql/algebra/operator/ucase'
         
     | 
| 
       87 
87 
     | 
    
         | 
| 
      
 88 
     | 
    
         
            +
                # Property Paths
         
     | 
| 
      
 89 
     | 
    
         
            +
                autoload :Alt,                'sparql/algebra/operator/alt'
         
     | 
| 
      
 90 
     | 
    
         
            +
                autoload :NotOneOf,           'sparql/algebra/operator/notoneof'
         
     | 
| 
      
 91 
     | 
    
         
            +
                autoload :PathOpt,            'sparql/algebra/operator/path_opt'
         
     | 
| 
      
 92 
     | 
    
         
            +
                autoload :PathPlus,           'sparql/algebra/operator/path_plus'
         
     | 
| 
      
 93 
     | 
    
         
            +
                autoload :PathStar,           'sparql/algebra/operator/path_star'
         
     | 
| 
      
 94 
     | 
    
         
            +
                autoload :Path,               'sparql/algebra/operator/path'
         
     | 
| 
      
 95 
     | 
    
         
            +
                autoload :Reverse,            'sparql/algebra/operator/reverse'
         
     | 
| 
      
 96 
     | 
    
         
            +
                autoload :Seq,                'sparql/algebra/operator/seq'
         
     | 
| 
      
 97 
     | 
    
         
            +
                autoload :Sequence,           'sparql/algebra/operator/sequence'
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
       88 
99 
     | 
    
         
             
                # Miscellaneous
         
     | 
| 
       89 
100 
     | 
    
         
             
                autoload :Asc,                'sparql/algebra/operator/asc'
         
     | 
| 
       90 
101 
     | 
    
         
             
                autoload :Coalesce,           'sparql/algebra/operator/coalesce'
         
     | 
| 
         @@ -159,6 +170,7 @@ module SPARQL; module Algebra 
     | 
|
| 
       159 
170 
     | 
    
         
             
                    when :>=              then GreaterThanOrEqual
         
     | 
| 
       160 
171 
     | 
    
         
             
                    when :abs             then Abs
         
     | 
| 
       161 
172 
     | 
    
         
             
                    when :add             then Add
         
     | 
| 
      
 173 
     | 
    
         
            +
                    when :alt             then Alt
         
     | 
| 
       162 
174 
     | 
    
         
             
                    when :and, :'&&'      then And
         
     | 
| 
       163 
175 
     | 
    
         
             
                    when :avg             then Avg
         
     | 
| 
       164 
176 
     | 
    
         
             
                    when :bnode           then BNode
         
     | 
| 
         @@ -195,18 +207,26 @@ module SPARQL; module Algebra 
     | 
|
| 
       195 
207 
     | 
    
         
             
                    when :month           then Month
         
     | 
| 
       196 
208 
     | 
    
         
             
                    when :multiply        then Multiply
         
     | 
| 
       197 
209 
     | 
    
         
             
                    when :not, :'!'       then Not
         
     | 
| 
       198 
     | 
    
         
            -
                    when :notexists 
     | 
| 
      
 210 
     | 
    
         
            +
                    when :notexists       then NotExists
         
     | 
| 
       199 
211 
     | 
    
         
             
                    when :notin           then NotIn
         
     | 
| 
      
 212 
     | 
    
         
            +
                    when :notoneof        then NotOneOf
         
     | 
| 
       200 
213 
     | 
    
         
             
                    when :now             then Now
         
     | 
| 
       201 
214 
     | 
    
         
             
                    when :or, :'||'       then Or
         
     | 
| 
      
 215 
     | 
    
         
            +
                    when :path            then Path
         
     | 
| 
      
 216 
     | 
    
         
            +
                    when :path?           then PathOpt
         
     | 
| 
      
 217 
     | 
    
         
            +
                    when :"path*"         then PathStar
         
     | 
| 
      
 218 
     | 
    
         
            +
                    when :"path+"         then PathPlus
         
     | 
| 
       202 
219 
     | 
    
         
             
                    when :plus            then Plus
         
     | 
| 
       203 
220 
     | 
    
         
             
                    when :rand            then Rand
         
     | 
| 
       204 
221 
     | 
    
         
             
                    when :regex           then Regex
         
     | 
| 
       205 
222 
     | 
    
         
             
                    when :replace         then Replace
         
     | 
| 
      
 223 
     | 
    
         
            +
                    when :reverse         then Reverse
         
     | 
| 
       206 
224 
     | 
    
         
             
                    when :round           then Round
         
     | 
| 
       207 
225 
     | 
    
         
             
                    when :sameterm        then SameTerm
         
     | 
| 
       208 
226 
     | 
    
         
             
                    when :sample          then Sample
         
     | 
| 
       209 
227 
     | 
    
         
             
                    when :seconds         then Seconds
         
     | 
| 
      
 228 
     | 
    
         
            +
                    when :seq             then Seq
         
     | 
| 
      
 229 
     | 
    
         
            +
                    when :sequence        then Sequence
         
     | 
| 
       210 
230 
     | 
    
         
             
                    when :sha1            then SHA1
         
     | 
| 
       211 
231 
     | 
    
         
             
                    when :sha256          then SHA256
         
     | 
| 
       212 
232 
     | 
    
         
             
                    when :sha512          then SHA512
         
     | 
| 
         @@ -322,7 +342,11 @@ module SPARQL; module Algebra 
     | 
|
| 
       322 
342 
     | 
    
         
             
                  @options  = operands.last.is_a?(Hash) ? operands.pop.dup : {}
         
     | 
| 
       323 
343 
     | 
    
         
             
                  @operands = operands.map! do |operand|
         
     | 
| 
       324 
344 
     | 
    
         
             
                    case operand
         
     | 
| 
      
 345 
     | 
    
         
            +
                      when Array
         
     | 
| 
      
 346 
     | 
    
         
            +
                        operand.each {|op| op.parent = self if operand.respond_to?(:parent=)}
         
     | 
| 
      
 347 
     | 
    
         
            +
                        operand
         
     | 
| 
       325 
348 
     | 
    
         
             
                      when Operator, Variable, RDF::Term, RDF::Query, RDF::Query::Pattern, Array, Symbol
         
     | 
| 
      
 349 
     | 
    
         
            +
                        operand.parent = self if operand.respond_to?(:parent=)
         
     | 
| 
       326 
350 
     | 
    
         
             
                        operand
         
     | 
| 
       327 
351 
     | 
    
         
             
                      when TrueClass, FalseClass, Numeric, String, DateTime, Date, Time
         
     | 
| 
       328 
352 
     | 
    
         
             
                        RDF::Literal(operand)
         
     | 
| 
         @@ -387,12 +411,6 @@ module SPARQL; module Algebra 
     | 
|
| 
       387 
411 
     | 
    
         
             
                  @prefixes = hash
         
     | 
| 
       388 
412 
     | 
    
         
             
                end
         
     | 
| 
       389 
413 
     | 
    
         | 
| 
       390 
     | 
    
         
            -
                ##
         
     | 
| 
       391 
     | 
    
         
            -
                # Any additional options for this operator.
         
     | 
| 
       392 
     | 
    
         
            -
                #
         
     | 
| 
       393 
     | 
    
         
            -
                # @return [Hash]
         
     | 
| 
       394 
     | 
    
         
            -
                attr_reader :options
         
     | 
| 
       395 
     | 
    
         
            -
             
     | 
| 
       396 
414 
     | 
    
         
             
                ##
         
     | 
| 
       397 
415 
     | 
    
         
             
                # The operands to this operator.
         
     | 
| 
       398 
416 
     | 
    
         
             
                #
         
     | 
| 
         @@ -540,7 +558,7 @@ module SPARQL; module Algebra 
     | 
|
| 
       540 
558 
     | 
    
         
             
                #
         
     | 
| 
       541 
559 
     | 
    
         
             
                # @return [String]
         
     | 
| 
       542 
560 
     | 
    
         
             
                def inspect
         
     | 
| 
       543 
     | 
    
         
            -
                  sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, operands. 
     | 
| 
      
 561 
     | 
    
         
            +
                  sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, operands.to_sse.gsub(/\s+/m, ' '))
         
     | 
| 
       544 
562 
     | 
    
         
             
                end
         
     | 
| 
       545 
563 
     | 
    
         | 
| 
       546 
564 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -552,7 +570,21 @@ module SPARQL; module Algebra 
     | 
|
| 
       552 
570 
     | 
    
         
             
                alias_method :==, :eql?
         
     | 
| 
       553 
571 
     | 
    
         | 
| 
       554 
572 
     | 
    
         
             
                ##
         
     | 
| 
       555 
     | 
    
         
            -
                #  
     | 
| 
      
 573 
     | 
    
         
            +
                # Return the non-destinguished variables contained within this operator
         
     | 
| 
      
 574 
     | 
    
         
            +
                # @return [Array<RDF::Query::Variable>]
         
     | 
| 
      
 575 
     | 
    
         
            +
                def ndvars
         
     | 
| 
      
 576 
     | 
    
         
            +
                  vars.reject(&:distinguished?)
         
     | 
| 
      
 577 
     | 
    
         
            +
                end
         
     | 
| 
      
 578 
     | 
    
         
            +
             
     | 
| 
      
 579 
     | 
    
         
            +
                ##
         
     | 
| 
      
 580 
     | 
    
         
            +
                # Return the variables contained within this operator
         
     | 
| 
      
 581 
     | 
    
         
            +
                # @return [Array<RDF::Query::Variable>]
         
     | 
| 
      
 582 
     | 
    
         
            +
                def vars
         
     | 
| 
      
 583 
     | 
    
         
            +
                  operands.select {|o| o.respond_to?(:vars)}.map(&:vars).flatten
         
     | 
| 
      
 584 
     | 
    
         
            +
                end
         
     | 
| 
      
 585 
     | 
    
         
            +
             
     | 
| 
      
 586 
     | 
    
         
            +
                ##
         
     | 
| 
      
 587 
     | 
    
         
            +
                # Iterate via depth-first recursive descent over operands, yielding each operator
         
     | 
| 
       556 
588 
     | 
    
         
             
                # @yield operator
         
     | 
| 
       557 
589 
     | 
    
         
             
                # @yieldparam [Object] operator
         
     | 
| 
       558 
590 
     | 
    
         
             
                def descendants(&block)
         
     | 
| 
         @@ -569,6 +601,38 @@ module SPARQL; module Algebra 
     | 
|
| 
       569 
601 
     | 
    
         
             
                    block.call(operand)
         
     | 
| 
       570 
602 
     | 
    
         
             
                  end
         
     | 
| 
       571 
603 
     | 
    
         
             
                end
         
     | 
| 
      
 604 
     | 
    
         
            +
             
     | 
| 
      
 605 
     | 
    
         
            +
                ##
         
     | 
| 
      
 606 
     | 
    
         
            +
                # Parent expression, if any
         
     | 
| 
      
 607 
     | 
    
         
            +
                #
         
     | 
| 
      
 608 
     | 
    
         
            +
                # @return [Operator]
         
     | 
| 
      
 609 
     | 
    
         
            +
                def parent; @options[:parent]; end
         
     | 
| 
      
 610 
     | 
    
         
            +
             
     | 
| 
      
 611 
     | 
    
         
            +
                ##
         
     | 
| 
      
 612 
     | 
    
         
            +
                # Parent operator, if any
         
     | 
| 
      
 613 
     | 
    
         
            +
                #
         
     | 
| 
      
 614 
     | 
    
         
            +
                # @return [Operator]
         
     | 
| 
      
 615 
     | 
    
         
            +
                def parent=(operator)
         
     | 
| 
      
 616 
     | 
    
         
            +
                  @options[:parent]= operator
         
     | 
| 
      
 617 
     | 
    
         
            +
                end
         
     | 
| 
      
 618 
     | 
    
         
            +
             
     | 
| 
      
 619 
     | 
    
         
            +
                ##
         
     | 
| 
      
 620 
     | 
    
         
            +
                # First ancestor operator of type `klass`
         
     | 
| 
      
 621 
     | 
    
         
            +
                #
         
     | 
| 
      
 622 
     | 
    
         
            +
                # @param [Class] klass
         
     | 
| 
      
 623 
     | 
    
         
            +
                # @return [Operator]
         
     | 
| 
      
 624 
     | 
    
         
            +
                def first_ancestor(klass)
         
     | 
| 
      
 625 
     | 
    
         
            +
                  parent.is_a?(klass) ? parent : parent.first_ancestor(klass) if parent
         
     | 
| 
      
 626 
     | 
    
         
            +
                end
         
     | 
| 
      
 627 
     | 
    
         
            +
             
     | 
| 
      
 628 
     | 
    
         
            +
                ##
         
     | 
| 
      
 629 
     | 
    
         
            +
                # Validate all operands, operator specific classes should override for operator-specific validation
         
     | 
| 
      
 630 
     | 
    
         
            +
                # @return [SPARQL::Algebra::Expression] `self`
         
     | 
| 
      
 631 
     | 
    
         
            +
                # @raise  [ArgumentError] if the value is invalid
         
     | 
| 
      
 632 
     | 
    
         
            +
                def validate!
         
     | 
| 
      
 633 
     | 
    
         
            +
                  operands.each {|op| op.validate! if op.respond_to?(:validate!)}
         
     | 
| 
      
 634 
     | 
    
         
            +
                  self
         
     | 
| 
      
 635 
     | 
    
         
            +
                end
         
     | 
| 
       572 
636 
     | 
    
         
             
              protected
         
     | 
| 
       573 
637 
     | 
    
         | 
| 
       574 
638 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -0,0 +1,58 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module SPARQL; module Algebra
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Operator
         
     | 
| 
      
 3 
     | 
    
         
            +
                ##
         
     | 
| 
      
 4 
     | 
    
         
            +
                # The SPARQL Property Path `alt` (Alternative Property Path) operator.
         
     | 
| 
      
 5 
     | 
    
         
            +
                #
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 7 
     | 
    
         
            +
                #   (alt a b)
         
     | 
| 
      
 8 
     | 
    
         
            +
                #
         
     | 
| 
      
 9 
     | 
    
         
            +
                # @see http://www.w3.org/TR/sparql11-query/#defn_evalPP_alternative
         
     | 
| 
      
 10 
     | 
    
         
            +
                class Alt < Operator::Binary
         
     | 
| 
      
 11 
     | 
    
         
            +
                  include Query
         
     | 
| 
      
 12 
     | 
    
         
            +
                  
         
     | 
| 
      
 13 
     | 
    
         
            +
                  NAME = :alt
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  ##
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # Equivalent to:
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #    (path x (alt :p :q) y)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #     => (union (bgp (x :p y)) (bgp (x :q y)))
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # @param  [RDF::Queryable] queryable
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #   the graph or repository to query
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # @param  [Hash{Symbol => Object}] options
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #   any additional keyword options
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # @option options [RDF::Term, RDF::Variable] :subject
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # @option options [RDF::Term, RDF::Variable] :object
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # @yield  [solution]
         
     | 
| 
      
 28 
     | 
    
         
            +
                  #   each matching solution
         
     | 
| 
      
 29 
     | 
    
         
            +
                  # @yieldparam  [RDF::Query::Solution] solution
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # @yieldreturn [void] ignored
         
     | 
| 
      
 31 
     | 
    
         
            +
                  # @see    http://www.w3.org/TR/rdf-sparql-query/#sparqlAlgebra
         
     | 
| 
      
 32 
     | 
    
         
            +
                  def execute(queryable, options = {}, &block)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    subject, object = options[:subject], options[:object]
         
     | 
| 
      
 34 
     | 
    
         
            +
                    debug(options) {"Alt #{[subject, operands, object].to_sse}"}
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                    # Solutions where predicate exists
         
     | 
| 
      
 37 
     | 
    
         
            +
                    qa = if operand(0).is_a?(RDF::Term)
         
     | 
| 
      
 38 
     | 
    
         
            +
                      RDF::Query.new do |q|
         
     | 
| 
      
 39 
     | 
    
         
            +
                        q.pattern [subject, operand(0), object]
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
                    else
         
     | 
| 
      
 42 
     | 
    
         
            +
                      operand(0)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                    qb = if operand(1).is_a?(RDF::Term)
         
     | 
| 
      
 46 
     | 
    
         
            +
                      RDF::Query.new do |q|
         
     | 
| 
      
 47 
     | 
    
         
            +
                        q.pattern [subject, operand(1), object]
         
     | 
| 
      
 48 
     | 
    
         
            +
                      end
         
     | 
| 
      
 49 
     | 
    
         
            +
                    else
         
     | 
| 
      
 50 
     | 
    
         
            +
                      operand(1)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    query = Union.new(qa, qb)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    queryable.query(query, options.merge(depth: options[:depth].to_i + 1), &block)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
                end # Alt
         
     | 
| 
      
 57 
     | 
    
         
            +
              end # Operator
         
     | 
| 
      
 58 
     | 
    
         
            +
            end; end # SPARQL::Algebra
         
     | 
| 
         @@ -41,10 +41,10 @@ module SPARQL; module Algebra 
     | 
|
| 
       41 
41 
     | 
    
         
             
                  # @see http://www.w3.org/TR/rdf-sparql-query/#evaluation
         
     | 
| 
       42 
42 
     | 
    
         
             
                  def execute(queryable, options = {}, &block)
         
     | 
| 
       43 
43 
     | 
    
         
             
                    debug(options) {"Extend"}
         
     | 
| 
       44 
     | 
    
         
            -
                    @solutions =  
     | 
| 
      
 44 
     | 
    
         
            +
                    @solutions = operand(1).execute(queryable, options.merge(depth: options[:depth].to_i + 1))
         
     | 
| 
       45 
45 
     | 
    
         
             
                    @solutions.each do |solution|
         
     | 
| 
       46 
46 
     | 
    
         
             
                      debug(options) {"===> soln #{solution.to_hash.inspect}"}
         
     | 
| 
       47 
     | 
    
         
            -
                       
     | 
| 
      
 47 
     | 
    
         
            +
                      operand(0).each do |(var, expr)|
         
     | 
| 
       48 
48 
     | 
    
         
             
                        begin
         
     | 
| 
       49 
49 
     | 
    
         
             
                          val = expr.evaluate(solution, options.merge(
         
     | 
| 
       50 
50 
     | 
    
         
             
                                                          queryable: queryable,
         
     | 
| 
         @@ -60,7 +60,19 @@ module SPARQL; module Algebra 
     | 
|
| 
       60 
60 
     | 
    
         
             
                    @solutions.each(&block) if block_given?
         
     | 
| 
       61 
61 
     | 
    
         
             
                    @solutions
         
     | 
| 
       62 
62 
     | 
    
         
             
                  end
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  # The variable introduced by the BIND clause must not have been used in the group graph pattern up to the point of use in BIND
         
     | 
| 
      
 65 
     | 
    
         
            +
                  def validate!
         
     | 
| 
      
 66 
     | 
    
         
            +
                    bind_vars = operand(0).map(&:first)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    query_vars = operand(1).vars
         
     | 
| 
      
 68 
     | 
    
         
            +
                    
         
     | 
| 
      
 69 
     | 
    
         
            +
                    unless (bind_vars.compact & query_vars.compact).empty?
         
     | 
| 
      
 70 
     | 
    
         
            +
                      raise ArgumentError,
         
     | 
| 
      
 71 
     | 
    
         
            +
                           "bound variable used in query: #{(bind_vars.compact & query_vars.compact).to_sse}"
         
     | 
| 
      
 72 
     | 
    
         
            +
                    end
         
     | 
| 
      
 73 
     | 
    
         
            +
                    super
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
       64 
76 
     | 
    
         
             
                  ##
         
     | 
| 
       65 
77 
     | 
    
         
             
                  # Returns an optimized version of this query.
         
     | 
| 
       66 
78 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -52,7 +52,24 @@ module SPARQL; module Algebra 
     | 
|
| 
       52 
52 
     | 
    
         
             
                    @solutions.each(&block) if block_given?
         
     | 
| 
       53 
53 
     | 
    
         
             
                    @solutions
         
     | 
| 
       54 
54 
     | 
    
         
             
                  end
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  # If filtering a join of two BGPs (having the same graph name), don't worry about validating, for shared ndvars, anyway,
         
     | 
| 
      
 57 
     | 
    
         
            +
                  #
         
     | 
| 
      
 58 
     | 
    
         
            +
                  #       (filter (regex ?homepage "^http://example.org/" "")
         
     | 
| 
      
 59 
     | 
    
         
            +
                  #         (join
         
     | 
| 
      
 60 
     | 
    
         
            +
                  #           (bgp (triple ??who :homepage ?homepage))
         
     | 
| 
      
 61 
     | 
    
         
            +
                  #           (bgp (triple ??who :schoolHomepage ?schoolPage))))))
         
     | 
| 
      
 62 
     | 
    
         
            +
                  #
         
     | 
| 
      
 63 
     | 
    
         
            +
                  # is legitimate
         
     | 
| 
      
 64 
     | 
    
         
            +
                  def validate!
         
     | 
| 
      
 65 
     | 
    
         
            +
                    unless (join = operands.last).is_a?(Join) &&
         
     | 
| 
      
 66 
     | 
    
         
            +
                            join.operands.all? {|op| op.is_a?(RDF::Query)} &&
         
     | 
| 
      
 67 
     | 
    
         
            +
                            join.operands.map(&:context).uniq.length == 1
         
     | 
| 
      
 68 
     | 
    
         
            +
                      operands.last.validate!
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
                    self
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
       56 
73 
     | 
    
         
             
                  ##
         
     | 
| 
       57 
74 
     | 
    
         
             
                  # Returns an optimized version of this query.
         
     | 
| 
       58 
75 
     | 
    
         
             
                  #
         
     |