This document expands on the notes in http://fireball.danbri.org/people/danbri/2002/02/java/rewriter/doc/inkling-query-rewriter.html with the goal of explaining the Squish2SQL convertor with a worked example. We take an example test1.squish and highlight the connection between the parts of both query (since URIs and literals as mangled into integers, this is especially useful).
Annotated output from Squish2SQL follows. The raw output was generated with:
java -cp jars/rewrite-helpers.jar Squish2SQL sql/test1.squish
SELECT ?thumb, ?name, ?mbox
WHERE
### predicate, subject, object ###########################
### ##
(foaf::depiction ?x ?uri) ## a1
* (foaf::depiction ?z ?uri) ## a2
(foaf::mbox ?x mailto:libby.miller@bristol.ac.uk) ## a3
(foaf::mbox ?z ?mbox) ## a4
* (foaf::name ?z ?name) ## a5
(foaf::thumbnail ?uri ?thumb) ## a6
* (dc::description ?uri ?dd) ## a7
USING foaf for http://xmlns.com/foaf/0.1/
dc for http://purl.org/dc/elements/1.1/
resources 'b*': variables in order used are ?x, ?uri, ?z, ?mbox,
?name, ?thumb, ?dd. Are the '2', '5' and '7's in related to a2, a5,
a7? assuming not.
b1
b2: mbox
b3
b4
b5: thumb
b6:
b7: name
Notes: the numbers for a's correspond to the where-clause rows. b2, b5 and b7 are bound to specific resources/literals, and correspond as follows: b2=mbox, b5=thumb, b7=name.
SELECT DISTINCT
b2.value AS mbox, b5.value AS thumb, b7.value AS name
FROM
triples a1, triples a2, triples a3, triples a4, triples a5, triples a6, triples a7, ## rows
resources b2, resources b5, resources b7 ## num variables asked for
WHERE a1.predicate = '116868652' ## foaf::depiction
AND a2.predicate = '116868652' ## foaf::depiction
AND a3.predicate = '1547507681' ## foaf::mbox
AND a3.object = '1145937192' ## mailto:libby.miller@bristol.ac.uk
AND a4.predicate = '1547507681' ## foaf::mbox
AND a5.predicate = '1577895888' ## foaf::name
AND a6.predicate = '-1848367484' ## foaf::thumbnail
AND a7.predicate = '-221079518' ## dc::description
AND a1.subject=a3.subject ## ?x a1, a3
AND a1.object=a2.object ## ?uri a1, a2
AND a2.object=a6.subject ## ?z a2, a6
AND a6.subject=a7.subject ## ?uri a6, a7
AND a2.subject=a4.subject ## ?z a2, a4
AND a4.subject=a5.subject ## ?z a4, a5
AND b2.key=a4.object ## ?mbox a4
AND b5.key=a6.object ## ?thumb a6
AND b7.key=a5.object ## ?name a5
Notes extracted from .java version:
//this is just for the a* variables
Hashtable realToSqlVariableNameMapA
//we need a1.subject=b1.subject - that's what this hash does.
Hashtable sqlVariableMatchAB;
sqlVariableNamesB = new Vector();
...when looping through WHERE clauses, each time:
clauses.each { |clause|
pred_bound = false
subject_bound = false
object_bound = false
allQueryVariables.each { |varname|
if s.equals(varname)
realToSqlVarname_A[varname]= "a"+id_a_clause
subject_bound = 1
end
if p.equals(varname)
realToSqlVarname_A[varname]= "a"+id+a_clause
end
if o.equals(varname)
realToSqlVarname_A[varname]= "a"+id_a_clause
end
}
sh1_sub=intToHashCode(s)
sh1_pred=etc
sh1_pobj=
}
The conversion algorithm required should be obvious. Enjoy.