Return-Path:
X-Original-To: apmail-incubator-jena-commits-archive@minotaur.apache.org
Delivered-To: apmail-incubator-jena-commits-archive@minotaur.apache.org
Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
by minotaur.apache.org (Postfix) with SMTP id 9D34A9EA8
for ;
Wed, 28 Dec 2011 18:46:58 +0000 (UTC)
Received: (qmail 87981 invoked by uid 500); 28 Dec 2011 18:46:58 -0000
Delivered-To: apmail-incubator-jena-commits-archive@incubator.apache.org
Received: (qmail 87956 invoked by uid 500); 28 Dec 2011 18:46:58 -0000
Mailing-List: contact jena-commits-help@incubator.apache.org; run by ezmlm
Precedence: bulk
List-Help:
List-Unsubscribe:
List-Post:
List-Id:
Reply-To: jena-dev@incubator.apache.org
Delivered-To: mailing list jena-commits@incubator.apache.org
Received: (qmail 87949 invoked by uid 99); 28 Dec 2011 18:46:58 -0000
Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230)
by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Dec 2011 18:46:58 +0000
X-ASF-Spam-Status: No, hits=-2000.0 required=5.0
tests=ALL_TRUSTED
X-Spam-Check-By: apache.org
Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4)
by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Dec 2011 18:46:54 +0000
Received: from eris.apache.org (localhost [127.0.0.1])
by eris.apache.org (Postfix) with ESMTP id AA14323888E7;
Wed, 28 Dec 2011 18:46:32 +0000 (UTC)
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: svn commit: r1225272 - in /incubator/jena/Jena2/ARQ/trunk: ./
src/main/java/com/hp/hpl/jena/sparql/lang/
src/main/java/com/hp/hpl/jena/sparql/syntax/
src/main/java/com/hp/hpl/jena/sparql/util/
src/test/java/com/hp/hpl/jena/sparql/lang/
Date: Wed, 28 Dec 2011 18:46:32 -0000
To: jena-commits@incubator.apache.org
From: andy@apache.org
X-Mailer: svnmailer-1.0.8-patched
Message-Id: <20111228184632.AA14323888E7@eris.apache.org>
X-Virus-Checked: Checked by ClamAV on apache.org
Author: andy
Date: Wed Dec 28 18:46:31 2011
New Revision: 1225272
URL: http://svn.apache.org/viewvc?rev=1225272&view=rev
Log:
JENA-142 Scope tracking of variables.
Modified:
incubator/jena/Jena2/ARQ/trunk/ChangeLog.txt
incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/lang/SyntaxVarScope.java
incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/ElementWalker.java
incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/PatternVarsVisitor.java
incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/RecursiveElementVisitor.java
incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/util/VarUtils.java
incubator/jena/Jena2/ARQ/trunk/src/test/java/com/hp/hpl/jena/sparql/lang/TestVarScope.java
Modified: incubator/jena/Jena2/ARQ/trunk/ChangeLog.txt
URL: http://svn.apache.org/viewvc/incubator/jena/Jena2/ARQ/trunk/ChangeLog.txt?rev=1225272&r1=1225271&r2=1225272&view=diff
==============================================================================
--- incubator/jena/Jena2/ARQ/trunk/ChangeLog.txt (original)
+++ incubator/jena/Jena2/ARQ/trunk/ChangeLog.txt Wed Dec 28 18:46:31 2011
@@ -3,11 +3,16 @@ ChangeLog for ARQ
==== ARQ 2.9.1
++ SPARQL 1.1: Complete scope tracking of variables (JENA-142)
++ Faster writing of XML and JSON results formats (JENA-178)
+
+
==== ARQ 2.8.9 / 2.9.0
** Java 6 is now required for running ARQ.
-+ ARQ: Provides \-escapes for characters ~.-!$&'()*+,;=:/?#@% in local part of prefix names
-+ ARQ: Allow %xx in the local part of prefix names
++ SPARQL 1.1: Provides \-escapes for characters ~.-!$&'()*+,;=:/?#@%
+ in local part of prefix names
++ SPARQl 1.1: Allow %xx in the local part of prefix names
+ SPARQL 1.1 / RDF 1.1 : DATATYPE(literal-with-lang) is now rdf:langString, not an error.
+ DatasetFactory: perferred methods for an in-memory dataset are:
create() -- will automatically add in-memory named graphs
Modified: incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/lang/SyntaxVarScope.java
URL: http://svn.apache.org/viewvc/incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/lang/SyntaxVarScope.java?rev=1225272&r1=1225271&r2=1225272&view=diff
==============================================================================
--- incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/lang/SyntaxVarScope.java (original)
+++ incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/lang/SyntaxVarScope.java Wed Dec 28 18:46:31 2011
@@ -56,6 +56,8 @@ public class SyntaxVarScope
* SubQuery done as a separate pass.
* Combine finalization with findAndAddNamedVars/setResultVars
*/
+
+ // Weakness : EXISTS inside FILTERs?
public static void check(Query query)
{
@@ -76,12 +78,8 @@ public class SyntaxVarScope
// Check BIND by accumulating variables and making sure BIND does not attempt to reuse one
private static void checkBind(Query query)
{
- LinkedHashSet queryVars = new LinkedHashSet() ;
- BindScopeChecker visitor = new BindScopeChecker(queryVars) ;
- //PatternVars.vars(query.getQueryPattern(), visitor) ;
-
- ElementWalker.Walker walker = new ScopeWalker(visitor) ;
- ElementWalker.walk(query.getQueryPattern(), walker) ;
+ HashSet queryVars = new HashSet() ;
+ scopeVars(queryVars, query.getQueryPattern()) ;
}
// Check subquery by finding subquries and recurisively checking.
@@ -239,26 +237,16 @@ public class SyntaxVarScope
}
}
- /** Accumulate pattern variables but include some checking (BIND) as well */
- private static class BindScopeChecker extends PatternVarsVisitor
+ // Special version of walker for scoping rules.
+
+ private static void scopeVars(Collection acc, Element e)
{
- public BindScopeChecker(Set s)
- {
- super(s) ;
- }
-
- @Override
- public void visit(ElementBind el)
- {
- Var var = el.getVar() ;
-
- if ( acc.contains(var) )
- throw new QueryParseException("BIND: Variable used when already in-scope: "+var+" in "+el, -1 , -1) ;
- checkAssignment(acc, el.getExpr(), var) ;
- }
+ PatternVarsVisitor pvv = new PatternVarsVisitor(acc) ;
+ ScopeWalker sw = new ScopeWalker(pvv) ;
+ e.visit(sw) ;
}
-
- // Special version of walker for scoping rules.
+
+ // Applies scope rules and does the structure walk.
public static class ScopeWalker extends ElementWalker.Walker
{
@@ -274,21 +262,16 @@ public class SyntaxVarScope
public void visit(ElementMinus el)
{
// Don't go down the RHS of MINUS
- //if ( el.getMinusElement() != null )
- // el.getMinusElement().visit(this) ;
proc.visit(el) ;
}
- // It is a top-down walk, so on enter an element of group or UNION,
- // then the entry set is
-
// Isolate elements of UNION
@Override
public void visit(ElementUnion el)
{
- Set accState = new HashSet(pvVisitor.acc) ;
- doMultipleIndependent(accState, el.getElements()) ;
- pvVisitor.acc = accState ;
+ Collection accGroup = pvVisitor.acc ;
+ for ( Element e : el.getElements() )
+ nestedScope(accGroup, e) ;
proc.visit(el) ;
}
@@ -300,28 +283,66 @@ public class SyntaxVarScope
// FILTER end of group
// All other elements (SERVICE?) outcome is only to the overall results.
-// @Override
-// public void visit(ElementGroup el)
-// {
-// // But BIND needs to be does over end of group.
-// // Ditto FILTER tests.
-// Set accState = new HashSet(pvVisitor.acc) ;
-// doMultipleIndependent(accState, el.getElements()) ;
-// pvVisitor.acc = accState ;
-// proc.visit(el) ;
-// }
+ @Override
+ public void visit(ElementGroup el)
+ {
+ // Ther are two kinds of elements: ones that accumulate variables
+ // across the group and ones that isolate a subexpression to be joined
+ // with other and the group itself.
+ // Scoped: UNION, Group, OPTIONAL, (MINUS), SERVICE, SubSELECT
+ // Acumulating: BGPs, paths, BIND, LET
+
+ Collection accGroup = pvVisitor.acc ; // Accumulate as we go.
+
+ for ( Element e : el.getElements() )
+ {
+ if ( scoped(e) )
+ nestedScope(accGroup, e) ;
+ else
+ scopeVars(accGroup, e) ;
+ }
+ proc.visit(el) ;
+ }
+ private void nestedScope(Collection accGroup , Element e )
+ {
+ // New scope accumulator.
+ Collection x = new HashSet() ;
+ scopeVars(x, e) ;
+ accGroup.addAll(x) ;
+ }
- private void doMultipleIndependent(Set agg, List elements)
+ private static boolean scoped(Element e)
+ {
+ return e instanceof ElementGroup ||
+ e instanceof ElementUnion ||
+ e instanceof ElementOptional ||
+ e instanceof ElementService ||
+ e instanceof ElementSubQuery ;
+ }
+
+ // Inside filters.
+
+ @Override
+ public void visit(ElementBind el)
+ {
+ Var var = el.getVar() ;
+
+ if ( pvVisitor.acc.contains(var) )
+ throw new QueryParseException("BIND: Variable used when already in-scope: "+var+" in "+el, -1 , -1) ;
+ checkAssignment(pvVisitor.acc, el.getExpr(), var) ;
+ }
+
+
+
+ @Override
+ public void visit(ElementService el)
{
- // agg is empty?
- for ( Element e : elements )
+ if ( el.getServiceNode().isVariable() )
{
- pvVisitor.acc.clear() ;
- // Do subelement.
- e.visit(this) ;
- // Accumulate for final result.
- agg.addAll(pvVisitor.acc) ;
+ Var var = Var.alloc(el.getServiceNode()) ;
+ if ( ! pvVisitor.acc.contains(var) )
+ throw new QueryParseException("SERVICE: Variable not already in-scope: "+var+" in "+el, -1 , -1) ;
}
}
Modified: incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/ElementWalker.java
URL: http://svn.apache.org/viewvc/incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/ElementWalker.java?rev=1225272&r1=1225271&r2=1225272&view=diff
==============================================================================
--- incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/ElementWalker.java (original)
+++ incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/ElementWalker.java Wed Dec 28 18:46:31 2011
@@ -19,12 +19,12 @@
package com.hp.hpl.jena.sparql.syntax;
-
/** An element visitor that walks the graph pattern tree,
* applying a visitor at each Element traversed.
- * Only walks one level of the query (not subqueries -- sub SELECT, (NOT)EXISTS
- * these will need to call down themselves if it is meaningful for the visitor.
- * Bottom-up walk - apply to subelements before applying to current element. */
+ * Does not (NOT)EXISTS in filters.
+ * These will need to call down themselves if it is meaningful for the visitor.
+ * Bottom-up walk - apply to subelements before applying to current element.
+ */
public class ElementWalker
{
@@ -49,7 +49,10 @@ public class ElementWalker
static public class Walker implements ElementVisitor
{
protected ElementVisitor proc ;
- protected Walker(ElementVisitor visitor) { proc = visitor ; }
+ protected Walker(ElementVisitor visitor)
+ {
+ proc = visitor ;
+ }
@Override
public void visit(ElementTriplesBlock el)
@@ -129,22 +132,17 @@ public class ElementWalker
proc.visit(el) ;
}
- // EXISTs, NOT EXISTs are really subqueries so don't automatically walk down them.
- // NB They also occur in FILTERs via expressions.
+ // EXISTs, NOT EXISTs also occur in FILTERs via expressions.
@Override
public void visit(ElementExists el)
{
-// if ( el.getElement() != null )
-// el.getElement().visit(this) ;
proc.visit(el) ;
}
@Override
public void visit(ElementNotExists el)
{
-// if ( el.getElement() != null )
-// el.getElement().visit(this) ;
proc.visit(el) ;
}
@@ -159,10 +157,6 @@ public class ElementWalker
@Override
public void visit(ElementSubQuery el)
{
- // Only walk this level.
-// Element el2 = el.getQuery().getQueryPattern() ;
-// if ( el2 != null )
-// el2.visit(this) ;
proc.visit(el) ;
}
Modified: incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/PatternVarsVisitor.java
URL: http://svn.apache.org/viewvc/incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/PatternVarsVisitor.java?rev=1225272&r1=1225271&r2=1225272&view=diff
==============================================================================
--- incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/PatternVarsVisitor.java (original)
+++ incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/PatternVarsVisitor.java Wed Dec 28 18:46:31 2011
@@ -18,8 +18,8 @@
package com.hp.hpl.jena.sparql.syntax;
+import java.util.Collection ;
import java.util.Iterator ;
-import java.util.Set ;
import com.hp.hpl.jena.graph.Triple ;
import com.hp.hpl.jena.sparql.core.TriplePath ;
@@ -29,8 +29,8 @@ import com.hp.hpl.jena.sparql.util.VarUt
public class PatternVarsVisitor extends ElementVisitorBase
{
- public Set acc ;
- public PatternVarsVisitor(Set s) { acc = s ; }
+ public Collection acc ;
+ public PatternVarsVisitor(Collection s) { acc = s ; }
@Override
public void visit(ElementTriplesBlock el)
Modified: incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/RecursiveElementVisitor.java
URL: http://svn.apache.org/viewvc/incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/RecursiveElementVisitor.java?rev=1225272&r1=1225271&r2=1225272&view=diff
==============================================================================
--- incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/RecursiveElementVisitor.java (original)
+++ incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/syntax/RecursiveElementVisitor.java Wed Dec 28 18:46:31 2011
@@ -26,9 +26,9 @@ package com.hp.hpl.jena.sparql.syntax;
* calling points:
*
* - start of element
- * - end of element
* - start each sub element
* - end of each sub element
+ * - end of element
*
*
*
Modified: incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/util/VarUtils.java
URL: http://svn.apache.org/viewvc/incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/util/VarUtils.java?rev=1225272&r1=1225271&r2=1225272&view=diff
==============================================================================
--- incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/util/VarUtils.java (original)
+++ incubator/jena/Jena2/ARQ/trunk/src/main/java/com/hp/hpl/jena/sparql/util/VarUtils.java Wed Dec 28 18:46:31 2011
@@ -18,6 +18,7 @@
package com.hp.hpl.jena.sparql.util;
+import java.util.Collection ;
import java.util.HashSet ;
import java.util.Set ;
@@ -35,20 +36,20 @@ public class VarUtils
return x ;
}
- public static void addVarsFromTriple(Set acc, Triple t)
+ public static void addVarsFromTriple(Collection acc, Triple t)
{
addVar(acc, t.getSubject()) ;
addVar(acc, t.getPredicate()) ;
addVar(acc, t.getObject()) ;
}
- public static void addVarsFromTriplePath(Set acc, TriplePath tpath)
+ public static void addVarsFromTriplePath(Collection acc, TriplePath tpath)
{
addVar(acc, tpath.getSubject()) ;
addVar(acc, tpath.getObject()) ;
}
- public static void addVar(Set acc, Node n)
+ public static void addVar(Collection acc, Node n)
{
if ( n == null )
return ;
Modified: incubator/jena/Jena2/ARQ/trunk/src/test/java/com/hp/hpl/jena/sparql/lang/TestVarScope.java
URL: http://svn.apache.org/viewvc/incubator/jena/Jena2/ARQ/trunk/src/test/java/com/hp/hpl/jena/sparql/lang/TestVarScope.java?rev=1225272&r1=1225271&r2=1225272&view=diff
==============================================================================
--- incubator/jena/Jena2/ARQ/trunk/src/test/java/com/hp/hpl/jena/sparql/lang/TestVarScope.java (original)
+++ incubator/jena/Jena2/ARQ/trunk/src/test/java/com/hp/hpl/jena/sparql/lang/TestVarScope.java Wed Dec 28 18:46:31 2011
@@ -22,16 +22,14 @@ import org.junit.Test ;
import org.openjena.atlas.junit.BaseTest ;
import com.hp.hpl.jena.query.Query ;
-import com.hp.hpl.jena.query.QueryFactory ;
import com.hp.hpl.jena.query.QueryException ;
-import com.hp.hpl.jena.sparql.lang.SyntaxVarScope ;
+import com.hp.hpl.jena.query.QueryFactory ;
public class TestVarScope extends BaseTest
{
private static void scope(String queryStr)
{
Query query = QueryFactory.create(queryStr) ;
- SyntaxVarScope.check(query) ;
}
@Test public void scope_01() { scope("SELECT ?x { ?s ?p ?o }") ; }
@@ -62,25 +60,37 @@ public class TestVarScope extends BaseTe
@Test (expected=QueryException.class)
public void scope_21() { scope("SELECT ?o { ?x ?p ?o } GROUP BY ?x") ; }
+
+ @Test(expected=QueryException.class)
+ public void scope_22() { scope("SELECT * { ?s ?p ?o BIND(5 AS ?o) }") ; }
- @Test public void scope_22() { scope("SELECT * { ?s ?p ?o OPTIONAL{?s ?p2 ?o2} BIND(?o2+5 AS ?z) }") ; }
+ @Test public void scope_23() { scope("SELECT * { ?s ?p ?o { BIND(5 AS ?o) } }") ; }
+
+ @Test(expected=QueryException.class)
+ public void scope_24() { scope("SELECT * { { ?s ?p ?o } BIND(5 AS ?o) }") ; }
+
+ @Test public void scope_25() { scope("SELECT * { { ?s ?p ?o } { BIND(5 AS ?o) } }") ; }
+
+ @Test public void scope_26() { scope("SELECT * { ?s ?p ?o OPTIONAL{?s ?p2 ?o2} BIND(?o2+5 AS ?z) }") ; }
@Test(expected=QueryException.class)
- public void scope_23() { scope("SELECT * { ?s ?p ?o OPTIONAL{?s ?p2 ?o2} BIND(5 AS ?o2) }") ; }
+ public void scope_27() { scope("SELECT * { ?s ?p ?o OPTIONAL{?s ?p2 ?o2} BIND(5 AS ?o2) }") ; }
@Test(expected=QueryException.class)
- public void scope_24() { scope("SELECT * { ?s ?p ?o OPTIONAL{?s ?p2 ?o2} BIND(?o+5 AS ?o2) }") ; }
+ public void scope_28() { scope("SELECT * { ?s ?p ?o OPTIONAL{?s ?p2 ?o2} BIND(?o+5 AS ?o2) }") ; }
@Test(expected=QueryException.class)
- public void scope_25() { scope("SELECT * { ?s ?p ?o OPTIONAL{?s ?p2 ?o2} BIND(5 AS ?o) }") ; }
+ public void scope_29() { scope("SELECT * { ?s ?p ?o OPTIONAL{?s ?p2 ?o2} BIND(5 AS ?o) }") ; }
+ @Test(expected=QueryException.class)
+ public void scope_31() { scope("SELECT * { { ?s ?p ?o } UNION {?s ?p2 ?o2} BIND(5 AS ?o) }") ; }
// Subqueries
@Test(expected=QueryException.class)
- public void scope_30() { scope("SELECT * { SELECT (?o+1 AS ?o) { ?s ?p ?o }}") ; }
+ public void scope_50() { scope("SELECT * { SELECT (?o+1 AS ?o) { ?s ?p ?o }}") ; }
@Test
- public void scope_31()
+ public void scope_51()
{
scope("SELECT ?y { " +
"{ { SELECT (?x AS ?y) { ?s ?p ?x } } } UNION { { SELECT (?x AS ?y) { ?s ?p ?x } } }" +
@@ -88,7 +98,7 @@ public class TestVarScope extends BaseTe
}
@Test(expected=QueryException.class)
- public void scope_32()
+ public void scope_52()
{
scope("SELECT ?y { " +
"{ { SELECT (?o+1 AS ?x) (?o+1 AS ?x) { ?s ?p ?o } } UNION { ?s ?p ?x } }" +