Class: SPARQL::Algebra::Operator::Construct

Inherits:
Binary show all
Includes:
Query
Defined in:
lib/sparql/algebra/operator/construct.rb

Overview

The SPARQL GraphPattern construct operator.

The CONSTRUCT query form returns a single RDF graph specified by a graph template. The result is an RDF graph formed by taking each query solution in the solution sequence, substituting for the variables in the graph template, and combining the triples into a single RDF graph by set union.

[10] ConstructQuery ::= 'CONSTRUCT' ( ConstructTemplate DatasetClause* WhereClause SolutionModifier | DatasetClause* 'WHERE' 'TriplesTemplate? '' SolutionModifier ) ValuesClause

Examples:

SPARQL Grammar

PREFIX : <http://example/> 
CONSTRUCT { ?x :p2 ?v }
WHERE {
  ?x :p ?o .
  OPTIONAL {?o :q ?v }
}

SSE

(prefix ((: <http://example/>))
 (construct ((triple ?x :p2 ?v))
  (leftjoin
   (bgp (triple ?x :p ?o))
   (bgp (triple ?o :q ?v)))))

See Also:

Constant Summary collapse

NAME =
[:construct]

Constants inherited from Binary

Binary::ARITY

Constants inherited from SPARQL::Algebra::Operator

ARITY, IsURI, URI

Constants included from Expression

Expression::PATTERN_PARENTS

Instance Attribute Summary

Attributes included from Query

#solutions

Attributes inherited from SPARQL::Algebra::Operator

#operands

Instance Method Summary collapse

Methods included from Query

#each_solution, #empty?, #failed?, #graph_name=, #matched?, #query_yields_boolean?, #query_yields_solutions?, #unshift, #variables

Methods inherited from Binary

#initialize

Methods inherited from SPARQL::Algebra::Operator

#aggregate?, arity, #base_uri, base_uri, base_uri=, #bind, #boolean, #constant?, #deep_dup, #each_descendant, #eql?, #evaluatable?, evaluate, #executable?, #first_ancestor, for, #initialize, #inspect, #ndvars, #node?, #operand, #optimize, #optimize!, #parent, #parent=, #prefixes, prefixes, prefixes=, #rewrite, #to_binary, to_sparql, #to_sxp, #to_sxp_bin, #validate!, #variable?, #variables, #vars

Methods included from Expression

cast, #constant?, #evaluate, extension, extension?, extensions, for, #invalid?, new, #node?, open, #optimize, #optimize!, parse, register_extension, #to_sxp_bin, #valid?, #validate!, #variable?

Constructor Details

This class inherits a constructor from SPARQL::Algebra::Operator::Binary

Instance Method Details

#execute(queryable, **options) {|statement| ... } ⇒ RDF::Queryable

Executes this query on the given RDF::Queryable object. Binds variables to the array of patterns in the first operand and returns the resulting RDF::Graph object

If any such instantiation produces a triple containing an unbound variable or an illegal RDF construct, such as a literal in subject or predicate position, then that triple is not included in the output RDF graph. The graph template can contain triples with no variables (known as ground or explicit triples), and these also appear in the output RDF graph returned by the CONSTRUCT query form.

Parameters:

  • queryable (RDF::Queryable)

    the graph or repository to query

  • options (Hash{Symbol => Object})

    any additional keyword options

Yields:

  • (statement)

    each matching statement

Yield Parameters:

Yield Returns:

  • (void)

    ignored

Returns:

See Also:



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/sparql/algebra/operator/construct.rb', line 48

def execute(queryable, **options, &block)
  debug(options) {"Construct #{operands.first}, #{options.inspect}"}
  graph = RDF::Graph.new
  patterns = operands.first
  query = operands.last

  queryable.query(query, **options.merge(depth: options[:depth].to_i + 1)).each do |solution|
    debug(options) {"(construct apply) #{solution.inspect} to BGP"}
    
    # Create a mapping from BNodes within the pattern list to newly constructed BNodes
    nodes = {}
    patterns.each do |pattern|
      terms = {}
      [:subject, :predicate, :object].each do |r|
        terms[r] = case o = pattern.send(r)
        when RDF::Node            then nodes[o] ||= RDF::Node.new
        when RDF::Query::Variable then solution[o]
        when RDF::Query::Pattern  then RDF::Statement.from(o.dup.bind(solution))
        else                           o
        end
      end

      statement = RDF::Statement.from(terms)

      # Sanity checking on statement
      if statement.subject.nil? || statement.predicate.nil? || statement.object.nil? ||
         statement.subject.literal? || statement.predicate.literal?
        debug(options) {"(construct skip) #{statement.inspect}"}
        next
      end

      debug(options) {"(construct add) #{statement.inspect}"}
      graph << statement
    end
  end

  debug(options) {"=>\n#{graph.dump(:ttl, standard_prefixes: true)}"}
  graph.each(&block) if block_given?
  graph
end

#query_yields_statements?Boolean

Query results statements (e.g., CONSTRUCT, DESCRIBE, CREATE)

Returns:

  • (Boolean)


91
92
93
# File 'lib/sparql/algebra/operator/construct.rb', line 91

def query_yields_statements?
  true
end

#to_sparql(**options) ⇒ String

Returns a partial SPARQL grammar for this term.

Returns:

  • (String)


100
101
102
103
104
105
106
# File 'lib/sparql/algebra/operator/construct.rb', line 100

def to_sparql(**options)
  str = "CONSTRUCT {\n" +
  operands[0].map { |e| e.to_sparql(top_level: false, **options) }.join(". \n") +
  "\n}\n"

  str << operands[1].to_sparql(top_level: true, project: nil, **options)
end