Coverage report: /development/source/library/org/datagraph/spocq-shard/src/algebra/operators/graph.lisp
| Kind | Covered | All | % |
| expression | 98 | 158 | 62.0 |
| branch | 22 | 40 | 55.0 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;; -*- Mode: lisp; Syntax: ansi-common-lisp; Base: 10; Package: org.datagraph.spocq.implementation; -*-
3
(in-package :org.datagraph.spocq.implementation)
5
(:documentation "This file defines the for GRAPH operator interface for the 'org.datagraph.spocq'
9
"Copyright 2010 [james anderson](mailto:james.anderson@setf.de) All Rights Reserved.")
12
"The graph operator augments a constituent bgp with a term for the context/graph(s) against
13
which to match the triple paterns. The interfac eoperaotr rewrites the graph form into an
14
augmented bgp, by adding a graph form as one of the bgp's constituent terms, to be later used
15
as an aspect of the bgp match/resolution. This simple rewriting defers the actual matching logic, as
16
that depends on several other elements of the query expression and of the query environment.
18
- which (if any) graphs are specified by the request protocol or the dataset clause of the query
19
itself. (see SQL4RDF, section [8.2](http://www.w3.org/TR/rdf-sparql-query/#specifyingDataset).)
20
- which graphs are made available if no dataset is specified. these include
21
- the repository's default "graph", (designated in lisp as t, in rdfcache as the value of
22
rdfcache:*default-context-number*)
23
- the repository's named graphs
24
- the bindings matched elsewhere in the query for a variable in the graph clause.
25
- the presence of a literal value as the graph designaor in the graph clause.
27
The primitive triple match interface expresses both the pattern and the matches in terms of quads.
28
hat is, each includes a graph/contxt term. Each of the situations affect the argument and/or result
31
- if a bgp is within a graph clause, and the graph term is variable
32
- if named graphs are declared (via protocol or declared), then the match process iterates over
33
those graphs and specifies each in turn as the context/graph argument to the query operator.
34
if, in this case, the graph variable appears also elsewhere in the query, bgp ordering should
35
prefer the graph clause over other bgp clauses and either the respective solutions will
36
be unified or any propagation should be from the graph clause to the other clause(s).
37
- if no named graph is declared, the graph argument is specified as wild and the results
38
reflect matches among all named graphs in the repository. That domain does not include the
40
If, in this case, the graph variable appears also elsewhere in the query, bgp ordering should
41
prefer the other clause over the bgp clause and either the respective solutions will
42
be unified or any propagation should be from the other clause(s) to the graph clause.
44
- if a bgp is within a graph clause, and the graph term is a literal, then no iteration occurs.
45
That literal value is supplied as the context/graph term to the query operator. There is no effect
48
- if a bgp is autonomous, then the effective graph term still bound - implicitly, to the default graph(s).
49
- if non-named graphs are declared (via protocol or declared), then the match process iterates over
50
those graphs and specifies each in turn as the context/graph argument to the query operator.
51
- if no non-named graph is declared, then the graph argument is bound to the repository's default
52
graph. This is designated by the result of the rdfcache:*default-context-number*.
54
See store/processing.lisp for the implementation."))
56
(defparameter *graph-mode* ()
57
"a list of graph processing options")
59
(defmacro spocq.a:|graph| (name group-graph-pattern)
60
"( ( (or anyURI variable) graphPattern ) solutionField )
61
A GRAPH form modifies the application of a basic group graph pattern to either
62
- constrain its extent to the specific graph named by the constant IRI, or
63
- limit its domain to those named graphs enumerated in the dataset definition, or
64
- permit it to range over all named graphs.
65
In the latter two cases, the result solution field will include a binding for the respective graph
68
(macroexpand-graph name group-graph-pattern))
70
(defun macroexpand-graph (name group-graph-pattern)
71
"Walk the constituent expression and add the graph to any immediately apparent bgp.
72
Stop at any graph expression as that governs anything it its scope.
73
Any select - thus a subselect may have a projection. In which case, if the graph is a variable which
74
appears in the body but is not projected, then the body must be alpha-converted and the graph variable
75
added to the projection."
77
(if (and (find :implicit-federation *graph-mode*)
78
(not (eq (federation-mode) '|urn:dydra|:|none|))
80
(zerop (repository-pattern-count *repository* nil nil nil name)))
81
;; for implicit graph federations, rewrite the graph form to a service form
82
`(spocq.a:|service| ,name ,group-graph-pattern :silent t)
83
;; if either no federation at all, or limit to service forms
84
(labels ((projected-variable-p (variable projection-specification)
85
(loop for projection in projection-specification
86
when (typecase projection
87
(symbol (eq projection variable))
88
(cons (eq (first projection) variable)))
90
(split-projection-specification (projection-specification)
91
(values (loop while (keywordp (first projection-specification))
92
collect (pop projection-specification)
93
collect (pop projection-specification))
94
projection-specification))
95
(merge-dimension (name projection-specification)
96
(loop for projection in projection-specification
97
when (and name (string< name (etypecase projection
99
(cons (first projection)))))
100
collect (shiftf name nil)
102
(augment-bgps (expression)
103
(cond ((bgp-form-p expression)
104
`(spocq.a:|bgp| (spocq.a:|graph| ,name)
105
,@(rest expression)))
106
((graph-form-p expression)
107
;; copy the tree to prevent further rewriting
108
(copy-list expression))
109
((table-form-p expression)
110
`(spocq.a:|table| ,(when (variable-p name) (list name)) :graph ,name))
111
((select-form-p expression)
112
(destructuring-bind (select field-expression projection-specification &rest args)
114
(declare (ignore select))
115
(multiple-value-bind (aggregation-clauses projection-specification)
116
(split-projection-specification projection-specification)
117
(unless (consp projection-specification)
118
(setf projection-specification (expression-variables field-expression)))
119
;; account for variations in whether
120
;; - the graph name is projected
121
;; - it is present in the field expression
122
;; - it is added to some bgp in the field expression
123
(cond ((projected-variable-p name projection-specification)
124
;; iff the identical variable was projected, then the graph term shares scope with it
125
(setf field-expression (map-tree #'augment-bgps field-expression))
126
(setf projection-specification (expression-variables field-expression))
127
`(spocq.a:|select| ,field-expression ,projection-specification ,@args))
129
;; otherwise, alpha-convert to distinguish the graph variable from anything which
130
;; should not escape the select
131
(setf field-expression (map-tree #'augment-bgps
132
(sublis (list (cons name (cons-variable (string name))))
134
;; if the graph is visisble from some bgp, add it to the projection
135
(when (member name (expression-variables field-expression))
136
(setf projection-specification (merge-dimension name projection-specification)))
137
`(spocq.a:|select| ,field-expression ,(append aggregation-clauses projection-specification) ,@args))
139
;; non-variables can augment a bgp, but cannot change the projection
140
`(spocq.a:|select| ,(map-tree #'augment-bgps field-expression)
141
,(append aggregation-clauses projection-specification)
143
((service-form-p expression)
144
;; expand a base field, but otherwise just copy to prevent further rewriting
145
(destructuring-bind (op location group-graph-pattern &rest args) expression
146
(if (or (null args) (keywordp (first args)))
147
(copy-list expression)
148
(destructuring-bind (field &rest args) args
149
`(,op ,location ,group-graph-pattern ,(augment-bgps field) ,@args)))))
150
((revision-form-p expression)
151
;; propagate the graph in all cases
152
(destructuring-bind (op location group-graph-pattern &rest args) expression
153
(if (or (null args) (keywordp (first args)))
154
`(,op ,location ,(augment-bgps group-graph-pattern) ,@args)
155
(destructuring-bind (field &rest args) args
156
`(,op ,location ,group-graph-pattern ,(augment-bgps field) ,@args)))))
159
(declare (dynamic-extent #'augment-bgps))
160
(map-tree #'augment-bgps group-graph-pattern))))
163
;;; (spocq.a:|graph| ?::y (spocq.a:|bgp| (spocq.a:|triple| "aaa" ?::x (get-time))))
164
;;; (inspect (macroexpand '(spocq.a:|graph| ?::y (spocq.a:|bgp| (spocq.a:|triple| "aaa" ?::x (get-time))))))
165
;;; (spocq.a:|graph| "g" (spocq.a:|bgp| (spocq.a:|triple| "aaa" ?::x (get-time))))
169
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
170
PREFIX data: <http://example.org/foaf/>
173
FROM NAMED <http://example.org/foaf/aliceFoaf>
174
FROM NAMED <http://example.org/foaf/bobFoaf>
178
?x foaf:mbox <mailto:bob@work.example> .
180
OPTIONAL { ?y foaf:nick ?nickY }}