You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by bu...@apache.org on 2012/01/25 00:39:41 UTC
svn commit: r803222 - in
/websites/staging/jena/trunk/content/jena/documentation/query: index.html
manipulating_sparql_using_arq.html
Author: buildbot
Date: Tue Jan 24 23:39:41 2012
New Revision: 803222
Log:
Staging update by buildbot for jena
Added:
websites/staging/jena/trunk/content/jena/documentation/query/manipulating_sparql_using_arq.html
Modified:
websites/staging/jena/trunk/content/jena/documentation/query/index.html
Modified: websites/staging/jena/trunk/content/jena/documentation/query/index.html
==============================================================================
--- websites/staging/jena/trunk/content/jena/documentation/query/index.html (original)
+++ websites/staging/jena/trunk/content/jena/documentation/query/index.html Tue Jan 24 23:39:41 2012
@@ -185,6 +185,7 @@ SPARQL is the query language developed b
<li><a href="cmds.html">Command line utilities</a></li>
<li><a href="logging.html">Logging</a></li>
<li><a href="explain.html">Explaining queries</a></li>
+<li><a href="manipulating_sparql_using_arq.html">Tutorial: manipulating SPARQL using ARQ</a></li>
</ul>
<h2 id="advanced_sparql_use">Advanced SPARQL use</h2>
<p>Features of ARQ that are legal SPARQL syntax.</p>
Added: websites/staging/jena/trunk/content/jena/documentation/query/manipulating_sparql_using_arq.html
==============================================================================
--- websites/staging/jena/trunk/content/jena/documentation/query/manipulating_sparql_using_arq.html (added)
+++ websites/staging/jena/trunk/content/jena/documentation/query/manipulating_sparql_using_arq.html Tue Jan 24 23:39:41 2012
@@ -0,0 +1,360 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE- 2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+ <link href="/jena/css/jena.css" rel="stylesheet" type="text/css">
+ <title>Apache Jena - Tutorial - Manipulating SPARQL using ARQ</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <script src="/jena/js/jquery-1.6.4.min.js" type="text/javascript"></script>
+ <script src="/jena/js/jena-navigation.js" type="text/javascript"></script>
+</head>
+
+<body>
+ <div id="header">
+ <div id="logoblock">
+ <img alt="Apache Jena" src="/jena/images/jena-logo/jena-logo-small.png"/>
+ </div>
+
+ <div id="titleblock">
+ <h1 class="title">Apache Jena</h1>
+ <div id="topmenu" class="tabbar round-10">
+ <ul>
+ <li class="round-top-8"><a class="round-top-8" href="/jena/index.html" id="home_menu">Home</a></li>
+ <li class="round-top-8"><a class="round-top-8" href="/jena/help_and_support/index.html">Support</a></li>
+ <li class="round-top-8"><a class="round-top-8" href="/jena/getting_started/index.html">Getting started</a></li>
+ <li class="round-top-8"><a class="round-top-8" href="/jena/tutorials/index.html">Tutorials</a></li>
+ <li class="round-top-8"><a class="round-top-8" href="/jena/documentation/index.html">Documentation</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div id="navigation" class="clear">
+ <h1 id="quick_links">Quick links</h1>
+<ul>
+<li><a href="/jena/index.html">Home</a></li>
+<li><a href="/jena/download/index.html">Downloads</a></li>
+<li><a href="/jena/help_and_support/index.html">Help and support</a></li>
+<li><a href="/jena/help_and_support/bugs_and_suggestions.html">Report a bug</a></li>
+<li><a href="/jena/about_jena/roadmap.html">Roadmap</a></li>
+<li><a href="/jena/getting_involved/index.html">Getting involved</a></li>
+<li><a href="/jena/documentation/">Documentation</a></li>
+</ul>
+<h1 id="about_jena">About Jena</h1>
+<ul>
+<li><a href="/jena/index.html">Home</a></li>
+<li><a href="/jena/about_jena/about.html">About Jena</a></li>
+<li><a href="/jena/about_jena/architecture.html">Architecture</a></li>
+<li><a href="/jena/about_jena/roadmap.html">Roadmap</a></li>
+<li><a href="/jena/about_jena/team.html">Project team</a></li>
+<li><a href="/jena/about_jena/contributions.html">Related projects</a></li>
+</ul>
+<h1 id="download">Download</h1>
+<ul>
+<li><a href="/jena/download/index.html">Downloading Jena</a></li>
+<li><a href="/jena/download/maven.html">Using Maven</a></li>
+<li><a href="/jena/download/osgi.html">Using OSGi</a></li>
+</ul>
+<h1 id="help_and_support">Help and support</h1>
+<ul>
+<li><a href="/jena/help_and_support/index.html">Getting help</a></li>
+<li><a href="/jena/help_and_support/bugs_and_suggestions.html">Bugs and suggestions</a></li>
+</ul>
+<h1 id="getting_started">Getting Started</h1>
+<ul>
+<li><a href="/jena/getting_started/index.html">A first Jena project</a></li>
+<li><a href="/jena/getting_started/rdf_api.html">RDF API overview</a></li>
+<li><a href="/jena/getting_started/sparql.html">Querying RDF with SPARQL</a></li>
+<li><a href="/jena/getting_started/fuseki.html">Serving RDF over HTTP</a></li>
+<li><a href="/jena/getting_started/tell_me_how.html">Tell me how to ...</a></li>
+</ul>
+<h1 id="tutorials">Tutorials</h1>
+<ul>
+<li><a href="/jena/tutorials/index.html">Tutorials index</a></li>
+<li><a href="/jena/tutorials/rdf_api.html">RDF tutorial</a></li>
+<li><a href="/jena/tutorials/sparql.html">SPARQL queries</a></li>
+<li><a href="/jena/tutorials/using_jena_with_eclipse.html">Using Jena with Eclipse</a></li>
+</ul>
+<h1 id="documentation">Documentation</h1>
+<ul>
+<li><a href="/jena/documentation/index.html">Overview</a></li>
+<li><a href="/jena/documentation/javadoc">Javadoc</a></li>
+<li><a href="/jena/documentation/rdf/index.html">RDF</a></li>
+<li><a href="/jena/documentation/query/index.html">SPARQL (ARQ)</a><ul>
+<li><a href="/jena/documentation/query/app_api.html">Application API</a></li>
+<li><a href="/jena/documentation/query/cmds.html">Command line utilities</a></li>
+</ul>
+</li>
+<li><a href="/jena/documentation/tdb/index.html">TDB</a><ul>
+<li><a href="/jena/documentation/tdb/tdb_transactions.html">API for Transactions</a></li>
+<li><a href="/jena/documentation/tdb/assembler.html">Dataset Assembler</a></li>
+</ul>
+</li>
+<li><a href="/jena/documentation/sdb/index.html">SDB</a></li>
+<li><a href="/jena/documentation/larq/index.html">LARQ</a></li>
+<li><a href="/jena/documentation/serving_data/index.html">Fuseki: Serving Data</a></li>
+<li><a href="/jena/documentation/ontology/index.html">Ontology</a></li>
+<li><a href="/jena/documentation/inference/index.html">Inference</a></li>
+<li><a href="/jena/documentation/assembler/index.html">Assembler</a><ul>
+<li><a href="/jena/documentation/assembler/assembler-howto.html">Assembler how-to</a></li>
+<li><a href="/jena/documentation/assembler/inside-assemblers.html">Inside assemblers</a></li>
+</ul>
+</li>
+<li><a href="/jena/documentation/io/index.html">I/O</a><ul>
+<li><a href="/jena/documentation/io/iohowto.html">I/O how-to</a></li>
+<li><a href="/jena/documentation/io/riot.html">RIOT</a></li>
+</ul>
+</li>
+<li><a href="/jena/documentation/notes/index.html">Notes</a><ul>
+<li><a href="/jena/documentation/notes/concurrency-howto.html">Concurrency how-to</a></li>
+<li><a href="/jena/documentation/notes/event-handler-howto.html">Event handler how-to</a></li>
+<li><a href="/jena/documentation/notes/file-manager.html">File manager how-to</a></li>
+<li><a href="/jena/documentation/notes/model-factory.html">Model factory how-to</a></li>
+<li><a href="/jena/documentation/notes/rdf-frames.html">RDF frames</a></li>
+<li><a href="/jena/documentation/notes/reification.html">Reification how-to</a></li>
+<li><a href="/jena/documentation/notes/typed-literals.html">Typed literals how-to</a></li>
+<li><a href="/jena/documentation/notes/iri.html">Support for IRI's</a></li>
+</ul>
+</li>
+<li><a href="/jena/documentation/tools/index.html">Tools</a><ul>
+<li><a href="/jena/documentation/tools/schemagen.html">schemagen</a></li>
+<li><a href="/jena/documentation/tools/eyeball-getting-started.html">eyeball</a></li>
+</ul>
+</li>
+</ul>
+<h1 id="getting_involved">Getting Involved</h1>
+<ul>
+<li><a href="/jena/getting_involved/index.html">Contributing to Jena</a></li>
+</ul>
+<h1 id="asf_links">ASF links</h1>
+<ul>
+<li><a href="http://www.apache.org">Apache Software Foundation</a></li>
+<li><a href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li>
+<li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
+<li><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a></li>
+<li><a href="http://www.apache.org/security/">Security</a></li>
+</ul>
+ </div>
+
+ <div id="content">
+ <h1 class="title">Tutorial - Manipulating SPARQL using ARQ</h1>
+ <p>When you've been working with SPARQL you quickly find that static
+queries are restrictive. Maybe you want to vary a value, perhaps add a
+filter, alter the limit, etc etc. Being an impatient sort you dive in to
+the query string, and it works. But what about <a href="http://xkcd.com/327/">little Bobby
+Tables</a>? And, even if you
+sanitise your inputs, string manipulation is a fraught process and
+syntax errors await you. Although it might seem harder than string
+munging, the ARQ API is your friend in the long run.</p>
+<p><em>Originally published on the <a href="http://researchrevealed.ilrt.bris.ac.uk/?p=35">Research Revealed project
+blog</a></em></p>
+<h2 id="inserting_values_simple_prepared_statements">Inserting values (simple prepared statements)</h2>
+<p>Let's begin with something simple. Suppose we wanted to restrict the
+following query to a particular person:</p>
+<div class="codehilite"><pre> <span class="nb">select</span> <span class="o">*</span> <span class="p">{</span><span class="err">Â </span><span class="p">?</span><span class="n">person</span> <span class="sr"><http://xmlns.com/foaf/0.1/name></span><span class="err">Â </span><span class="p">?</span><span class="n">name</span> <span class="p">}</span>
+</pre></div>
+
+
+<p><code>String#replaceAll</code> would work, but there is a safer way.
+<code>QueryExecutionFactory</code> in most cases lets you supply a <code>QuerySolution</code>
+with which you can prebind values.</p>
+<div class="codehilite"><pre> <span class="n">QuerySolutionMap</span> <span class="n">initialBinding</span> <span class="o">=</span> <span class="k">new</span> <span class="n">QuerySolutionMap</span><span class="p">();</span>
+ <span class="n">initialBinding</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s">"name"</span><span class="p">,</span> <span class="n">personResource</span><span class="p">);</span>
+ <span class="n">qe</span> <span class="o">=</span> <span class="n">QueryExecutionFactory</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">dataset</span><span class="p">,</span> <span class="n">initialBinding</span><span class="p">);</span>
+</pre></div>
+
+
+<p>This is often much simpler than the string equivalent since you don't
+have to escape quotes in literals. (Beware that this doesn't work for
+<code>sparqlService</code>, which is a great shame. It would be nice to spend some
+time remedying that.)</p>
+<h2 id="making_a_query_from_scratch">Making a Query from Scratch</h2>
+<p>The previously mentioned limitation is due to the fact that prebinding
+doesn't actually change the query at all, but the execution of that
+query. So what how do we really alter queries?</p>
+<p>ARQ provides two ways to work with queries: at the syntax level (<code>Query</code>
+and <code>Element</code>), or the algebra level (<code>Op</code>). The distinction is clear in
+filters:</p>
+<div class="codehilite"><pre> <span class="n">SELECT</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="p">{</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="sr"><http://example.com/val></span><span class="err">Â </span><span class="p">?</span><span class="n">val</span> <span class="o">.</span> <span class="n">FILTER</span> <span class="p">(</span><span class="err">Â </span><span class="p">?</span><span class="n">val</span> <span class="o"><</span> <span class="mi">20</span> <span class="p">)</span> <span class="p">}</span>
+</pre></div>
+
+
+<p>If you work at the syntax level you'll find that this looks (in pseudo
+code) like:</p>
+<div class="codehilite"><pre> <span class="p">(</span><span class="n">GROUP</span> <span class="p">(</span><span class="n">PATTERN</span> <span class="p">(</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="sr"><http://example.com/val></span><span class="err">Â </span><span class="p">?</span><span class="n">val</span> <span class="p">))</span> <span class="p">(</span><span class="n">FILTER</span> <span class="p">(</span> <span class="o"><</span><span class="err">Â </span><span class="p">?</span><span class="n">val</span> <span class="mi">20</span> <span class="p">)</span> <span class="p">))</span>
+</pre></div>
+
+
+<p>That is there's a group containing a triple pattern and a filter, just
+as you see in the query. The algebra is different, and we can see it
+using <code>arq.qparse --print op</code></p>
+<div class="codehilite"><pre> <span class="nv">$</span> <span class="nv">java</span> <span class="n">arq</span><span class="o">.</span><span class="n">qparse</span> <span class="o">--</span><span class="k">print</span> <span class="n">op</span> <span class="s">'SELECTÂ ?s {Â ?s <http://example.com/val>Â ?val . FILTER (Â ?val < 20 ) }'</span>
+ <span class="p">(</span><span class="n">base</span> <span class="sr"><file:///...></span>
+ <span class="p">(</span><span class="n">project</span> <span class="p">(?</span><span class="n">s</span><span class="p">)</span>
+ <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="o"><</span><span class="err">Â </span><span class="p">?</span><span class="n">val</span> <span class="mi">20</span><span class="p">)</span>
+ <span class="p">(</span><span class="n">bgp</span> <span class="p">(</span><span class="n">triple</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="sr"><http://example.com/val></span><span class="err">Â </span><span class="p">?</span><span class="n">val</span><span class="p">)))))</span>
+</pre></div>
+
+
+<p>Here the filter contains the pattern, rather than sitting next to it.
+This form makes it clear that the expression is filtering the pattern.</p>
+<p>Let's create that query from scratch using ARQ. We begin with some
+common pieces: the triple to match, and the expression for the filter.</p>
+<div class="codehilite"><pre> <span class="sr">//</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span><span class="err">Â </span><span class="p">?</span><span class="n">p</span><span class="err">Â </span><span class="p">?</span><span class="n">o</span> <span class="o">.</span>
+ <span class="n">Triple</span> <span class="n">pattern</span> <span class="o">=</span>
+ <span class="n">Triple</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">Var</span><span class="o">.</span><span class="n">alloc</span><span class="p">(</span><span class="s">"s"</span><span class="p">),</span> <span class="n">Var</span><span class="o">.</span><span class="n">alloc</span><span class="p">(</span><span class="s">"p"</span><span class="p">),</span> <span class="n">Var</span><span class="o">.</span><span class="n">alloc</span><span class="p">(</span><span class="s">"o"</span><span class="p">));</span>
+ <span class="sr">//</span> <span class="p">(</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="o"><</span> <span class="mi">20</span> <span class="p">)</span>
+ <span class="n">Expr</span> <span class="n">e</span> <span class="o">=</span> <span class="k">new</span> <span class="n">E_LessThan</span><span class="p">(</span><span class="k">new</span> <span class="n">ExprVar</span><span class="p">(</span><span class="s">"s"</span><span class="p">),</span> <span class="k">new</span> <span class="n">NodeValueInteger</span><span class="p">(</span><span class="mi">20</span><span class="p">));</span>
+</pre></div>
+
+
+<p><code>Triple</code> should be familiar from jena. <code>Var</code> is an extension of <code>Node</code>
+for variables. <code>Expr</code> is the root interface for expressions, those
+things that appear in <code>FILTER</code> and <code>LET</code>.</p>
+<p>First the syntax route:</p>
+<div class="codehilite"><pre> <span class="n">ElementTriplesBlock</span> <span class="n">block</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ElementTriplesBlock</span><span class="p">();</span> <span class="sr">//</span> <span class="n">Make</span> <span class="n">a</span> <span class="n">BGP</span>
+ <span class="n">block</span><span class="o">.</span><span class="n">addTriple</span><span class="p">(</span><span class="n">pattern</span><span class="p">);</span> <span class="sr">//</span> <span class="n">Add</span> <span class="k">our</span> <span class="n">pattern</span> <span class="n">match</span>
+ <span class="n">ElementFilter</span> <span class="n">filter</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ElementFilter</span><span class="p">(</span><span class="n">e</span><span class="p">);</span> <span class="sr">//</span> <span class="n">Make</span> <span class="n">a</span> <span class="n">filter</span> <span class="n">matching</span> <span class="n">the</span> <span class="n">expression</span>
+ <span class="n">ElementGroup</span> <span class="n">body</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ElementGroup</span><span class="p">();</span> <span class="sr">//</span> <span class="n">Group</span> <span class="k">our</span> <span class="n">pattern</span> <span class="n">match</span> <span class="ow">and</span> <span class="n">filter</span>
+ <span class="n">body</span><span class="o">.</span><span class="n">addElement</span><span class="p">(</span><span class="n">block</span><span class="p">);</span>
+ <span class="n">body</span><span class="o">.</span><span class="n">addElement</span><span class="p">(</span><span class="n">filter</span><span class="p">);</span>
+
+ <span class="n">Query</span> <span class="sx">q = </span><span class="n">QueryFactory</span><span class="o">.</span><span class="n">make</span><span class="p">();</span>
+ <span class="sx">q.setQueryPattern(body); // Set the body of the query to our group</span>
+<span class="sx"> q.</span><span class="n">setQuerySelectType</span><span class="p">();</span> <span class="sr">//</span> <span class="n">Make</span> <span class="n">it</span> <span class="n">a</span> <span class="nb">select</span> <span class="n">query</span>
+ <span class="n">q</span><span class="o">.</span><span class="n">addResultVar</span><span class="p">(</span><span class="s">"s"</span><span class="p">);</span> <span class="sr">//</span> <span class="n">Select</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span>
+</pre></div>
+
+
+<p>Now the algebra:</p>
+<div class="codehilite"><pre> <span class="n">Op</span> <span class="n">op</span><span class="p">;</span>
+ <span class="n">BasicPattern</span> <span class="n">pat</span> <span class="o">=</span> <span class="k">new</span> <span class="n">BasicPattern</span><span class="p">();</span> <span class="sr">//</span> <span class="n">Make</span> <span class="n">a</span> <span class="n">pattern</span>
+ <span class="n">pat</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">pattern</span><span class="p">);</span> <span class="sr">//</span> <span class="n">Add</span> <span class="k">our</span> <span class="n">pattern</span> <span class="n">match</span>
+ <span class="n">op</span> <span class="o">=</span> <span class="k">new</span> <span class="n">OpBGP</span><span class="p">(</span><span class="n">pat</span><span class="p">);</span> <span class="sr">//</span> <span class="n">Make</span> <span class="n">a</span> <span class="n">BGP</span> <span class="n">from</span> <span class="n">this</span> <span class="n">pattern</span>
+ <span class="n">op</span> <span class="o">=</span> <span class="n">OpFilter</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">op</span><span class="p">);</span> <span class="sr">//</span> <span class="n">Filter</span> <span class="n">that</span> <span class="n">pattern</span> <span class="n">with</span> <span class="k">our</span> <span class="n">expression</span>
+ <span class="n">op</span> <span class="o">=</span> <span class="k">new</span> <span class="n">OpProject</span><span class="p">(</span><span class="n">op</span><span class="p">,</span> <span class="n">Arrays</span><span class="o">.</span><span class="n">asList</span><span class="p">(</span><span class="n">Var</span><span class="o">.</span><span class="n">alloc</span><span class="p">(</span><span class="s">"s"</span><span class="p">)));</span> <span class="sr">//</span> <span class="n">Reduce</span> <span class="n">to</span> <span class="n">just</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span>
+ <span class="n">Query</span> <span class="sx">q = </span><span class="n">OpAsQuery</span><span class="o">.</span><span class="n">asQuery</span><span class="p">(</span><span class="n">op</span><span class="p">);</span> <span class="sr">//</span> <span class="n">Convert</span> <span class="n">to</span> <span class="n">a</span> <span class="n">query</span>
+ <span class="n">q</span><span class="o">.</span><span class="n">setQuerySelectType</span><span class="p">();</span> <span class="sr">//</span> <span class="n">Make</span> <span class="n">is</span> <span class="n">a</span> <span class="nb">select</span> <span class="n">query</span>
+</pre></div>
+
+
+<p>Notice that the query form (<code>SELECT, CONSTRUCT, DESCRIBE, ASK</code>) isn't
+part of the algebra, and we have to set this in the query (although
+SELECT is the default). <code>FROM</code> and <code>FROM NAMED</code> are similarly absent.</p>
+<h2 id="navigating_and_tinkering_visitors">Navigating and Tinkering: Visitors</h2>
+<p>You can also look around the algebra and syntax using visitors. Start by
+extending <code>OpVisitorBase</code> (<code>ElementVisitorBase</code>) which stubs out the
+interface so you can concentrate on the parts of interest, then walk
+using <code>OpWalker.walk(Op, OpVisitor)</code>
+(<code>ElementWalker.walk(Element, ElementVisitor)</code>). These work bottom up.</p>
+<p>For some alterations, like manipulating triple matches in place,
+visitors will do the trick. They provide a simple way to get to the
+right parts of the query, and you can alter the pattern backing BGPs in
+both the algebra and syntax. Mutation isn't consistently available,
+however, so don't depend on it.</p>
+<h2 id="transforming_the_algebra">Transforming the Algebra</h2>
+<p>So far there is no obvious advantage in using the algebra. The real
+power is visible in transformers, which allow you to reorganise an
+algebra completely. ARQ makes extensive use of transformations to
+simplify and optimise query execution.</p>
+<p>In Research Revealed I wrote some code to take a number of constraints
+and produce a query. There were a number of ways to do this, but one way
+I found was to generate ops from each constraint and join the results:</p>
+<div class="codehilite"><pre> <span class="k">for</span> <span class="p">(</span><span class="n">Constraint</span> <span class="n">con:</span> <span class="n">cons</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">op</span> <span class="o">=</span> <span class="n">OpJoin</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">op</span><span class="p">,</span> <span class="n">consToOp</span><span class="p">(</span><span class="n">cons</span><span class="p">));</span> <span class="sr">//</span> <span class="nb">join</span>
+ <span class="p">}</span>
+</pre></div>
+
+
+<p>The result was a perfectly correct mess, which is only barely readable
+with just three conditions:</p>
+<div class="codehilite"><pre> <span class="p">(</span><span class="nb">join</span>
+ <span class="p">(</span><span class="nb">join</span>
+ <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="o"><</span><span class="err">Â </span><span class="p">?</span><span class="n">o0</span> <span class="mi">20</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp</span> <span class="p">(</span><span class="n">triple</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="sr"><urn:ex:prop0></span><span class="err">Â </span><span class="p">?</span><span class="n">o0</span><span class="p">)))</span>
+ <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="o"><</span><span class="err">Â </span><span class="p">?</span><span class="n">o1</span> <span class="mi">20</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp</span> <span class="p">(</span><span class="n">triple</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="sr"><urn:ex:prop1></span><span class="err">Â </span><span class="p">?</span><span class="n">o1</span><span class="p">))))</span>
+ <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="o"><</span><span class="err">Â </span><span class="p">?</span><span class="n">o2</span> <span class="mi">20</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp</span> <span class="p">(</span><span class="n">triple</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="sr"><urn:ex:prop2></span><span class="err">Â </span><span class="p">?</span><span class="n">o2</span><span class="p">))))</span>
+</pre></div>
+
+
+<p>Each of the constraints is a filter on a bgp. This can be made much more
+readable by moving the filters out, and merging the triple patterns. We
+can do this with the following <code>Transform</code>:</p>
+<div class="codehilite"><pre> <span class="n">class</span> <span class="n">QueryCleaner</span> <span class="n">extends</span> <span class="n">TransformBase</span>
+ <span class="p">{</span>
+ <span class="nv">@Override</span>
+ <span class="n">public</span> <span class="n">Op</span> <span class="n">transform</span><span class="p">(</span><span class="n">OpJoin</span> <span class="nb">join</span><span class="p">,</span> <span class="n">Op</span> <span class="n">left</span><span class="p">,</span> <span class="n">Op</span> <span class="n">right</span><span class="p">)</span> <span class="p">{</span>
+ <span class="sr">//</span> <span class="n">Bail</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">of</span> <span class="n">the</span> <span class="n">right</span> <span class="n">form</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">left</span> <span class="n">instanceof</span> <span class="n">OpFilter</span> <span class="o">&&</span> <span class="n">right</span> <span class="n">instanceof</span> <span class="n">OpFilter</span><span class="p">))</span> <span class="k">return</span> <span class="nb">join</span><span class="p">;</span>
+ <span class="n">OpFilter</span> <span class="n">leftF</span> <span class="o">=</span> <span class="p">(</span><span class="n">OpFilter</span><span class="p">)</span> <span class="n">left</span><span class="p">;</span>
+ <span class="n">OpFilter</span> <span class="n">rightF</span> <span class="o">=</span> <span class="p">(</span><span class="n">OpFilter</span><span class="p">)</span> <span class="n">right</span><span class="p">;</span>
+
+ <span class="sr">//</span> <span class="n">Add</span> <span class="n">all</span> <span class="n">of</span> <span class="n">the</span> <span class="n">triple</span> <span class="n">matches</span> <span class="n">to</span> <span class="n">the</span> <span class="n">LHS</span> <span class="n">BGP</span>
+ <span class="p">((</span><span class="n">OpBGP</span><span class="p">)</span> <span class="n">leftF</span><span class="o">.</span><span class="n">getSubOp</span><span class="p">())</span><span class="o">.</span><span class="n">getPattern</span><span class="p">()</span><span class="o">.</span><span class="n">addAll</span><span class="p">(((</span><span class="n">OpBGP</span><span class="p">)</span> <span class="n">rightF</span><span class="o">.</span><span class="n">getSubOp</span><span class="p">())</span><span class="o">.</span><span class="n">getPattern</span><span class="p">());</span>
+ <span class="sr">//</span> <span class="n">Add</span> <span class="n">the</span> <span class="n">RHS</span> <span class="n">filter</span> <span class="n">to</span> <span class="n">the</span> <span class="n">LHS</span>
+ <span class="n">leftF</span><span class="o">.</span><span class="n">getExprs</span><span class="p">()</span><span class="o">.</span><span class="n">addAll</span><span class="p">(</span><span class="n">rightF</span><span class="o">.</span><span class="n">getExprs</span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">leftF</span><span class="p">;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="o">...</span>
+ <span class="n">op</span> <span class="o">=</span> <span class="n">Transformer</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="k">new</span> <span class="n">QueryCleaner</span><span class="p">(),</span> <span class="n">op</span><span class="p">);</span> <span class="sr">//</span> <span class="n">clean</span> <span class="n">query</span>
+</pre></div>
+
+
+<p>This looks for joins of the form:</p>
+<div class="codehilite"><pre> <span class="p">(</span><span class="nb">join</span>
+ <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="n">exp1</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp1</span><span class="p">))</span>
+ <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="n">exp2</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp2</span><span class="p">)))</span>
+</pre></div>
+
+
+<p>And replaces it with:</p>
+<div class="codehilite"><pre> <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="n">exp1</span> <span class="o">&&</span> <span class="n">exp2</span><span class="p">)</span> <span class="p">(</span><span class="n">bgp1</span> <span class="o">&&</span> <span class="n">bgp2</span><span class="p">))</span>
+</pre></div>
+
+
+<p>As we go through the original query all joins are removed, and the
+result is:</p>
+<div class="codehilite"><pre> <span class="p">(</span><span class="n">filter</span> <span class="p">(</span><span class="n">exprlist</span> <span class="p">(</span><span class="o"><</span><span class="err">Â </span><span class="p">?</span><span class="n">o0</span> <span class="mi">20</span><span class="p">)</span> <span class="p">(</span><span class="o"><</span><span class="err">Â </span><span class="p">?</span><span class="n">o1</span> <span class="mi">20</span><span class="p">)</span> <span class="p">(</span><span class="o"><</span><span class="err">Â </span><span class="p">?</span><span class="n">o2</span> <span class="mi">20</span><span class="p">))</span>
+ <span class="p">(</span><span class="n">bgp</span>
+ <span class="p">(</span><span class="n">triple</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="sr"><urn:ex:prop0></span><span class="err">Â </span><span class="p">?</span><span class="n">o0</span><span class="p">)</span>
+ <span class="p">(</span><span class="n">triple</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="sr"><urn:ex:prop1></span><span class="err">Â </span><span class="p">?</span><span class="n">o1</span><span class="p">)</span>
+ <span class="p">(</span><span class="n">triple</span><span class="err">Â </span><span class="p">?</span><span class="n">s</span> <span class="sr"><urn:ex:prop2></span><span class="err">Â </span><span class="p">?</span><span class="n">o2</span><span class="p">)</span>
+ <span class="p">))</span>
+</pre></div>
+
+
+<p>That completes this brief introduction. There is much more to ARQ, of
+course, but hopefully you now have a taste for what it can do.</p>
+ </div>
+
+ <div id="footer">
+ <div class="copyright">
+ <p>
+ Copyright © 2011–12 The Apache Software Foundation, Licensed under
+ the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.
+ <br />
+ Apache Jena, Jena, the Apache Jena project logo,
+ Apache and the Apache feather logos are trademarks of The Apache Software Foundation.
+ </p>
+ </div>
+ </div>
+
+</body>
+</html>