You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2022/06/10 07:56:36 UTC
[jena] branch main updated: gh-1369: Fix for handling assignments in OpAsQuery
This is an automated email from the ASF dual-hosted git repository.
andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/main by this push:
new 4e57638acf gh-1369: Fix for handling assignments in OpAsQuery
new 9dcfc13d7c Merge pull request #1370 from Aklakan/gh-1369
4e57638acf is described below
commit 4e57638acf3b009644098c6b0b2cb4d5e800fc92
Author: Claus Stadler <Ra...@googlemail.com>
AuthorDate: Mon Jun 6 16:25:46 2022 +0200
gh-1369: Fix for handling assignments in OpAsQuery
---
.../org/apache/jena/sparql/algebra/OpAsQuery.java | 76 ++++++-
.../apache/jena/sparql/algebra/TestOpAsQuery.java | 244 +++++++++++----------
2 files changed, 191 insertions(+), 129 deletions(-)
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/OpAsQuery.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/OpAsQuery.java
index 37a106f8b7..ea895114ae 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/OpAsQuery.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/OpAsQuery.java
@@ -253,12 +253,13 @@ public class OpAsQuery {
} ;
// The assignments will become part of the project.
- Map<Var, Expr> assignments = new HashMap<>() ;
+ // Using VarExprList to preserve order; https://github.com/apache/jena/issues/1369
+ VarExprList assignments = new VarExprList();
if ( level.opExtends != null ) {
processExtends(level.opExtends, (var,expr)->{
// Internal rename.
expr = rewrite(expr, varToExpr) ;
- assignments.put(var, expr) ;
+ assignments.add(var, expr) ;
}) ;
}
@@ -286,17 +287,70 @@ public class OpAsQuery {
// No project, Make BINDs
//processQueryPattern(op, assignments) ;
-
} else {
- level.opProject.getVars().forEach(v -> {
- if ( assignments.containsKey(v) ) {
- query.addResultVar(v, assignments.get(v)) ;
- } else
- query.getProjectVars().add(v) ;
+ // Where assignments and projections align the assignments will become part of the projection
+ // otherwise the assignments will become BINDs; https://github.com/apache/jena/issues/1369
+ List<Var> projectVars = level.opProject.getVars();
+
+ List<Var> assignVars = assignments.getVars();
+ int assignVarsSize = assignVars.size();
+ int projectOffset = assignVarsSize; // Start at end and search backwards
+ int idxThreshold = Integer.MAX_VALUE; // Prevent adding later mentioned expressions earlier to the projection list
+
+ // Find an offset in the assignments from which on
+ // *all remaining* variables appears in the same order as in the projection
+ while (projectOffset-- > 0) {
+ Var assignVar = assignVars.get(projectOffset);
+
+ // Ensure that the projection does not shuffle the given order of expressions
+ // A later assignment must also appear later in the built projection
+ int idx = projectVars.indexOf(assignVar);
+ if (idx < 0 || idx > idxThreshold) {
+ break;
+ }
+ idxThreshold = idx;
+ }
- }) ;
- }
+ // Assignments with index <= projectOffset become BINDs
+ // Note that a projectOffset of -1 means there won't be any BINDs
+ if (projectOffset >= 0) {
+ Element activeElement = query.getQueryPattern();
+
+ ElementGroup activeGroup;
+ if (activeElement instanceof ElementGroup) {
+ activeGroup = (ElementGroup)activeElement;
+ } else {
+ // Not sure whether it's possible here for BINDs to exist with the
+ // activeElement NOT being a group pattern - but better safe than sorry
+ activeGroup = new ElementGroup();
+ activeGroup.addElement(activeElement);
+ query.setQueryPattern(activeGroup);
+ }
+
+ for (int i = 0; i <= projectOffset; ++i) {
+ Var v = assignVars.get(i);
+ Expr e = assignments.getExpr(v);
+ activeGroup.addElement(new ElementBind(v, e));
+ }
+ }
+ // For each projected variable determine whether a possible expression was already
+ // added as a BIND or whether it needs to be projected
+ for (Var v : projectVars) {
+ Expr e = assignments.getExpr(v);
+
+ int offset = assignVars.indexOf(v);
+ if (offset > projectOffset) {
+ // Note that 'query.addResultVar' handles the case where e is null
+ query.addResultVar(v, e) ;
+ }
+ else {
+ // Either the variable did not map to an expression or
+ // the expression was added as BIND - in any case just project the variable
+ query.addResultVar(v, null) ;
+ }
+ }
+ }
if ( level.opDistinct != null )
query.setDistinct(true) ;
@@ -314,7 +368,7 @@ public class OpAsQuery {
/**
* Collect the OpExtend in a stack of OpExtend into a list for later
* processing. (Processing only uses opExtend in the list, not inner one
- * which wil also be in the list.)
+ * which will also be in the list.)
*/
private static Op processExtend(Op op, List<OpExtend> assignments) {
while ( op instanceof OpExtend ) {
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestOpAsQuery.java b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestOpAsQuery.java
index ea96ecff33..2fa959bfbb 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestOpAsQuery.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestOpAsQuery.java
@@ -42,58 +42,66 @@ public class TestOpAsQuery {
@Test public void testBasic02() { test_roundTripQuery("SELECT * { ?s ?p ?o }") ; }
@Test public void testBasic03() { test_roundTripQuery("SELECT * { ?s ?p ?o FILTER(?o > 5) }") ; }
@Test public void testBasic04() { test_roundTripQuery("SELECT ?s { ?s ?p ?o FILTER(?o > 5) }") ; }
-
- // 01, 02: Same algebra.
+
+ // 01, 02: Same algebra.
@Test public void testBind01() { test_roundTripQuery("SELECT ?s (?o + 5 AS ?B) { ?s ?p ?o }") ; }
@Test public void testBind02() { test_roundTripAlegbra("SELECT ?o ?B { ?s ?p ?o BIND (?o + 5 AS ?B) }") ; }
// No project
@Test public void testBind03() { test_roundTripQuery("SELECT * { ?s ?p ?o BIND (?o + 5 AS ?B) }") ; }
-
+
// Over nested.
- @Test public void testBind04() {
+ @Test public void testBind04() {
test_roundTripQuery("SELECT * { ?s ?p ?o BIND(?o+1 AS ?a1) ?x ?q ?v BIND(?v+2 AS ?a2) }",
- "SELECT * { { ?s ?p ?o BIND(( ?o + 1 ) AS ?a1) } ?x ?q ?v BIND(( ?v + 2 ) AS ?a2) } ");
+ "SELECT * { { ?s ?p ?o BIND(( ?o + 1 ) AS ?a1) } ?x ?q ?v BIND(( ?v + 2 ) AS ?a2) } ");
}
-
+
// Over nested.
- @Test public void testBind05() {
+ @Test public void testBind05() {
test_roundTripQuery("SELECT * { ?s ?p ?o BIND(?o+1 AS ?a1) ?x ?q ?v BIND(2 AS ?a2) } ORDER BY ?s",
- "SELECT * { { { ?s ?p ?o BIND(( ?o + 1 ) AS ?a1) } ?x ?q ?v } BIND(2 AS ?a2) } ORDER BY ?s");
+ "SELECT * { { { ?s ?p ?o BIND(( ?o + 1 ) AS ?a1) } ?x ?q ?v } BIND(2 AS ?a2) } ORDER BY ?s");
}
-
+
// https://issues.apache.org/jira/browse/JENA-1843
@Test public void testBind06() { test_roundTripQuery("SELECT * { ?s ?p ?o BIND(?o + 1 AS ?a1) BIND(?v+2 as ?a2) }"); }
@Test public void testBind07() { test_roundTripQuery("SELECT * { BIND(?o + 1 AS ?a1) BIND(?v+2 as ?a2) }"); }
-
- @Test public void testOptional01()
+
+ // https://github.com/apache/jena/issues/1369
+ @Test public void testBind08() { test_roundTripQuery("SELECT (?x AS ?y) { BIND ('x' AS ?x) }"); }
+ @Test public void testBind09() { test_roundTripQuery("SELECT ('y' AS ?y) ?x { BIND ('x' AS ?x) }"); }
+ @Test public void testBind10() { test_roundTripQuery("SELECT ('y' AS ?y) ?s ('x' AS ?x) { ?s ?p ?o }"); }
+ @Test public void testBind11() { test_roundTripQuery("SELECT ?s ('y' AS ?y) ?p ?x ?o { ?s ?p ?o BIND ('x' AS ?x) }"); }
+ @Test public void testBind12() { test_roundTripQuery("SELECT ?w ('y' AS ?y) ?x { BIND('w' AS ?w) ?s ?p ?o BIND ('x' AS ?x) }"); }
+ @Test public void testBind13() { test_roundTripQuery("SELECT ('x' AS ?x) (str(?x) AS ?y) (str(?x) AS ?z) {}"); }
+
+ @Test public void testOptional01()
{ test_roundTripQuery("SELECT * WHERE { ?s ?p ?o OPTIONAL { ?s ?q ?z FILTER (?foo) } }") ; }
-
+
// Double {{...}} matter here in SPARQL.
- @Test public void testOptional02()
+ @Test public void testOptional02()
{ test_roundTripQuery("SELECT * WHERE { ?s ?p ?o OPTIONAL { { ?s ?q ?z FILTER (?foo) } } }") ; }
-
- @Test public void testOptional03()
+
+ @Test public void testOptional03()
// Don't currently unnest the LHS of the second optional. See testOptional03a
{ test_roundTripQuery("SELECT * WHERE { ?s ?p ?o OPTIONAL { ?s ?p1 ?o1 } OPTIONAL { ?s ?p2 ?o2 } } ") ; }
- @Test public void testOptional04()
+ @Test public void testOptional04()
{ test_roundTripQuery("SELECT * WHERE { ?s ?p ?o OPTIONAL { ?s ?p1 ?o1 } OPTIONAL { ?s ?p2 ?o2 } OPTIONAL { ?s ?p3 ?o3 }} ") ; }
@Test
public void testCountStar() {
test_roundTripQuery("select (count(*) as ?cs) { ?s ?p ?o }");
}
-
+
@Test
public void testCountGroup() {
test_roundTripQuery("select (count(?p) as ?cp) { ?s ?p ?o } group by ?s");
}
-
+
@Test
public void testCountGroupAs() {
test_roundTripQuery("select (count(?p) as ?cp) { ?s ?p ?o }");
}
-
+
@Test
public void testDoubleCount() {
Query[] result = test_roundTripQuery("select (count(?s) as ?sc) (count(?p) as ?pc) { ?s ?p ?o }") ;
@@ -101,74 +109,74 @@ public class TestOpAsQuery {
assertTrue(result[1].getResultVars().contains("sc"));
assertTrue(result[1].getResultVars().contains("pc"));
}
-
+
/* JENA-166 */
@Test
public void testGroupWithExpression() {
test_roundTripQuery("SELECT (sample(?a) + 1 AS ?c) {} GROUP BY ?x");
}
-
+
/* Coverage developed for JENA-963 : GROUP BY*/
@Test public void testGroupBy_01()
{ test_roundTripQuery("SELECT ?s { ?s ?p ?o } GROUP BY ?s"); }
-
+
@Test public void testGroupBy_02()
{ test_roundTripQuery("SELECT (count(?p) as ?cp) { ?s ?p ?o } GROUP BY ?s"); }
-
+
@Test public void testGroupBy_03()
{ test_roundTripQuery("SELECT ?s { ?s ?p ?o } GROUP BY ?s HAVING (count(*) > 1 )"); }
-
+
@Test public void testGroupBy_04()
{ test_roundTripQuery("SELECT ?s { ?s ?p ?o } GROUP BY ?s HAVING (?s > 1 )"); }
-
+
@Test public void testGroupBy_05()
{ test_roundTripQuery("SELECT (count(?p) as ?cp) { ?s ?p ?o } GROUP BY ?s HAVING (?cp > 1 )"); }
-
+
@Test public void testGroupBy_06()
{ test_roundTripQuery("SELECT (count(?p) as ?cp) { ?s ?p ?o } GROUP BY (abs(?o)) HAVING (?cp > 1 )"); }
-
+
@Test public void testGroupBy_07()
{ test_roundTripQuery("SELECT (?X+2 AS ?Y) (count(?p) as ?cp) ?Z (1/?X AS ?X1) { ?s ?p ?o } GROUP BY ?Z (abs(?o) AS ?X) HAVING (?cp > 1 )"); }
-
+
@Test public void testGroupBy_08()
{ test_roundTripQuery("SELECT (count(?p) as ?cp) { ?s ?p ?o } GROUP BY (abs(?o)) HAVING (?cp > 1 )"); }
-
+
@Test public void testGroupBy_09()
{ test_roundTripQuery("SELECT (count(?p) as ?cp) { ?s ?p ?o } GROUP BY (abs(?o)) ORDER BY (COUNT(*))"); }
-
+
@Test public void testGroupBy_10()
{ test_roundTripQuery("SELECT (7+count(?p) as ?cp) { ?s ?p ?o } GROUP BY (abs(?o)) HAVING (?cp > 1 && SUM(?o) > 99 ) ORDER BY (6+COUNT(*))"); }
-
+
@Test public void testGroupBy_11()
{ test_roundTripQuery("SELECT ?X { ?s ?p ?o } GROUP BY (abs(?o) AS ?X) HAVING (?cp > 1 )"); }
-
+
@Test public void testGroupBy_12()
- { test_roundTripQuery("SELECT * { ?s ?q ?z {SELECT DISTINCT * { ?s ?p ?o }} }"); }
-
+ { test_roundTripQuery("SELECT * { ?s ?q ?z {SELECT DISTINCT * { ?s ?p ?o }} }"); }
+
// https://issues.apache.org/jira/browse/JENA-1844
@Test public void testGroupBy_13()
{ test_roundTripQuery("SELECT * { ?s ?p ?o BIND(?o+1 AS ?a1) } ORDER BY ?s"); }
-
+
@Test public void testSubQuery_01()
{ test_roundTripQuery("SELECT ?s { SELECT (count(*) as ?cp) { ?s ?p ?o } }") ; }
-
+
@Test public void testSubQuery_02()
{ test_roundTripQuery("SELECT ?s { ?s ?p ?o { SELECT (count(*) as ?cp) { ?s ?p ?o } }}") ; }
-
+
@Test public void testSubQuery_03()
{ test_roundTripQuery("SELECT ?s { { SELECT (count(*) as ?cp) { ?s ?p ?o } } ?s ?p ?o }") ; }
-
+
@Test public void testSubQuery_04()
{ test_roundTripQuery("SELECT * WHERE { ?s ?p ?o . BIND(?o AS ?x) }") ; }
-
+
@Test public void testSubQuery_05()
{ test_roundTripQuery("SELECT (?o AS ?x) WHERE { ?s ?p ?o .}") ; }
-
+
@Test
public void testProject1() {
test_roundTripQuery("SELECT (?x + 1 AS ?c) {}");
}
-
+
@Test
public void testProject2() {
Query[] result = test_roundTripQuery("SELECT (?x + 1 AS ?c) ?d {}");
@@ -176,72 +184,72 @@ public class TestOpAsQuery {
assertTrue(result[1].getResultVars().contains("c"));
assertTrue(result[1].getResultVars().contains("d"));
}
-
+
@Test
public void testNestedBind() {
test_roundTripQuery("SELECT ?c { { } UNION { BIND(?x + 1 AS ?c) } }");
}
-
+
@Test
public void testNestedProject() {
test_roundTripQuery("SELECT (?x + 1 AS ?c) { { } UNION { } }");
}
-
+
@Test
public void testGroupExpression() {
test_roundTripQuery("SELECT ?z { } GROUP BY (?x + ?y AS ?z)");
}
-
+
@Test
public void testNestedProjectWithGroup() {
test_roundTripQuery("SELECT (SAMPLE(?c) as ?s) { {} UNION {BIND(?x + 1 AS ?c)} } GROUP BY ?x");
}
-
+
@Test
public void testQuadPatternInDefaultGraph() {
test_roundTripQueryQuads("SELECT * WHERE { ?s a ?type }");
}
-
+
@Test
public void testGraphClauseUri() {
test_roundTripQuery("SELECT * WHERE { GRAPH <http://example> { ?s a ?type } }");
}
-
+
@Test
public void testGraphClauseComplex() {
test_roundTripQuery("SELECT * WHERE { GRAPH <http://example> { ?s a ?type . OPTIONAL { ?s <http://label> ?label } } }");
}
-
+
@Test
public void testQuadPatternInGraph() {
test_roundTripQueryQuads("SELECT * WHERE { GRAPH <http://example> { ?s a ?type } }");
}
-
+
@Test
public void testQuadPatternInGraphComplex01() {
//This fails because OpQuadPattern's are converted back to individual GRAPH clauses
Object[] result = roundTripQueryQuad("SELECT * WHERE { GRAPH <http://example> { ?s a ?type . OPTIONAL { ?s <http://label> ?label } } }");
assertFalse(result[0].equals(result[1]));
}
-
+
@Test
public void testQuadPatternInGraphComplex02() {
//This succeeds since each OpQuadPattern is from a single simple GRAPH clause
test_roundTripQueryQuads("SELECT * WHERE { GRAPH <http://example> { ?s a ?type } OPTIONAL { GRAPH <http://example> { ?s <http://label> ?label } } }");
}
-
+
@Test
public void testExtend1() {
// Top Level BIND should now be round trippable
test_roundTripQuery("SELECT * WHERE { ?s ?p ?o . BIND(?o AS ?x) }");
}
-
+
@Test
public void testExtend2() {
// Nested BIND should always have been round trippable
test_roundTripQuery("SELECT * WHERE { GRAPH ?g { ?s ?p ?o . BIND(?o AS ?x) } }");
}
-
+
@Test
public void testExtend3() {
//JENA-429
@@ -250,7 +258,7 @@ public class TestOpAsQuery {
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>" ,
"PREFIX mylib: <java:dateadd.lib.pkgfor.arq.>",
"",
- "SELECT ?yearmonth ( count(?document) as ?total )",
+ "SELECT ?yearmonth ( count(?document) as ?total )",
"{" ,
" ?document a :Document;",
" :documentDateOfCreation ?date ;",
@@ -259,25 +267,25 @@ public class TestOpAsQuery {
"} group by ?yearmonth") ;
test_roundTripQuery(query);
}
-
+
@Test
public void testExtend4() {
//Simplified repo of JENA-429
test_roundTripQuery("SELECT ?key (COUNT(?member) AS ?total) WHERE { ?s ?p ?o . BIND(LCASE(?o) AS ?key) } GROUP BY ?key");
}
-
+
@Test
public void testExtendInService() {
//Original test case from JENA-422
Query[] result = test_roundTripQuery("SELECT * WHERE { SERVICE <http://example/endpoint> { ?s ?p ?o . BIND(?o AS ?x) } }");
assertTrue(result[1].toString().contains("BIND"));
}
-
+
@Test
public void testSubQuery1() {
test_roundTripQuery("SELECT ?s WHERE { SELECT ?s ?p WHERE { ?s ?p ?o } }");
}
-
+
@Test
public void testSubQuery2() {
String query = "SELECT ?s ?x WHERE { { SELECT ?s ?p WHERE { ?s ?p ?o } } { SELECT ?x WHERE { ?x ?p ?o } } }";
@@ -285,53 +293,53 @@ public class TestOpAsQuery {
// Not all cases of sub-query have unnecessary {} removed.
test_roundTripQuery(query) ;
}
-
+
@Test
public void testSubQuery3() {
String query = "SELECT * WHERE { { SELECT ?s ?p WHERE { ?s ?p ?o } } { SELECT ?x WHERE { ?x ?p ?o } } }";
test_roundTripQuery(query) ;
}
-
+
@Test
public void testAggregatesInSubQuery1() {
//Simplified form of a test case provided via the mailing list (JENA-445)
String query = "SELECT ?key ?agg WHERE { SELECT ?key (COUNT(*) AS ?agg) { ?key ?p ?o } GROUP BY ?key }";
test_roundTripQuery(query);
}
-
+
@Test
public void testAggregatesInSubQuery2() {
//Simplified form of a test case provided via the mailing list (JENA-445)
test_roundTripAlegbra("SELECT * WHERE { { SELECT ?key (COUNT(*) AS ?agg) { ?key ?p ?o } GROUP BY ?key } }");
}
-
+
@Test
public void testAggregatesInSubQuery3() {
//Actual test case from JENA-445 bug report
- String queryString =
- "PREFIX dcterms: <http://purl.org/dc/terms/> \n" +
- "PREFIX dbpedia: <http://dbpedia.org/resource/> \n" +
-
- "SELECT ?num_of_holidays ?celebrate_Chinese_New_Year WHERE { \n" +
- "{" +
- "SELECT ?country_cat (COUNT(?holiday) as ?num_of_holidays) \n" +
- "WHERE {" +
- "?country_cat <http://www.w3.org/2004/02/skos/core#broader> <http://dbpedia.org/resource/Category:Public_holidays_by_country>. \n" +
- "?holiday dcterms:subject ?country_cat \n" +
- "}GROUP by ?country_cat \n" +
- "} \n" +
- "{ \n" +
- "SELECT ?country_cat (COUNT(?holiday) as ?celebrate_Chinese_New_Year) \n" +
- "WHERE { \n" +
- "?country_cat <http://www.w3.org/2004/02/skos/core#broader> <http://dbpedia.org/resource/Category:Public_holidays_by_country>. \n" +
- "?holiday dcterms:subject ?country_cat \n" +
- "FILTER(?holiday=\"http://dbpedia.org/resource/Lunar_New_Year\'s_Day\") \n" +
- "}GROUP by ?country_cat \n" +
- "} \n" +
- "}\n";
+ String queryString =
+ "PREFIX dcterms: <http://purl.org/dc/terms/> \n" +
+ "PREFIX dbpedia: <http://dbpedia.org/resource/> \n" +
+
+ "SELECT ?num_of_holidays ?celebrate_Chinese_New_Year WHERE { \n" +
+ "{" +
+ "SELECT ?country_cat (COUNT(?holiday) as ?num_of_holidays) \n" +
+ "WHERE {" +
+ "?country_cat <http://www.w3.org/2004/02/skos/core#broader> <http://dbpedia.org/resource/Category:Public_holidays_by_country>. \n" +
+ "?holiday dcterms:subject ?country_cat \n" +
+ "}GROUP by ?country_cat \n" +
+ "} \n" +
+ "{ \n" +
+ "SELECT ?country_cat (COUNT(?holiday) as ?celebrate_Chinese_New_Year) \n" +
+ "WHERE { \n" +
+ "?country_cat <http://www.w3.org/2004/02/skos/core#broader> <http://dbpedia.org/resource/Category:Public_holidays_by_country>. \n" +
+ "?holiday dcterms:subject ?country_cat \n" +
+ "FILTER(?holiday=\"http://dbpedia.org/resource/Lunar_New_Year\'s_Day\") \n" +
+ "}GROUP by ?country_cat \n" +
+ "} \n" +
+ "}\n";
test_roundTripQuery(queryString);
}
-
+
@Test
public void testModifiersOnSubQuery1() {
// From JENA-954
@@ -342,10 +350,10 @@ public class TestOpAsQuery {
" }",
" } LIMIT 1",
"}");
-
+
test_roundTripQuery(query) ;
}
-
+
@Test
public void testModifiersOnSubQuery2() {
// From JENA-954
@@ -356,10 +364,10 @@ public class TestOpAsQuery {
" }",
" } LIMIT 1",
"}");
-
+
test_roundTripQuery(query);
}
-
+
@Test
public void testModifiersOnSubQuery3() {
// From JENA-954
@@ -370,10 +378,10 @@ public class TestOpAsQuery {
" }",
" } LIMIT 1",
"}");
-
+
test_roundTripQuery(query);
}
-
+
@Test
public void testModifiersOnSubQuery4() {
// From JENA-954
@@ -384,16 +392,16 @@ public class TestOpAsQuery {
" }",
" } OFFSET 1",
"}");
-
+
test_roundTripQuery(query);
}
-
+
@Test
public void testPathExpressions1() {
String query = "PREFIX : <http://example/> SELECT * { ?s :p* ?o . ?x :r 123 . }" ;
test_roundTripQuery(query);
}
-
+
@Test
public void testPathExpressions2() {
String query = "PREFIX : <http://example/> SELECT * { ?s :p*/:q ?o . ?x :r 123 . }" ;
@@ -402,41 +410,41 @@ public class TestOpAsQuery {
@Test
public void testMinus1() {
- test_roundTripQuery("PREFIX : <http://example/> SELECT * { ?s :p ?o MINUS { ?s :q ?v .FILTER(?v<5) } }") ;
+ test_roundTripQuery("PREFIX : <http://example/> SELECT * { ?s :p ?o MINUS { ?s :q ?v .FILTER(?v<5) } }") ;
}
-
+
@Test
public void testMinus2() {
// query gains a level of {} but the meaning is the same.
String query = "PREFIX : <http://example/> SELECT * { ?s :p ?o OPTIONAL { ?s :x ?2 } MINUS { ?s :q ?v .FILTER(?v<5) } }" ;
test_roundTripAlegbra(query) ;
}
-
+
@Test
public void testTable1() {
String query = "SELECT * WHERE { ?x ?p ?z . VALUES ?y { } }" ;
roundTripQuery(query);
}
-
+
@Test
public void testTable2() {
// JENA-1468 : op to string and back.
String qs = "SELECT * WHERE { ?x ?p ?z . VALUES ?y { } }" ;
- Query query = QueryFactory.create(qs);
+ Query query = QueryFactory.create(qs);
Op op = Algebra.compile(query);
String x = op.toString();
Op op1 = SSE.parseOp(x);
Query query2 = OpAsQuery.asQuery(op1);
assertEquals(query, query2);
}
-
+
@Test
public void testValues1() {
String query = "SELECT * { VALUES ?x {1 2} ?s ?p ?x }" ;
test_roundTripQuery(query) ;
}
-
+
@Test
public void testValues2() {
String query = "SELECT * { ?s ?p ?x VALUES ?x {1 2} }" ;
@@ -444,14 +452,14 @@ public class TestOpAsQuery {
}
// Algebra to query : optimization cases OpAsQuery can handle.
-
+
@Test
public void testAlgebra01() {
String opStr = "(sequence (bgp (?s1 ?p1 ?o1)) (bgp (?s2 ?p2 ?o2)) )" ;
String query = "SELECT * { ?s1 ?p1 ?o1. ?s2 ?p2 ?o2}" ;
test_AlgebraToQuery(opStr, query);
}
-
+
@Test
public void testAlgebra02() {
String opStr = "(sequence (bgp (?s1 ?p1 ?o1)) (path ?x (path* :p) ?z) )" ;
@@ -465,57 +473,57 @@ public class TestOpAsQuery {
String query = "PREFIX : <http://example/> SELECT * { ?x :p* ?z . ?s1 ?p1 ?o1. }" ;
test_AlgebraToQuery(opStr, query);
}
-
+
// There 3 classes of transformations: there are 3 main test operations.
// test_roundTripQuery: The same query is recovered from OpAsQuery
// test_roundTripAlegbra: Different queries with the same alegra forms
// test_equivalentQuery: Different equivalent queries - same answers, different algebra.
// test_algebraToQuery: algebra to query (e.g. optimization shapes)
- //
+ //
// test_roundTripQuery is test_equivalentQuery with same input and expected.
// + quad variants.
-
+
public static void test_equivalentQuery(String input, String expected) {
Query orig = QueryFactory.create(input, Syntax.syntaxSPARQL_11);
Op toReconstruct = Algebra.compile(orig);
Query got = OpAsQuery.asQuery(toReconstruct);
Query result = QueryFactory.create(expected, Syntax.syntaxSPARQL_11);
- assertEquals(result, got);
+ assertEquals(result, got);
}
-
+
// Test for queries that do query->algebra->OpAsQuery->query
// to produce an output that is .equals the input.
/** query->algebra->OpAsQuery->query */
public static Query[] test_roundTripQuery(String query) {
// [original, got]
Query[] r = roundTripQuery(query) ;
- stripNamespacesAndBase(r[0]) ;
+ stripNamespacesAndBase(r[0]) ;
stripNamespacesAndBase(r[1]) ;
assertEquals(r[0], r[1]) ;
return r ;
}
-
+
public static void test_roundTripQuery(String query, String outcome) {
Query[] r = roundTripQuery(query) ;
Query orig = r[0];
Query output = r[1];
Query q2 = QueryFactory.create(outcome);
- stripNamespacesAndBase(orig) ;
+ stripNamespacesAndBase(orig) ;
stripNamespacesAndBase(output) ;
stripNamespacesAndBase(q2) ;
assertEquals(q2, output) ;
}
-
- // Test via quads
+
+ // Test via quads
public static Query[] test_roundTripQueryQuads(String query) {
Query[] r = roundTripQueryQuad(query) ;
assertEquals(r[0], r[1]) ;
return r ;
}
- // Compare A1 and A2 where
+ // Compare A1 and A2 where
// query[Q1]->algebra[A1]->OpAsQuery->query[Q2]->algebra[A2]
- // Sometimes Q1 and Q2 are equivalent but not .equals.
+ // Sometimes Q1 and Q2 are equivalent but not .equals.
public void test_roundTripAlegbra(String query) {
Query[] r = roundTripQuery(query);
// Even if the strings come out as non-equal because of the translation from algebra to query
@@ -525,7 +533,7 @@ public class TestOpAsQuery {
Op a2 = Algebra.compile(r[1]);
Assert.assertEquals(a1, a2);
}
-
+
/** algebra->OpAsQuery->query */
public static void test_AlgebraToQuery(String input, String expected) {
Op op = SSE.parseOp(input) ;
@@ -543,7 +551,7 @@ public class TestOpAsQuery {
Query[] r = { orig, got };
return r;
}
-
+
/** query->algebra/quads->OpAsQuery->query */
private static Query[] roundTripQueryQuad(String query) {
Query orig = QueryFactory.create(query, Syntax.syntaxSPARQL_11);
@@ -553,7 +561,7 @@ public class TestOpAsQuery {
Query[] r = { orig, got };
return r;
}
-
+
protected static void stripNamespacesAndBase(Query q) {
Map<String, String> prefixes = q.getPrefixMapping().getNsPrefixMap();
for (String prefix : prefixes.keySet()) {