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 2016/06/06 11:34:51 UTC
jena git commit: JENA-1167: Cope with filter-before-defined variables
Repository: jena
Updated Branches:
refs/heads/master cd1c21ff6 -> 6f12cdbd3
JENA-1167: Cope with filter-before-defined variables
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/6f12cdbd
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/6f12cdbd
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/6f12cdbd
Branch: refs/heads/master
Commit: 6f12cdbd3964adfddfdaddd3092970a9ea5460aa
Parents: cd1c21f
Author: Andy Seaborne <an...@apache.org>
Authored: Mon Jun 6 12:14:42 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Mon Jun 6 12:14:42 2016 +0100
----------------------------------------------------------------------
.../jena/sparql/engine/main/JoinClassifier.java | 59 +++++++------
.../sparql/engine/main/LeftJoinClassifier.java | 47 ++++++-----
.../jena/sparql/engine/main/VarFinder.java | 88 +++++++++++++++++---
.../jena/sparql/algebra/TestClassify.java | 23 +++--
.../jena/sparql/algebra/TestTransformQuads.java | 3 +-
.../jena/sparql/algebra/TestVarFinder.java | 49 ++++++-----
6 files changed, 182 insertions(+), 87 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/6f12cdbd/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/JoinClassifier.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/JoinClassifier.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/JoinClassifier.java
index 22c3f39..00b06ea 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/JoinClassifier.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/JoinClassifier.java
@@ -87,40 +87,45 @@ public class JoinClassifier
System.err.println(rightOp) ;
}
- // Need only check left/rght.
+ // Need only check left/right.
VarFinder vfLeft = VarFinder.process(leftOp) ;
Set<Var> vLeftFixed = vfLeft.getFixed() ;
Set<Var> vLeftOpt = vfLeft.getOpt() ;
// Set<Var> vLeftFilter = vfLeft.getFilter() ;
- if ( print )
- System.err.println("Left/fixed: " + vLeftFixed) ;
- if ( print )
- System.err.println("Left/opt: " + vLeftOpt) ;
- // if (print) System.err.println("Left/filter: " + vLeftFilter) ;
-
- VarFinder vfRight = VarFinder.process(rightOp) ;
- Set<Var> vRightFixed = vfRight.getFixed() ;
- Set<Var> vRightOpt = vfRight.getOpt() ;
- Set<Var> vRightFilter = vfRight.getFilter() ;
- Set<Var> vRightAssign = vfRight.getAssign() ;
-
- if ( print )
- System.err.println("Right/fixed: " + vRightFixed) ;
- if ( print )
- System.err.println("Right/opt: " + vRightOpt) ;
- if ( print )
- System.err.println("Right/filter: " + vRightFilter) ;
- if ( print )
- System.err.println("Right/assign: " + vRightAssign) ;
-
- // Step 1 : remove any variable definitely fixed from the floating sets
+ if ( print ) {
+ System.err.println("Left") ;
+ vfLeft.print(System.err) ;
+ }
+ VarFinder vfRight = VarFinder.process(rightOp) ;
+ if ( print ) {
+ System.err.println("Right") ;
+ vfRight.print(System.err) ;
+ }
+
+ Set<Var> vRightFixed = vfRight.getFixed() ;
+ Set<Var> vRightOpt = vfRight.getOpt() ;
+ Set<Var> vRightFilter = vfRight.getFilter() ;
+ Set<Var> vRightFilterOnly = vfRight.getFilterOnly() ;
+ Set<Var> vRightAssign = vfRight.getAssign() ;
+
+ // Step 1 : If there are any variables in the LHS that are filter-only or filter-before define,
+ // we can't do anything.
+ if ( ! vRightFilterOnly.isEmpty() ) {
+ // A tigher condition is to see of any of the getFilterOnly are possible from the
+ // left. If not, then we can still use a sequence.
+ // But an outer sequence may push arbitrary here so play safe on the argument
+ // this is a relative uncommon case.
+ return false ;
+ }
+
+ // Step 2 : remove any variable definitely fixed from the floating sets
// because the nature of the "join" will deal with that.
vLeftOpt = SetUtils.difference(vLeftOpt, vLeftFixed) ;
vRightOpt = SetUtils.difference(vRightOpt, vRightFixed) ;
// And also assign/filter variables in the RHS which are always defined
- // in the
- // RHS. Leaves any potentially free variables in RHS filter.
+ // in the RHS.
+ // Leaves any potentially free variables in RHS filter.
vRightFilter = SetUtils.difference(vRightFilter, vRightFixed) ;
vRightAssign = SetUtils.difference(vRightAssign, vRightFixed) ;
@@ -156,7 +161,7 @@ public class JoinClassifier
if ( print )
System.err.println("Case 1 = " + bad1) ;
- // Case 2 : a filter in the RHS is uses a variable from the LHS (whether
+ // Case 3 : a filter in the RHS is uses a variable from the LHS (whether
// fixed or optional)
// Scoping means we must hide the LHS value form the RHS
// Could mask (??). For now, we stop linearization of this join.
@@ -167,7 +172,7 @@ public class JoinClassifier
if ( print )
System.err.println("Case 2 = " + bad2) ;
- // Case 3 : an assign in the RHS uses a variable not introduced
+ // Case 4 : an assign in the RHS uses a variable not introduced
// Scoping means we must hide the LHS value from the RHS
// Think this may be slightly relaxed, using variables in an
http://git-wip-us.apache.org/repos/asf/jena/blob/6f12cdbd/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/LeftJoinClassifier.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/LeftJoinClassifier.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/LeftJoinClassifier.java
index 9608334..ad68c09 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/LeftJoinClassifier.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/LeftJoinClassifier.java
@@ -47,12 +47,11 @@ public class LeftJoinClassifier
// Need also worry about filters in the right (not in the LJ condition)
// which use vars from the left.
- static public boolean isLinear(OpLeftJoin op)
- {
+ static public boolean isLinear(OpLeftJoin op) {
return isLinear(op.getLeft(), op.getRight()) ;
}
- static public boolean isLinear(Op left, Op right)
- {
+
+ static public boolean isLinear(Op left, Op right) {
left = effectiveOp(left) ;
right = effectiveOp(right) ;
@@ -62,34 +61,43 @@ public class LeftJoinClassifier
return false ;
Set<Var> leftVars = OpVars.visibleVars(left) ;
+ if ( print ) {
+ System.err.println("Left") ;
+ System.err.println(leftVars) ;
+ }
VarFinder vf = VarFinder.process(right) ;
+ if ( print ) {
+ System.err.println("Right") ;
+ vf.print(System.err) ;
+ }
+
+ // Case 1 : If there are any variables in the LHS that are
+ // filter-only or filter-before define, we can't do anything.
+ if ( ! vf.getFilterOnly().isEmpty() ) {
+ // A tigher condition is to see of any of the getFilterOnly are possible from the
+ // left. If not, then we can still use a sequence.
+ // But an outer sequence may push arbitrary here so play safe on the argument
+ // this is a relative uncommon case.
+ return false ;
+ }
Set<Var> optRight = vf.getOpt() ;
Set<Var> fixedRight = vf.getFixed() ;
Set<Var> filterVarsRight = vf.getFilter() ;
Set<Var> assignVarsRight = vf.getAssign() ;
-
- if (print) {
- System.err.println("Left/visible: " + leftVars) ;
- System.err.println("Right/fixed: " + fixedRight) ;
- System.err.println("Right/opt: " + optRight) ;
- System.err.println("Right/filter: " + filterVarsRight) ;
- System.err.println("Right/assign: " + assignVarsRight) ;
- }
-
- // Case 1
+ // Case 2
// A variable is nested in an optional on the RHS and on the LHS
// Cannot linearize as we must preserve scope
boolean b1 = SetUtils.intersectionP(leftVars, optRight) ;
if (print) System.err.println("Case 1 - " + b1);
- // Case 2
+ // Case 3
// A variable mentioned in a filter within the RHS already exists on the LHS
// Cannot linearize as would change filter evaluation
boolean b2 = SetUtils.intersectionP(leftVars, filterVarsRight) ;
if (print) System.err.println("Case 2 - " + b2);
- // Case 3
+ // Case 4
// A variable mentioned in the assign is not introduced on the RHS
// Cannot linearize as would change bind evaluation
Set<Var> unsafeAssign = new HashSet<>(assignVarsRight);
@@ -101,8 +109,7 @@ public class LeftJoinClassifier
return ! b1 && ! b2 && ! b3 ;
}
- static public Set<Var> nonLinearVars(OpLeftJoin op)
- {
+ static public Set<Var> nonLinearVars(OpLeftJoin op) {
Op left = effectiveOp(op.getLeft()) ;
Op right = effectiveOp(op.getRight()) ;
Set<Var> leftVars = OpVars.visibleVars(left) ;
@@ -111,11 +118,9 @@ public class LeftJoinClassifier
return SetUtils.intersection(leftVars, optRight) ;
}
- private static Op effectiveOp(Op op)
- {
+ private static Op effectiveOp(Op op) {
if (op instanceof OpExt)
op = ((OpExt) op).effectiveOp() ;
return op ;
}
-
}
http://git-wip-us.apache.org/repos/asf/jena/blob/6f12cdbd/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/VarFinder.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/VarFinder.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/VarFinder.java
index 258f7ea..be6c8e0 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/VarFinder.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/VarFinder.java
@@ -24,6 +24,7 @@ import static org.apache.jena.sparql.util.VarUtils.addVarsFromQuad ;
import static org.apache.jena.sparql.util.VarUtils.addVarsFromTriple ;
import static org.apache.jena.sparql.util.VarUtils.addVarsFromTriplePath ;
+import java.io.PrintStream ;
import java.util.HashSet ;
import java.util.List ;
import java.util.Set ;
@@ -69,11 +70,31 @@ public class VarFinder
private VarFinder(Op op)
{ varUsageVisitor = VarUsageVisitor.apply(op) ; }
- public Set<Var> getOpt() { return varUsageVisitor.optDefines ; }
- public Set<Var> getFilter() { return varUsageVisitor.filterMentions ; }
- public Set<Var> getAssign() { return varUsageVisitor.assignMentions ; }
- public Set<Var> getFixed() { return varUsageVisitor.defines ; }
+ public Set<Var> getOpt() { return varUsageVisitor.optDefines ; }
+ public Set<Var> getFilter() { return varUsageVisitor.filterMentions ; }
+ public Set<Var> getFilterOnly() { return varUsageVisitor.filterMentionsOnly ; }
+ public Set<Var> getAssign() { return varUsageVisitor.assignMentions ; }
+ public Set<Var> getFixed() { return varUsageVisitor.defines ; }
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder() ;
+ sb.append("Fixed:").append(getFixed()) ;
+ sb.append(", Filter:").append(getFilter()) ;
+ sb.append(", Filter2:").append(getFilterOnly()) ;
+ sb.append(", Opt:").append(getOpt()) ;
+ sb.append(", Assign:").append(getAssign()) ;
+ return sb.toString() ;
+ }
+
+ public void print(PrintStream out) {
+ out.printf(" Filter: %s\n", getFilter()) ;
+ out.printf(" Filter2: %s\n", getFilterOnly()) ;
+ out.printf(" Fixed : %s\n", getFixed()) ;
+ out.printf(" Opt: %s\n", getOpt()) ;
+ out.printf(" Assign: %s\n", getAssign()) ;
+ }
+
private static class VarUsageVisitor
//extends OpVisitorBase
implements OpVisitor
@@ -84,22 +105,25 @@ public class VarFinder
return v;
}
- Set<Var> defines = null;
- Set<Var> optDefines = null;
- Set<Var> filterMentions = null;
- Set<Var> assignMentions = null;
+ Set<Var> defines = null ;
+ Set<Var> optDefines = null ;
+ Set<Var> filterMentions = null ;
+ Set<Var> filterMentionsOnly = null ; // Mentioned in filter before defined.
+ Set<Var> assignMentions = null ;
VarUsageVisitor() {
defines = new HashSet<>();
optDefines = new HashSet<>();
filterMentions = new HashSet<>();
+ filterMentionsOnly = new HashSet<>();
assignMentions = new HashSet<>();
}
- VarUsageVisitor(Set<Var> _defines, Set<Var> _optDefines, Set<Var> _filterMentions, Set<Var> _assignMentions) {
+ VarUsageVisitor(Set<Var> _defines, Set<Var> _optDefines, Set<Var> _filterMentions, Set<Var> _filterMentions2, Set<Var> _assignMentions) {
defines = _defines;
optDefines = _optDefines;
filterMentions = _filterMentions;
+ filterMentionsOnly = _filterMentions2 ;
assignMentions = _assignMentions;
}
@@ -156,6 +180,7 @@ public class VarFinder
defines.addAll(usage.defines);
optDefines.addAll(usage.optDefines);
filterMentions.addAll(usage.filterMentions);
+ filterMentionsOnly.addAll(usage.filterMentionsOnly);
assignMentions.addAll(usage.assignMentions);
}
@@ -177,13 +202,22 @@ public class VarFinder
private void mergeMinusDiff(Op left, Op right) {
mergeVars(left) ;
VarUsageVisitor usage = VarUsageVisitor.apply(right);
- // Everything in the right side is really a filter.
+ // Everything in the right side is really a filter.
+ combinefilterMentions(this, usage.filterMentionsOnly) ;
+
filterMentions.addAll(usage.defines) ;
filterMentions.addAll(usage.optDefines) ;
filterMentions.addAll(usage.filterMentions) ;
filterMentions.addAll(usage.assignMentions) ;
}
+ private static void combinefilterMentions(VarUsageVisitor usage, Set<Var> mentions) {
+ for ( Var v : mentions ) {
+ if ( ! usage.defines.contains(v) )
+ usage.filterMentionsOnly.add(v) ;
+ }
+ }
+
@Override
public void visit(OpConditional opLeftJoin) {
leftJoin(opLeftJoin.getLeft(), opLeftJoin.getRight(), null);
@@ -196,11 +230,13 @@ public class VarFinder
defines.addAll(leftUsage.defines);
optDefines.addAll(leftUsage.optDefines);
filterMentions.addAll(leftUsage.filterMentions);
+ filterMentionsOnly.addAll(leftUsage.filterMentionsOnly);
assignMentions.addAll(leftUsage.assignMentions);
optDefines.addAll(rightUsage.defines); // Asymmetric.
optDefines.addAll(rightUsage.optDefines);
filterMentions.addAll(rightUsage.filterMentions);
+ filterMentionsOnly.addAll(rightUsage.filterMentionsOnly);
assignMentions.addAll(rightUsage.assignMentions);
// Remove any definites that are in the optionals
@@ -208,8 +244,20 @@ public class VarFinder
optDefines.removeAll(leftUsage.defines);
// And the associated filter.
- if ( exprs != null )
+ if ( exprs != null ) {
+ processExpr(exprs, rightUsage.defines) ;
exprs.varsMentioned(filterMentions);
+ }
+ }
+
+ // additionalDefines - set of variables which are defined is the filter is executed.
+ private void processExpr(ExprList exprs, Set<Var> additionalDefines) {
+ Set<Var> vars = exprs.getVarsMentioned() ;
+ filterMentions.addAll(vars) ;
+ for ( Var v : vars ) {
+ if ( ! defines.contains(v) && (additionalDefines == null || ! additionalDefines.contains(v) ) )
+ filterMentionsOnly.add(v) ;
+ }
}
@Override
@@ -231,6 +279,9 @@ public class VarFinder
filterMentions.addAll(usage1.filterMentions);
filterMentions.addAll(usage2.filterMentions);
+ filterMentionsOnly.addAll(usage1.filterMentionsOnly);
+ filterMentionsOnly.addAll(usage2.filterMentionsOnly);
+
assignMentions.addAll(usage1.assignMentions);
assignMentions.addAll(usage2.assignMentions);
}
@@ -248,8 +299,8 @@ public class VarFinder
@Override
public void visit(OpFilter opFilter) {
- opFilter.getExprs().varsMentioned(filterMentions);
opFilter.getSubOp().visit(this);
+ processExpr(opFilter.getExprs(), null) ;
}
@Override
@@ -279,10 +330,12 @@ public class VarFinder
subUsage.defines.retainAll(vars);
subUsage.optDefines.retainAll(vars);
subUsage.filterMentions.retainAll(vars) ;
+ subUsage.filterMentionsOnly.retainAll(vars) ;
subUsage.assignMentions.retainAll(vars) ;
defines.addAll(subUsage.defines);
optDefines.addAll(subUsage.optDefines);
filterMentions.addAll(subUsage.filterMentions);
+ filterMentionsOnly.addAll(subUsage.filterMentionsOnly);
assignMentions.addAll(subUsage.assignMentions);
}
@@ -353,5 +406,16 @@ public class VarFinder
defines.addAll(vars) ;
}
}
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder() ;
+ sb.append("Fixed:").append(defines) ;
+ sb.append(", Filter:").append(filterMentions) ;
+ sb.append(", Filter2:").append(filterMentionsOnly) ;
+ sb.append(", Opt:").append(optDefines) ;
+ sb.append(", Assign:").append(assignMentions) ;
+ return sb.toString() ;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/jena/blob/6f12cdbd/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestClassify.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestClassify.java b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestClassify.java
index 17e7692..7cea0a2 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestClassify.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestClassify.java
@@ -39,8 +39,12 @@ public class TestClassify extends BaseTest
@Test public void testClassify_Join_03()
{ classifyJ("{?s :p :o . { ?s :p ?o FILTER(?o) } }", true) ; }
+ // JENA-1167
+ // This actually safe in thsi case but as general component.
+ // the JoinClassifier is not clever enough to know that ?o is completely
+ // unbound. It may be boudn bu whatever feeds into the potential sequence.
@Test public void testClassify_Join_04()
- { classifyJ("{?s :p :o . { ?s :p :o FILTER(?o) } }", true) ; }
+ { classifyJ("{?s :p :o . { ?s :p :o FILTER(?o) } }", false) ; }
@Test public void testClassify_Join_05()
{ classifyJ("{?s :p :o . { ?x :p :o FILTER(?s) } }", false) ; }
@@ -61,6 +65,9 @@ public class TestClassify extends BaseTest
@Test public void testClassify_Join_10()
{ classifyJ("{ { ?x :p :o FILTER(?s) } ?s :p :o }", true) ; }
+
+ // OPTIONAL nested inside {} so it is a join of the LHS and the {}-RHS.
+
// Not safe: ?s
// Other parts of RHS may restrict ?s to things that can't match the LHS.
@Test public void testClassify_Join_11()
@@ -74,9 +81,15 @@ public class TestClassify extends BaseTest
{ classifyJ("{?s :p :o . { ?x :p :o OPTIONAL { :s :p :o FILTER(?x) } } }", true) ; }
@Test public void testClassify_Join_14()
- { classifyJ("{?s :p :o . { OPTIONAL { :s :p :o FILTER(?o) } } }", true) ; }
+ { classifyJ("{?s :p :o . { OPTIONAL { :s :p :o FILTER(?o) } } }", false) ; }
+
+ @Test public void testClassify_Join_14a()
+ { classifyJ("{?s :p :o . { OPTIONAL { :s :p ?o FILTER(?o) } } }", true) ; }
- @Test public void testClassify_Join_15()
+ @Test public void testClassify_Join_14b()
+ { classifyJ("{?s :p ?o . { OPTIONAL { :s :p :o FILTER(?o) } } }", false) ; }
+
+ @Test public void testClassify_Join_15()
{ classifyJ("{?s :p :o . { OPTIONAL { ?x :p :o FILTER(?s) } } }", false) ; }
@Test public void testClassify_Join_20()
@@ -89,9 +102,9 @@ public class TestClassify extends BaseTest
@Test public void testClassify_Join_31()
{ classifyJ("{ ?x ?y ?z {SELECT ?s { ?s ?p ?o} } }", true) ; }
- // Use of a filter variable not in from the LHS
+ // JENA-1167 : Use of a filter variable not in from the LHS
@Test public void testClassify_Join_32()
- { classifyJ("{ GRAPH ?g { ?x ?y ?z } { FILTER (?a) } }", true) ; }
+ { classifyJ("{ GRAPH ?g { ?x ?y ?z } { FILTER (?a) } }", false) ; }
// Use of a filter variable from the LHS
@Test public void testClassify_Join_33()
http://git-wip-us.apache.org/repos/asf/jena/blob/6f12cdbd/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestTransformQuads.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestTransformQuads.java b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestTransformQuads.java
index 20d7f3a..24d99e3 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestTransformQuads.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestTransformQuads.java
@@ -72,9 +72,10 @@ public class TestTransformQuads extends BaseTest
) ; }
// Nested and filter
+ // ?g is unbound in the filter.
@Test public void quads20() { test ("{ GRAPH ?g { ?s ?p ?o GRAPH ?g1 { ?s1 ?p1 ?o1 FILTER (str(?g) = 'graphURI') } } }",
"(assign ((?g ?*g0))" +
- " (sequence" +
+ " (join" +
" (quadpattern (quad ?*g0 ?s ?p ?o))" +
" (filter (= (str ?g) 'graphURI')" +
" (quadpattern (quad ?g1 ?s1 ?p1 ?o1)))))"
http://git-wip-us.apache.org/repos/asf/jena/blob/6f12cdbd/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestVarFinder.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestVarFinder.java b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestVarFinder.java
index aeb8332..b3eb539 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestVarFinder.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestVarFinder.java
@@ -35,57 +35,64 @@ public class TestVarFinder extends BaseTest
@Test public void varfind_01_1() { varfindFixed("(bgp (?s <p> <o>))", "s") ; }
@Test public void varfind_01_2() { varfindOpt("(bgp (?s <p> <o>))") ; }
@Test public void varfind_01_3() { varfindFilter("(bgp (?s <p> <o>))") ; }
+ @Test public void varfind_01_4() { varfindFilter("(bgp (?s <p> <o>))") ; }
@Test public void varfind_02_1() { varfindFixed("(graph ?g (bgp (?s <p> <o>)))", "s", "g") ; }
@Test public void varfind_02_2() { varfindOpt("(graph ?g (bgp (?s <p> <o>)))") ; }
@Test public void varfind_02_3() { varfindFilter("(graph ?g (bgp (?s <p> <o>)))") ; }
+ @Test public void varfind_02_4() { varfindFilterOnly("(graph ?g (bgp (?s <p> <o>)))") ; }
@Test public void varfind_03_1() { varfindFixed("(filter (?s) (bgp (?s <p> <o>)))", "s") ; }
@Test public void varfind_03_2() { varfindOpt("(filter (?s) (bgp (?s <p> <o>)))") ; }
@Test public void varfind_03_3() { varfindFilter("(filter (?s) (bgp (?s <p> <o>)))", "s") ; }
+ @Test public void varfind_03_4() { varfindFilterOnly("(filter (?s) (bgp (?s <p> <o>)))") ; }
+ @Test public void varfind_03_5() { varfindFilterOnly("(filter (?z) (bgp (?s <p> <o>)))", "z") ; }
@Test public void varfind_04_1() { varfindFixed("(leftjoin (bgp (?x <q> <v>)) (filter (?s) (bgp (?s <p> <o>))))", "x") ; }
@Test public void varfind_04_2() { varfindOpt("(leftjoin (bgp (?x <q> <v>)) (filter (?s) (bgp (?s <p> <o>))))", "s") ; }
@Test public void varfind_04_3() { varfindFilter("(leftjoin (bgp (?x <q> <v>)) (filter (?s) (bgp (?s <p> <o>))))", "s") ; }
+ @Test public void varfind_04_4() { varfindFilterOnly("(leftjoin (bgp (?x <q> <v>)) (filter (?Z) (bgp (?s <p> <o>))))", "Z") ; }
+ @Test public void varfind_04_5() { varfindFilterOnly("(leftjoin (bgp (?x <q> <v>)) (bgp (?s <p> <o>)) ?Z)", "Z") ; }
-
- private static void varfindFixed(String string, String...vars)
- {
- varfind(string, vars, null, null) ;
+ private static void varfindFixed(String string, String... vars) {
+ varfind(string, vars, null, null, null) ;
+ }
+
+ private static void varfindOpt(String string, String... vars) {
+ varfind(string, null, vars, null, null) ;
}
- private static void varfindOpt(String string, String...vars)
- {
- varfind(string, null, vars, null) ;
+ private static void varfindFilter(String string, String... vars) {
+ varfind(string, null, null, vars, null) ;
}
- private static void varfindFilter(String string, String...vars)
- {
- varfind(string, null, null, vars) ;
+ private static void varfindFilterOnly(String string, String... vars) {
+ varfind(string, null, null, null, vars) ;
}
- private static void varfind(String string, String[] varsFixed, String [] varsOpt, String [] varsFilter)
- {
+ private static void varfind(String string, String[] varsFixed, String[] varsOpt, String[] varsFilter, String[] varsFilterOnly) {
Op op = SSE.parseOp(string) ;
VarFinder vf = VarFinder.process(op) ;
- if ( varsFixed != null ) check(varsFixed, vf.getFixed()) ;
- if ( varsOpt != null ) check(varsOpt, vf.getOpt()) ;
- if ( varsFilter != null ) check(varsFilter, vf.getFilter()) ;
+ if ( varsFixed != null )
+ check(varsFixed, vf.getFixed()) ;
+ if ( varsOpt != null )
+ check(varsOpt, vf.getOpt()) ;
+ if ( varsFilter != null )
+ check(varsFilter, vf.getFilter()) ;
+ if ( varsFilterOnly != null )
+ check(varsFilterOnly, vf.getFilterOnly()) ;
}
- private static void check(String[] varsExpected, Set<Var> varsFound)
- {
+ private static void check(String[] varsExpected, Set<Var> varsFound) {
Var[] vars = new Var[varsExpected.length] ;
- for ( int i = 0 ; i < varsExpected.length ; i++ )
- {
+ for ( int i = 0 ; i < varsExpected.length ; i++ ) {
Var v = Var.alloc(varsExpected[i]) ;
vars[i] = v ;
}
-
+
List<Var> varList = Arrays.asList(vars) ;
HashSet<Var> varSet = new HashSet<>() ;
varSet.addAll(varList) ;
assertEquals(varSet, varsFound) ;
}
-
}