You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2013/04/23 22:26:31 UTC
svn commit: r1471133 - in /jena/trunk/jena-arq/src:
main/java/com/hp/hpl/jena/sparql/algebra/OpAsQuery.java
test/java/com/hp/hpl/jena/sparql/algebra/OpAsQueryTest.java
Author: rvesse
Date: Tue Apr 23 20:26:30 2013
New Revision: 1471133
URL: http://svn.apache.org/r1471133
Log:
Improve handling of sub-queries in OpAsQuery plus additional unit tests for this
Modified:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpAsQuery.java
jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/OpAsQueryTest.java
Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpAsQuery.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpAsQuery.java?rev=1471133&r1=1471132&r2=1471133&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpAsQuery.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/algebra/OpAsQuery.java Tue Apr 23 20:26:30 2013
@@ -44,30 +44,9 @@ import com.hp.hpl.jena.vocabulary.RDF ;
public class OpAsQuery
{
public static Query asQuery(Op op)
- {
- Query query = QueryFactory.make() ;
-
- Converter v = new Converter(query) ;
- //OpWalker.walk(op, v) ;
- op.visit(v) ;
-
- Collection<Var> vars = v.projectVars;
- query.setQueryResultStar(vars.isEmpty()); // SELECT * unless we are projecting
-
- Iterator<Var> iter = vars.iterator();
- for (; iter.hasNext();) {
- Var var = iter.next();
- if (v.varExpression.containsKey(var))
- query.addResultVar(var, v.varExpression.get(var));
- else
- query.addResultVar(var);
- }
-
- ElementGroup eg = v.currentGroup ;
- query.setQueryPattern(eg) ;
- query.setQuerySelectType() ;
- query.setResultVars() ; // Variables from the group.
- return query ;
+ {
+ Converter converter = new Converter(op) ;
+ return converter.convert();
}
private static Set<Var> allocProjectVars()
@@ -85,18 +64,52 @@ public class OpAsQuery
public static class Converter implements OpVisitor
{
private Query query ;
+ private Op op ;
private Element element = null ;
private ElementGroup currentGroup = null ;
private Deque<ElementGroup> stack = new ArrayDeque<ElementGroup>() ;
private Collection<Var> projectVars = allocProjectVars();
private Map<Var, Expr> varExpression = new HashMap<Var, Expr>() ;
private int groupDepth = 0;
+ private boolean inProject = false;
+ private boolean hasRun = false;
- public Converter(Query query)
+ public Converter(Op op)
{
- this.query = query ;
+ this.query = QueryFactory.create() ;
+ this.op = op;
currentGroup = new ElementGroup() ;
}
+
+ Query convert() {
+ if (hasRun) {
+ return this.query;
+ } else {
+ try {
+ op.visit(this) ;
+
+ Collection<Var> vars = this.projectVars;
+ query.setQueryResultStar(vars.isEmpty()); // SELECT * unless we are projecting
+
+ Iterator<Var> iter = vars.iterator();
+ for (; iter.hasNext();) {
+ Var var = iter.next();
+ if (this.varExpression.containsKey(var))
+ query.addResultVar(var, this.varExpression.get(var));
+ else
+ query.addResultVar(var);
+ }
+
+ ElementGroup eg = this.currentGroup ;
+ query.setQueryPattern(eg) ;
+ query.setQuerySelectType() ;
+ query.setResultVars() ; // Variables from the group.
+ return query ;
+ } finally {
+ this.hasRun = true;
+ }
+ }
+ }
Element asElement(Op op)
{
@@ -517,11 +530,22 @@ public class OpAsQuery
@Override
public void visit(OpProject opProject)
{
- // Defer adding result vars until the end.
- // OpGroup generates dupes otherwise
- this.projectVars = allocProjectVars() ;
- this.projectVars.addAll(opProject.getVars());
- opProject.getSubOp().visit(this) ;
+ if (inProject) {
+ // If we've already inside a project then we are reconstructing a sub-query
+ // Create a new converter and call on the sub-op to get the sub-query
+ Converter subConverter = new Converter(opProject);
+ ElementSubQuery subQuery = new ElementSubQuery(subConverter.convert());
+ ElementGroup g = currentGroup();
+ g.addElement(subQuery);
+ } else {
+ // Defer adding result vars until the end.
+ // OpGroup generates dupes otherwise
+ this.projectVars = allocProjectVars() ;
+ this.projectVars.addAll(opProject.getVars());
+ inProject = true;
+ opProject.getSubOp().visit(this) ;
+ inProject = false;
+ }
}
@Override
Modified: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/OpAsQueryTest.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/OpAsQueryTest.java?rev=1471133&r1=1471132&r2=1471133&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/OpAsQueryTest.java (original)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/algebra/OpAsQueryTest.java Tue Apr 23 20:26:30 2013
@@ -18,6 +18,8 @@
package com.hp.hpl.jena.sparql.algebra;
+import java.util.Map;
+
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.Query;
@@ -175,25 +177,14 @@ public class OpAsQueryTest {
" :documentType \"exam results\" ." ,
" BIND( mylib:DateFormat( xsd:string(?date), \"yyyy-MM\" ) as ?yearmonth )",
"} group by ?yearmonth") ;
-
- Query[] r = checkQuery(query);
- // Won't be equal due to lack of prefixes
- Assert.assertNotEquals(r[0], r[1]);
-
- String query2 = r[1].toString();
- Query q = QueryFactory.create(query2);
+ checkQueryParseable(query, true);
}
@Test
public void testExtend4() {
//Simplified repo of JENA-429
String query = "SELECT ?key (COUNT(?member) AS ?total) WHERE { ?s ?p ?o . BIND(LCASE(?o) AS ?key) } GROUP BY ?key";
-
- Query[] r = checkQuery(query);
- Assert.assertEquals(r[0], r[1]);
-
- String query2 = r[1].toString();
- Query q = QueryFactory.create(query2);
+ checkQueryParseable(query, true);
}
@Test
@@ -203,6 +194,34 @@ public class OpAsQueryTest {
assertEquals(result[0], result[1]);
assertTrue(result[1].toString().contains("BIND"));
}
+
+ @Test
+ public void testSubQuery1() {
+ String query = "SELECT ?s WHERE { { SELECT ?s ?p WHERE { ?s ?p ?o } } }";
+ checkQueryParseable(query, true);
+ }
+
+ @Test
+ public void testSubQuery2() {
+ String query = "SELECT ?s ?x WHERE { { SELECT ?s ?p WHERE { ?s ?p ?o } } { SELECT ?x WHERE { ?x ?p ?o } } }";
+ //These end up being non-equal queries because the nesting in the final query is a little funky
+ //but the results should still be semantically equivalent
+ checkQueryParseable(query, false);
+ }
+
+ @Test
+ public void testAggregatesInSubQuery1() {
+ //Simplified form of a test case provided via the mailing list
+ String query = "SELECT ?key ?agg WHERE { { SELECT ?key (COUNT(*) AS ?agg) { ?key ?p ?o } GROUP BY ?key } }";
+ checkQueryParseable(query, true);
+ }
+
+ @Test
+ public void testAggregatesInSubQuery2() {
+ //Simplified form of a test case provided via the mailing list
+ String query = "SELECT * WHERE { { SELECT ?key (COUNT(*) AS ?agg) { ?key ?p ?o } GROUP BY ?key } }";
+ checkQueryParseable(query, false);
+ }
public Query[] checkQuery(String query) {
Query orig = QueryFactory.create(query, Syntax.syntaxSPARQL_11);
@@ -212,7 +231,7 @@ public class OpAsQueryTest {
return r;
}
- public Object[] checkQuadQuery(String query) {
+ public Query[] checkQuadQuery(String query) {
Query orig = QueryFactory.create(query, Syntax.syntaxSPARQL_11);
Op toReconstruct = Algebra.compile(orig);
toReconstruct = Algebra.toQuadForm(toReconstruct);
@@ -220,4 +239,29 @@ public class OpAsQueryTest {
Query[] r = { orig, got };
return r;
}
+
+ public Query[] checkQueryParseable(String query, boolean expectEquals) {
+ Query[] r = checkQuery(query);
+
+ //Strip namespaces and Base URI from each so comparison is not affected by those
+ stripNamespacesAndBase(r[0]);
+ stripNamespacesAndBase(r[1]);
+
+ if (expectEquals) {
+ Assert.assertEquals(r[0], r[1]);
+ } else {
+ Assert.assertNotEquals(r[0], r[1]);
+ }
+ String query2 = r[1].toString();
+ Query q = QueryFactory.create(query2);
+ return r;
+ }
+
+ protected void stripNamespacesAndBase(Query q) {
+ Map<String, String> prefixes = q.getPrefixMapping().getNsPrefixMap();
+ for (String prefix : prefixes.keySet()) {
+ q.getPrefixMapping().removeNsPrefix(prefix);
+ }
+ q.setBaseURI((String)null);
+ }
}