/**
* 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.
*/
package org.apache.jena.sparql.algebra.optimize ;
import java.util.Objects ;
import org.apache.jena.atlas.junit.BaseTest ;
import org.apache.jena.atlas.lib.StrUtils ;
import org.apache.jena.graph.Node ;
import org.apache.jena.sparql.algebra.Op ;
import org.apache.jena.sparql.algebra.Transform ;
import org.apache.jena.sparql.algebra.Transformer ;
import org.apache.jena.sparql.engine.ExecutionContext ;
import org.apache.jena.sparql.engine.QueryIterator ;
import org.apache.jena.sparql.engine.binding.Binding ;
import org.apache.jena.sparql.expr.ExprList ;
import org.apache.jena.sparql.pfunction.PropFuncArg ;
import org.apache.jena.sparql.pfunction.PropertyFunction ;
import org.apache.jena.sparql.pfunction.PropertyFunctionRegistry ;
import org.apache.jena.sparql.procedure.Procedure ;
import org.apache.jena.sparql.procedure.ProcedureBase ;
import org.apache.jena.sparql.procedure.ProcedureRegistry ;
import org.apache.jena.sparql.sse.SSE ;
import org.junit.Assert ;
import org.junit.Test ;
public class TestTransformFilterPlacement extends BaseTest { //extends AbstractTestTransform {
// ** Filter
@Test public void place_bgp_01() {
test("(filter (= ?x 1) (bgp ( ?s ?p ?x)))", "(filter (= ?x 1) (bgp ( ?s ?p ?x)))") ;
}
@Test public void place_bgp_02() {
test("(filter (= ?x 1) (bgp (?s ?p ?x) (?s1 ?p1 ?x1) ))",
"(sequence (filter (= ?x 1) (bgp ( ?s ?p ?x))) (bgp (?s1 ?p1 ?x1)))") ;
}
@Test public void place_bgp_03() {
test("(filter (= ?x 1) (bgp (?s ?p ?x) (?s1 ?p1 ?x) ))",
"(sequence (filter (= ?x 1) (bgp ( ?s ?p ?x))) (bgp (?s1 ?p1 ?x)))") ;
}
@Test public void place_bgp_03a() {
testNoBGP("(filter (= ?x 1) (bgp (?s ?p ?x) (?s1 ?p1 ?x) ))",
null) ;
}
@Test public void place_bgp_04() {
test("(filter (= ?XX 1) (bgp (?s ?p ?x) (?s1 ?p1 ?XX) ))",
"(filter (= ?XX 1) (bgp (?s ?p ?x) (?s1 ?p1 ?XX) ))") ;
// and not
// "(sequence (bgp (?s ?p ?x)) (filter (= ?XX 1) (?s1 ?p1 ?XX)) )"
}
@Test public void place_bgp_05() {
test("(filter (= ?x 123) (bgp (?s ?p ?x) (?s ?p ?x1) (?s ?p ?x2)) )",
"(sequence (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?x1) (?s ?p ?x2)) )") ;
}
@Test public void place_bgp_05a() {
// Won't push and break up the BGP
testNoBGP("(filter (= ?x 123) (bgp (?s ?p ?x) (?s ?p ?x1) (?s ?p ?x2)) )",
null) ;
}
@Test public void place_bgp_06() {
testNoChange("(filter (isURI ?g) (quadpattern (?g ?s ?p ?o) ))") ;
}
@Test public void place_bgp_06a() {
testNoBGP("(filter (isURI ?g) (quadpattern (?g ?s ?p ?o) ))",
null) ;
}
@Test public void place_bgp_07() {
test("(filter (isURI ?g) (quadpattern (?g ?s ?p ?o1) (?g ?s ?p ?o2) ))",
"(sequence (filter (isURI ?g) (quadpattern (?g ?s ?p ?o1) )) (quadpattern (?g ?s ?p ?o2)) )") ;
}
@Test public void place_bgp_07a() {
testNoBGP("(filter (isURI ?g) (quadpattern (?g ?s ?p ?o1) (?g ?s ?p ?o2) ))",
null) ;
}
@Test public void place_bgp_08() {
test("(filter (exprlist (isURI ?g) (= ?o2 123)) (quadpattern (?g ?s ?p ?o1) (?g ?s ?p ?o2) (?g ?s ?p ?o3) ))",
"(sequence (filter (= ?o2 123) (sequence (filter (isURI ?g) (quadpattern (?g ?s ?p ?o1))) (quadpattern (?g ?s ?p ?o2)))) (quadpattern (?g ?s ?p ?o3)) )") ;
}
@Test public void place_bgp_08a() {
testNoBGP("(filter (exprlist (isURI ?g) (= ?o2 123)) (quadpattern (?g ?s ?p ?o1) (?g ?s ?p ?o2) (?g ?s ?p ?o3) ))",
null) ;
}
@Test public void place_bgp_50() {
test(StrUtils.strjoinNL("(filter (exprlist (|| (|| (|| (&& (< \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?startDate1) (< ?endDate1 \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime>)) (&& (< ?startDate1 \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime>) (< \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?endDate1))) (&& (&& (<= ?startDate1 \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime>) (<= ?endDate1 \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime>)) (<= \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?endDate1))) (&& (&& (<= \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?startDate1) (<= \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?endDate1)) (<= ?startDate1 \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime>))) (! (sameTerm ?node2 <urn:foo>)))",
" (quadpattern",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?arg1Pred1 <urn:foo>)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?class1)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?arg2Pred1 ?node2)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?startDatePred1 ?startDate1)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?endDatePred1 ?endDate1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:class>)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:pred1> ?arg1Pred1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:pred2> ?arg2Pred1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:predStartDate> ?startDatePred1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:predEndDate> ?endDatePred1)",
"))"),
StrUtils.strjoinNL("(sequence",
" (filter (|| (|| (|| (&& (< \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?startDate1) (< ?endDate1 \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime>)) (&& (< ?startDate1 \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime>) (< \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?endDate1))) (&& (&& (<= ?startDate1 \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime>) (<= ?endDate1 \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime>)) (<= \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?endDate1))) (&& (&& (<= \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?startDate1) (<= \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?endDate1)) (<= ?startDate1 \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime>)))",
" (sequence",
" (filter (! (sameTerm ?node2 <urn:foo>))",
" (quadpattern",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?arg1Pred1 <urn:foo>)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?class1)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?arg2Pred1 ?node2)",
" ))",
" (quadpattern",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?startDatePred1 ?startDate1)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?endDatePred1 ?endDate1)",
" )))",
" (quadpattern",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:class>)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:pred1> ?arg1Pred1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:pred2> ?arg2Pred1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:predStartDate> ?startDatePred1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:predEndDate> ?endDatePred1)",
" ))"));
}
@Test public void place_bgp_50a() {
testNoBGP(StrUtils.strjoinNL("(filter (exprlist (|| (|| (|| (&& (< \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?startDate1) (< ?endDate1 \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime>)) (&& (< ?startDate1 \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime>) (< \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?endDate1))) (&& (&& (<= ?startDate1 \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime>) (<= ?endDate1 \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime>)) (<= \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?endDate1))) (&& (&& (<= \"2012-01-01T00:00:00\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?startDate1) (<= \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime> ?endDate1)) (<= ?startDate1 \"2012-12-31T23:59:59\"^^<http://www.w3.org/2001/XMLSchema#dateTime>))) (! (sameTerm ?node2 <urn:foo>)))",
" (quadpattern",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?arg1Pred1 <urn:foo>)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?class1)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?arg2Pred1 ?node2)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?startDatePred1 ?startDate1)",
" (quad <urn:x-arq:DefaultGraphNode> ?inst1 ?endDatePred1 ?endDate1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:class>)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:pred1> ?arg1Pred1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:pred2> ?arg2Pred1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:predStartDate> ?startDatePred1)",
" (quad <urn:x-arq:DefaultGraphNode> ?class1 <urn:predEndDate> ?endDatePred1)",
"))"), null);
}
@Test public void place_no_match_01() {
// Unbound
testNoChange("(filter (= ?x ?unbound) (bgp (?s ?p ?x)))") ;
}
@Test public void place_no_match_02() {
testNoChange("(filter (= ?x ?unbound) (bgp (?s ?p ?x) (?s ?p ?x)))") ;
}
@Test public void place_no_match_03() {
testNoChange("(filter (= ?x ?unbound) (bgp (?s ?p ?x) (?s1 ?p1 ?XX)))") ;
}
@Test public void place_sequence_01() {
test("(filter (= ?x 123) (sequence (bgp (?s ?p ?x)) (bgp (?s ?p ?z)) ))",
"(sequence (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?z)) )") ;
}
@Test public void place_sequence_02() {
// Given the sequence flows left into right, only need to filter in the
// LHS. The RHS can't introduce ?x because it would not be a legal sequence
// if, for example, it had a BIND in it.
test("(filter (= ?x 123) (sequence (bgp (?s ?p ?x)) (bgp (?s ?p ?x)) ))",
"(sequence (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?x)) )") ;
}
@Test public void place_sequence_03() {
test("(filter (= ?x 123) (sequence (bgp (?s ?p ?x)) (bgp (?s ?p ?x1)) (bgp (?s ?p ?x2)) ))",
"(sequence (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?x1)) (bgp (?s ?p ?x2)) )") ;
}
@Test public void place_sequence_04() {
test("(filter (= ?x 123) (sequence (bgp (?s ?p ?x1)) (bgp (?s ?p ?x)) (bgp (?s ?p ?x2)) ))",
"(sequence (bgp (?s ?p ?x1)) (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?x2)) )") ;
}
@Test public void place_sequence_04a() {
testNoBGP("(filter (= ?x 123) (sequence (bgp (?s ?p ?x1)) (bgp (?s ?p ?x)) (bgp (?s ?p ?x2)) ))",
"(sequence (bgp (?s ?p ?x1)) (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?x2)))") ;
}
@Test public void place_sequence_05() {
test("(filter (= ?x 123) (sequence (bgp (?s ?p ?x) (?s ?p ?x1)) (bgp (?s ?p ?x2)) ))",
"(sequence (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?x1)) (bgp (?s ?p ?x2)) )") ;
}
@Test public void place_sequence_05a() {
testNoBGP("(filter (= ?x 123) (sequence (bgp (?s ?p ?x) (?s ?p ?x1)) (bgp (?s ?p ?x2)) ))",
"(sequence (filter (= ?x 123) (bgp (?s ?p ?x) (?s ?p ?x1))) (bgp (?s ?p ?x2)))") ;
}
@Test public void place_sequence_06() {
test("(filter (= ?x 123) (sequence (bgp (?s ?p ?x1) (?s ?p ?x2)) (bgp (?s ?p ?x)) ))",
"(sequence (bgp (?s ?p ?x1) (?s ?p ?x2)) (filter (= ?x 123) (bgp (?s ?p ?x))) )") ;
}
@Test public void place_sequence_07() {
testNoChange("(filter (= ?A 123) (sequence (bgp (?s ?p ?x)) (bgp (?s ?p ?z)) ))") ;
}
@Test public void place_sequence_08() {
testNoChange("(sequence (bgp (?s ?p ?x)) (filter (= ?z 123) (bgp (?s ?p ?z))) )") ;
}
@Test public void place_sequence_09() {
test("(filter (= ?x 123) (sequence (bgp (?s ?p ?x1) (?s ?p ?x)) (bgp (?s ?p ?x2)) ))",
"(sequence (filter (= ?x 123) (bgp (?s ?p ?x1) (?s ?p ?x))) (bgp (?s ?p ?x2)) )") ;
}
@Test public void place_sequence_09a() {
testNoBGP("(filter (= ?x 123) (sequence (bgp (?s ?p ?x1) (?s ?p ?x)) (bgp (?s ?p ?x2)) ))",
"(sequence (filter (= ?x 123) (bgp (?s ?p ?x1) (?s ?p ?x))) (bgp (?s ?p ?x2)) )") ;
}
// Join : one sided push.
@Test public void place_join_01() {
test("(filter (= ?x 123) (join (bgp (?s ?p ?x)) (bgp (?s ?p ?z)) ))",
"(join (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?z)) )") ;
}
// Join : two side push
@Test public void place_join_02() {
test("(filter (= ?x 123) (join (bgp (?s ?p ?x)) (bgp (?s ?p ?x)) ))",
"(join (filter (= ?x 123) (bgp (?s ?p ?x))) (filter (= ?x 123) (bgp (?s ?p ?x))) )") ;
}
@Test public void place_join_03() {
String x = StrUtils.strjoinNL
("(filter ((= 13 14) (> ?o1 12) (< ?o 56) (< (+ ?o ?o1) 999))",
" (join",
" (bgp (triple ?s ?p ?o))" ,
" (bgp (triple ?s ?p1 ?o1))))") ;
// Everything pushed down once.
String y = StrUtils.strjoinNL
("(filter (< (+ ?o ?o1) 999)",
" (join",
" (filter ((= 13 14) (< ?o 56))",
" (bgp (triple ?s ?p ?o)))",
" (filter ((= 13 14) (> ?o1 12))",
" (bgp (triple ?s ?p1 ?o1)))))") ;
// Recursive push in - causes (= 13 14) to go into BGP
String y1 = StrUtils.strjoinNL
("(filter (< (+ ?o ?o1) 999)",
" (join",
" (filter (< ?o 56)",
" (sequence",
" (filter (= 13 14)",
" (table unit))",
" (bgp (triple ?s ?p ?o))))",
" (filter (> ?o1 12)",
" (sequence",
" (filter (= 13 14)",
" (table unit))",
" (bgp (triple ?s ?p1 ?o1))))",
" ))") ;
test(x, y1) ;
}
@Test public void place_conditional_01() {
test("(filter (= ?x 123) (conditional (bgp (?s ?p ?x)) (bgp (?s ?p ?z)) ))",
"(conditional (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?z)) )") ;
}
@Test public void place_conditional_02() {
test("(filter (= ?z 123) (conditional (bgp (?s ?p ?x)) (bgp (?s ?p ?z)) ))",
"(filter (= ?z 123) (conditional (bgp (?s ?p ?x)) (bgp (?s ?p ?z)) ))") ;
}
@Test public void place_conditional_03() {
test("(filter (= ?x 123) (conditional (bgp (?s ?p ?x)) (bgp (?s ?p ?x)) ))",
"(conditional (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?x)) )") ;
}
@Test public void place_leftjoin_01() {
// conditional
test("(filter (= ?x 123) (leftjoin (bgp (?s ?p ?x)) (bgp (?s ?p ?z)) ))",
"(leftjoin (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?z)) )") ;
}
@Test public void place_leftjoin_02() {
// conditional
test("(filter (= ?z 123) (leftjoin (bgp (?s ?p ?x)) (bgp (?s ?p ?z)) ))",
"(filter (= ?z 123) (leftjoin (bgp (?s ?p ?x)) (bgp (?s ?p ?z)) ))") ;
}
@Test public void place_leftjoin_03() {
// conditional
test("(filter (= ?x 123) (leftjoin (bgp (?s ?p ?x)) (bgp (?s ?p ?x)) ))",
"(leftjoin (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?x)) )") ;
}
@Test public void place_project_01() {
test("(filter (= ?x 123) (project (?x) (bgp (?s ?p ?x)) ))",
"(project (?x) (filter (= ?x 123) (bgp (?s ?p ?x)) ))") ;
}
@Test public void place_project_02() {
testNoChange("(filter (= ?x 123) (project (?s) (bgp (?s ?p ?x)) ))") ;
}
@Test public void place_project_03() {
test("(filter (= ?x 123) (project (?x) (bgp (?s ?p ?x) (?s ?p ?z) ) ))",
"(project (?x) (sequence (filter (= ?x 123) (bgp (?s ?p ?x)) ) (bgp (?s ?p ?z))) )") ;
}
@Test public void place_distinct_01() {
test("(filter (= ?x 123) (distinct (bgp (?s ?p ?x)) ))",
"(distinct (filter (= ?x 123) (bgp (?s ?p ?x)) ))") ;
}
@Test public void place_distinct_02() {
test("(filter (= ?x 123) (distinct (bgp (?s ?p ?o)) ))",
null) ;
}
@Test public void place_distinct_03() {
test("(filter (= ?x 123) (distinct (extend ((?x 123)) (bgp (?s ?p ?o)) )))",
"(distinct (filter (= ?x 123) (extend ((?x 123)) (bgp (?s ?p ?o)) )))") ;
}
@Test public void place_distinct_04() {
test("(filter ((= ?o 456) (= ?z 987)) (distinct (bgp (?s ?p ?o) )))",
"(filter (= ?z 987) (distinct (filter (= ?o 456) (bgp (?s ?p ?o) ))))") ;
}
@Test public void place_reduced_01() {
test("(filter (= ?x 123) (reduced (bgp (?s ?p ?x)) ))",
"(reduced (filter (= ?x 123) (bgp (?s ?p ?x)) ))") ;
}
@Test public void place_reduced_02() {
test("(filter (= ?x 123) (reduced (bgp (?s ?p ?o)) ))",
null) ;
}
@Test public void place_reduced_04() {
test("(filter ((= ?o 456) (= ?z 987)) (reduced (bgp (?s ?p ?o) )))",
"(filter (= ?z 987) (reduced (filter (= ?o 456) (bgp (?s ?p ?o) ))))") ;
}
@Test public void place_reduced_03() {
test("(filter (= ?x 123) (reduced (extend ((?x 123)) (bgp (?s ?p ?o)) )))",
"(reduced (filter (= ?x 123) (extend ((?x 123)) (bgp (?s ?p ?o)) )))") ;
}
@Test public void place_extend_01() {
test("(filter (= ?x 123) (extend ((?z 123)) (bgp (?s ?p ?x)) ))",
"(extend ((?z 123)) (filter (= ?x 123) (bgp (?s ?p ?x)) ))") ;
}
@Test public void place_extend_02() {
test("(filter ((= ?x1 123) (= ?x2 456)) (extend (?z 789) (bgp (?s ?p ?x1)) ))",
"(filter (= ?x2 456) (extend (?z 789) (filter (= ?x1 123) (bgp (?s ?p ?x1)) )))") ;
}
@Test public void place_extend_03() { // Blocked
test("(filter (= ?x 123) (extend ((?x 123)) (bgp (?s ?p ?z)) ))",
null) ;
}
@Test public void place_extend_04() {
test("(filter (= ?x 123) (extend ((?x1 123)) (filter (< ?x 456) (bgp (?s ?p ?x) (?s ?p ?z))) ))",
"(extend (?x1 123) (sequence (filter ((= ?x 123) (< ?x 456)) (bgp (?s ?p ?x))) (bgp (?s ?p ?z))) )") ;
}
@Test public void place_extend_05() {
// Filter further out than one place.
test("(filter (= ?z 1) (sequence (extend (?x1 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?z))))",
"(sequence (extend (?x1 123) (bgp (?s ?p ?x))) (filter (= ?z 1) (bgp (?s ?p ?z)) ))") ;
}
@Test public void place_extend_06() {
// Filter further out than one place.
test("(filter (= ?z 1) (join (extend (?x1 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?z))))" ,
"(join (extend (?x1 123) (bgp (?s ?p ?x))) (filter (= ?z 1) (bgp (?s ?p ?z))) )") ;
}
@Test public void place_extend_07() {
// Push filters through extend where the extend itself is over an
// extend that can have filters pushed into it.
String x1 = StrUtils.strjoinNL
("(filter ( (= ?s 5) (= ?w 6) (= ?s1 7) )"
," (extend ((?w 2))"
," (extend ((?s 1))"
," (table (vars ?s1)"
," (row [?s1 1])"
,"))))") ;
String x2 = StrUtils.strjoinNL
("(filter (= ?w 6)"
," (extend ((?w 2))"
," (filter (= ?s 5)"
," (extend ((?s 1))"
," (filter (= ?s1 7)"
," (table (vars ?s1)"
," (row [?s1 1])"
," ))))))") ;
test(x1, x2) ;
}
@Test public void place_extend_08() {
// Push filters through extend where the extend itself is over an
// extend that can have filters pushed into it.
String x1 = StrUtils.strjoinNL
("(filter ( (= ?s 'S') (= ?w 'W') (= ?s1 'S1') (= ?a 'A') (= ?b 'B'))"
," (extend ((?w 2))"
," (extend ((?s 1))"
," (distinct"
," (extend ((?a 2))"
," (extend ((?b 1))"
," (table (vars ?s1)"
," (row [?s1 1])"
,")))))))"
) ;
String x2 = StrUtils.strjoinNL
("(filter (= ?w 'W')"
," (extend ((?w 2))"
," (filter (= ?s 'S')"
," (extend ((?s 1))"
," (distinct"
," (filter (= ?a 'A')"
," (extend ((?a 2))"
," (filter (= ?b 'B')"
," (extend ((?b 1))"
," (filter (= ?s1 'S1')"
," (table (vars ?s1)"
," (row [?s1 1])"
," )))))))))))"
) ;
test(x1, x2) ;
}
@Test public void place_assign_01() {
test("(filter (= ?x 123) (assign ((?z 123)) (bgp (?s ?p ?x)) ))",
"(assign ((?z 123)) (filter (= ?x 123) (bgp (?s ?p ?x)) ))") ;
}
@Test public void place_assign_02() {
test("(filter ((= ?x1 123) (= ?x2 456)) (assign (?z 789) (bgp (?s ?p ?x1)) ))",
"(filter (= ?x2 456) (assign (?z 789) (filter (= ?x1 123) (bgp (?s ?p ?x1)) )))"
) ;
}
@Test public void place_assign_03() { // Blocked
test("(filter (= ?x 123) (assign ((?x 123)) (bgp (?s ?p ?z)) ))",
null) ;
}
@Test public void place_assign_04() {
// Caution - OpFilter equality is sensitive to the order of expressions
test("(filter (= ?x 123) (assign ((?x1 123)) (filter (< ?x 456) (bgp (?s ?p ?x) (?s ?p ?z))) ))",
"(assign (?x1 123) (sequence (filter ((= ?x 123) (< ?x 456)) (bgp (?s ?p ?x))) (bgp (?s ?p ?z))) )") ;
}
@Test public void place_assign_05() {
// Even with No BGP we can still wrap a BGP without breaking it
testNoBGP("(filter (= ?x 123) (assign ((?z 123)) (bgp (?s ?p ?x)) ))",
"(assign ((?z 123)) (filter (= ?x 123) (bgp (?s ?p ?x)) ))") ;
}
@Test public void place_assign_06() {
test("(filter (= ?x 123) (assign ((?z 123)) (bgp (?s ?p ?x) (?s ?p ?x1) )))",
"(assign ((?z 123)) (sequence (filter (= ?x 123) (bgp (?s ?p ?x)) ) (bgp (?s ?p ?x1)) ) )") ;
}
@Test public void place_assign_06a() {
// With No BGP we won't break up the BGP but we will still push the filter down
testNoBGP("(filter (= ?x 123) (assign ((?z 123)) (bgp (?s ?p ?x) (?s ?p ?x1) )))",
"(assign ((?z 123)) (filter (= ?x 123) (bgp (?s ?p ?x) (?s ?p ?x1)) ) )") ;
}
@Test public void place_assign_07() {
// Push filters through assign where the assign itself is over an
// assign that can have filters pushed into it.
String x1 = StrUtils.strjoinNL
("(filter ( (= ?s 5) (= ?w 6) (= ?s1 7) )"
," (assign ((?w 2))"
," (assign ((?s 1))"
," (table (vars ?s1)"
," (row [?s1 1])"
,"))))") ;
String x2 = StrUtils.strjoinNL
("(filter (= ?w 6)"
," (assign ((?w 2))"
," (filter (= ?s 5)"
," (assign ((?s 1))"
," (filter (= ?s1 7)"
," (table (vars ?s1)"
," (row [?s1 1])"
," ))))))") ;
test(x1, x2) ;
}
@Test public void place_assign_08() {
// Push filters through assign where the assign itself is over an
// assign that can have filters pushed into it.
String x1 = StrUtils.strjoinNL
("(filter ( (= ?s 'S') (= ?w 'W') (= ?s1 'S1') (= ?a 'A') (= ?b 'B'))"
," (assign ((?w 2))"
," (assign ((?s 1))"
," (distinct"
," (assign ((?a 2))"
," (assign ((?b 1))"
," (table (vars ?s1)"
," (row [?s1 1])"
,")))))))"
) ;
String x2 = StrUtils.strjoinNL
("(filter (= ?w 'W')"
," (assign ((?w 2))"
," (filter (= ?s 'S')"
," (assign ((?s 1))"
," (distinct"
," (filter (= ?a 'A')"
," (assign ((?a 2))"
," (filter (= ?b 'B')"
," (assign ((?b 1))"
," (filter (= ?s1 'S1')"
," (table (vars ?s1)"
," (row [?s1 1])"
," )))))))))))"
) ;
test(x1, x2) ;
}
@Test public void place_filter_01() {
test("(filter (= ?x 123) (filter (= ?y 456) (bgp (?s ?p ?x) (?s ?p ?y)) ))" ,
"(filter (= ?y 456) (sequence (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?y)) ))" ) ;
}
@Test public void place_filter_02() {
test("(filter (= ?x 123) (filter (= ?y 456) (bgp (?s ?p ?x) (?s ?p ?y) (?s ?p ?z) )))" ,
"(sequence (filter (= ?y 456) (sequence (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?y)))) (bgp (?s ?p ?z)))") ;
}
// JENA-881
@Test public void place_filter_03() {
String x1 = StrUtils.strjoinNL
("(filter true"
," (union"
," (table empty)"
," (filter (= ?z 3)"
," (table unit))))"
) ;
String x2 = StrUtils.strjoinNL
("(union"
," (filter true"
," (table empty))"
," (filter (exprlist true (= ?z 3))"
," (table unit)))"
) ;
test(x1, x2) ;
}
// JENA-881
@Test public void place_filter_04() {
String x1 = StrUtils.strjoinNL
("(filter true"
," (union"
," (filter false"
," (table unit))"
," (filter (!= ?z 3)"
," (table unit))))"
) ;
String x2 = StrUtils.strjoinNL
("(union"
," (filter (exprlist true false)"
," (table unit))"
," (filter (exprlist true (!= ?z 3))"
," (table unit)))"
) ;
test(x1, x2) ;
}
// JENA-881
@Test public void place_filter_05() {
String x1 = StrUtils.strjoinNL
("(filter (= ?z 3)"
," (sequence"
," (filter (= ?y 3)"
," (table unit))"
," (bgp (triple ?s ?p ?z))))"
) ;
String x2 = StrUtils.strjoinNL
("(sequence"
," (filter (= ?y 3)"
," (table unit))"
," (filter (= ?z 3)"
," (bgp (triple ?s ?p ?z))))"
) ;
test(x1, x2) ;
}
@Test public void place_union_01() {
test("(filter (= ?x 123) (union (bgp (?s ?p ?x) (?s ?p ?y)) (bgp (?s ?p ?z) (?s1 ?p1 ?x)) ))",
"(union (sequence (filter (= ?x 123) (bgp (?s ?p ?x))) (bgp (?s ?p ?y))) "+
"(filter (= ?x 123) (bgp (?s ?p ?z) (?s1 ?p1 ?x)) ))") ;
}
@Test public void place_union_02() {
String in = StrUtils.strjoinNL
("(filter 1"
," (union"
, " (bgp (triple ?s ?p ?o))"
," (filter 0 (table unit))"
,"))"
) ;
String out = StrUtils.strjoinNL
("(union"
," (sequence"
," (filter 1 (table unit))"
, " (bgp (triple ?s ?p ?o)))"
," (filter (exprlist 1 0) (table unit))"
,")"
);
test(in, out) ;
}
@Test public void place_union_02a() {
String in = StrUtils.strjoinNL
("(filter 1"
," (union"
, " (bgp (triple ?s ?p ?o))"
," (filter 0 (table unit))"
,"))"
) ;
String out = StrUtils.strjoinNL
("(union"
," (filter 1 (bgp (triple ?s ?p ?o)))"
," (filter (exprlist 1 0) (table unit))"
,")"
);
testNoBGP(in, out) ;
}
@Test public void place_union_03() {
String in = StrUtils.strjoinNL
("(slice _ 1"
," (project (?s ?p ?o)"
," (filter 1"
," (union"
," (bgp (?s ?p ?o))"
," (filter 0 (table unit))"
," ))"
,"))"
) ;
String out = StrUtils.strjoinNL
("(slice _ 1"
," (project (?s ?p ?o)"
," (union"
," (sequence"
," (filter 1 (table unit))"
," (bgp (?s ?p ?o)))"
," (filter (exprlist 1 0)"
," (table unit))"
, ")"
,"))");
test(in, out) ;
}
@Test public void place_union_03a() {
String in = StrUtils.strjoinNL
("(slice _ 1"
," (project (?s ?p ?o)"
," (filter 1"
," (union"
," (bgp (?s ?p ?o))"
," (filter 0 (table unit))"
," ))"
,"))"
) ;
String out = StrUtils.strjoinNL
("(slice _ 1"
," (project (?s ?p ?o)"
," (union"
," (filter 1 (bgp (?s ?p ?o)))"
," (filter (exprlist 1 0) (table unit))"
, ")"
,"))");
testNoBGP(in, out) ;
}
// Union - push outer filters into each arm.
@Test public void place_union_04() {
String in = StrUtils.strjoinNL
("(filter (= 1 1)"
," (union"
," (bgp (triple ?s ?p ?o))"
," (filter (!= 0 0)"
," (table unit))))"
) ;
String out = StrUtils.strjoinNL
("(union"
," (sequence"
," (filter (= 1 1)"
," (table unit))"
," (bgp (triple ?s ?p ?o)))"
," (filter (exprlist (= 1 1) (!= 0 0))"
," (table unit)))"
) ;
test ( in, out ) ;
}
@Test public void place_union_04a() {
String in = StrUtils.strjoinNL
("(filter (= 1 1)"
," (union"
," (bgp (triple ?s ?p ?o))"
," (filter (!= 0 0)"
," (table unit))))"
) ;
String out = StrUtils.strjoinNL
("(union"
," (filter (= 1 1)"
," (bgp (triple ?s ?p ?o)))"
," (filter (exprlist (= 1 1) (!= 0 0))"
," (table unit)))"
) ;
testNoBGP ( in, out ) ;
}
// Unrelated filter
@Test public void place_union_05() {
String in = StrUtils.strjoinNL
("(filter (= ?x 1)"
," (union"
," (bgp (triple ?s ?p ?o))"
," (bgp (triple ?s ?p ?o))"
,"))"
) ;
String out = in ;
test( in, out ) ;
}
// Unrelated filter
@Test public void place_union_05a() {
String in = StrUtils.strjoinNL
("(filter (= ?x 1)"
," (union"
," (bgp (triple ?s ?p ?o))"
," (bgp (triple ?s ?p ?o))"
,"))"
) ;
String out = in ;
testNoBGP( in, out ) ;
}
// Filter in one arm but not the other.
// Push and also leave to be placed again.
@Test public void place_union_06() {
String in = StrUtils.strjoinNL
("(filter (= ?x 1)"
," (union"
," (bgp (triple ?s ?p ?o))"
," (bgp (triple ?s ?p ?x))"
,"))"
) ;
String out = StrUtils.strjoinNL
("(filter (= ?x 1)"
," (union"
," (bgp (triple ?s ?p ?o))"
," (filter (= ?x 1) (bgp (triple ?s ?p ?x)))"
,"))"
) ;
test( in, out ) ;
}
// Filter in one arm but not the other
@Test public void place_union_07() {
String in = StrUtils.strjoinNL
("(filter (= ?x 1)"
," (union"
," (bgp (triple ?s ?p ?x))"
," (bgp (triple ?s ?p ?o))"
,"))"
) ;
String out = StrUtils.strjoinNL
("(filter (= ?x 1)"
," (union"
," (filter (= ?x 1) (bgp (triple ?s ?p ?x)))"
," (bgp (triple ?s ?p ?o))"
,"))"
) ;
test( in, out ) ;
}
// JENA-1235
@Test public void place_disjunction_01() {
String in = StrUtils.strjoinNL
(
"(filter (exprlist (!= ?VAR 123) (regex ?var4 'pat1'))"
," (disjunction"
," (bgp (?var2 :p1 ?var4) (?var2 :p2 ?var3))"
," (bgp (?var2 :p3 ?var4) (?var2 :p4 ?var3))"
," ))"
) ;
String out = StrUtils.strjoinNL
("(filter (!= ?VAR 123)"
," (disjunction"
," (sequence"
," (filter (regex ?var4 'pat1')"
," (bgp (triple ?var2 :p1 ?var4)))"
," (bgp (triple ?var2 :p2 ?var3)))"
," (sequence"
," (filter (regex ?var4 'pat1')"
," (bgp (triple ?var2 :p3 ?var4)))"
," (bgp (triple ?var2 :p4 ?var3)))))"
) ;
test( in, out ) ;
}
// Push in, push and wrap, wrap.
@Test public void place_disjunction_02() {
String in = StrUtils.strjoinNL
(
"(filter (exprlist (!= ?VAR 123) (regex ?var4 'pat1'))"
," (disjunction"
," (bgp (?var2 :p1 ?var4) (?var2 :p2 ?var3))"
," (bgp (?var2 :p4 ?var3) (?var2 :p3 ?var4))"
," (bgp (?var2 :p4 ?var9))"
," ))"
) ;
String out = StrUtils.strjoinNL
("(filter (!= ?VAR 123)"
," (disjunction"
," (sequence"
," (filter (regex ?var4 'pat1')"
," (bgp (triple ?var2 :p1 ?var4)))"
," (bgp (triple ?var2 :p2 ?var3)))"
," (filter (regex ?var4 'pat1')"
," (bgp"
," (triple ?var2 :p4 ?var3)"
," (triple ?var2 :p3 ?var4)"
," ))"
," (filter (regex ?var4 'pat1')"
," (bgp (triple ?var2 :p4 ?var9)))))"
) ;
test( in, out ) ;
}
private static String propertyFunctionURI = "http://example/PF" ;
// Dummy property
private static PropertyFunction dummyPropertyFunction = new PropertyFunction() {
@Override
public QueryIterator exec(QueryIterator input, PropFuncArg argSubject, Node predicate, PropFuncArg argObject, ExecutionContext execCxt) {
return null;
}
@Override
public void build(PropFuncArg argSubject, Node predicate, PropFuncArg argObject, ExecutionContext execCxt) {}
};
private static void test_property_function(Runnable action) {
PropertyFunctionRegistry.get().put(propertyFunctionURI, dummyPropertyFunction.getClass());
try {
action.run();
} finally {
PropertyFunctionRegistry.get().remove(propertyFunctionURI) ;
}
}
@Test public void place_property_functions_01() {
// No filter.
test_property_function(()->{
String in = "(propfunc :PF ?pfSubjArg (?pfObjArg1 ?pfObjArg2) (bgp(?s ?p ?o)))" ;
String out = in ;
test( in, out ) ;
}) ;
}
@Test public void place_property_functions_02() {
test_property_function(()->{
String in = StrUtils.strjoinNL
("(filter ((= ?x 1)(= ?o 9))"
," (propfunc :PF ?pfSubjArg (?pfObjArg1 ?pfObjArg2)"
," (bgp (?s ?p ?o))"
," ))"
) ;
String out = StrUtils.strjoinNL
("(filter (= ?x 1)"
," (propfunc :PF ?pfSubjArg (?pfObjArg1 ?pfObjArg2)"
," (filter (= ?o 9)"
," (bgp (triple ?s ?p ?o))"
," )))"
) ;
test( in, out ) ;
}) ;
}
@Test public void place_property_functions_02a() {
test_property_function(()->{
String in = StrUtils.strjoinNL
("(filter (= ?x 1)"
," (propfunc :PF ?pfSubjArg (?pfObjArg1 ?pfObjArg2)"
," (bgp (?s ?p ?o))"
," ))"
) ;
String out = in ;
test( in, out ) ;
}) ;
}
@Test public void place_property_functions_02b() {
test_property_function(()->{
String in = StrUtils.strjoinNL
("(filter (= ?o 9)"
," (propfunc :PF ?pfSubjArg (?pfObjArg1 ?pfObjArg2)"
," (bgp (?s ?p ?o))"
," ))"
) ;
String out = StrUtils.strjoinNL
("(propfunc :PF ?pfSubjArg (?pfObjArg1 ?pfObjArg2)"
," (filter (= ?o 9)"
," (bgp (triple ?s ?p ?o))"
," ))"
) ;
test( in, out ) ;
}) ;
}
@Test public void place_property_functions_03() {
test_property_function(()->{
String in = StrUtils.strjoinNL
("(filter ((= ?pfSubjArg 1)(= ?o 9))"
," (propfunc :PF ?pfSubjArg (?pfObjArg1 ?pfObjArg2)"
," (bgp (?s ?p ?o))"
," ))"
) ;
String out = StrUtils.strjoinNL
("(filter (= ?pfSubjArg 1)"
," (propfunc :PF ?pfSubjArg (?pfObjArg1 ?pfObjArg2)"
," (filter (= ?o 9)"
," (bgp (triple ?s ?p ?o))"
," )))"
) ;
test( in, out ) ;
}) ;
}
@Test public void place_property_functions_04() {
test_property_function(()->{
String in = StrUtils.strjoinNL
("(filter ((= ?pfObjArg 1)(= ?o 9))"
," (propfunc :PF ?pfSubjArg (?pfObjArg1 ?pfObjArg2)"
," (bgp (?s ?p ?o))"
," ))"
) ;
String out = StrUtils.strjoinNL
("(filter (= ?pfObjArg 1)"
," (propfunc :PF ?pfSubjArg (?pfObjArg1 ?pfObjArg2)"
," (filter (= ?o 9)"
," (bgp (triple ?s ?p ?o))"
," )))"
) ;
test( in, out ) ;
}) ;
}
private static String procedureURI = "http://example/PROC" ;
// Dummy procedure
private static Procedure dummyProcedure = new ProcedureBase() {
@Override
public QueryIterator exec(Binding binding, Node name, ExprList args, ExecutionContext execCxt) {
return null;
}
};
private static void test_procedure(Runnable action) {
ProcedureRegistry.get().put(procedureURI, dummyProcedure.getClass());
try {
action.run();
} finally {
ProcedureRegistry.get().remove(procedureURI) ;
}
}
@Test public void place_procedure_01() {
test_procedure(()->{
String in = "(proc :PROC ((+ ?arg1 111) (?arg2)) (bgp (?s ?p ?o)))" ;
String out = in ;
test( in, out ) ;
}) ;
}
@Test public void place_procedure_02() {
test_procedure(()->{
String in = StrUtils.strjoinNL
("(filter (= ?o 9)"
," (proc :PROC ((+ ?arg1 111) (?arg2))"
," (bgp (?s ?p ?o))"
," ))"
) ;
String out = StrUtils.strjoinNL
("(proc :PROC ((+ ?arg1 111) (?arg2))"
," (filter (= ?o 9)"
," (bgp (?s ?p ?o))"
," ))"
) ;
test( in, out ) ;
}) ;
}
@Test public void place_procedure_03() {
test_procedure(()->{
String in = StrUtils.strjoinNL
("(filter (= ?x 9)"
," (proc :PROC ((+ ?arg1 111) (?arg2))"
," (bgp (?s ?p ?o))"
," ))"
) ;
String out = in ;
test( in, out ) ;
}) ;
}
@Test public void place_procedure_04() {
test_procedure(()->{
String in = StrUtils.strjoinNL
("(filter (= ?arg1 9)"
," (proc :PROC ((+ ?arg1 111) (?arg2))"
," (bgp (?s ?p ?o))"
," ))"
) ;
String out = in ;
test( in, out ) ;
}) ;
}
@Test public void place_procedure_05() {
test_procedure(()->{
String in = StrUtils.strjoinNL
("(filter ((= ?x 9) (= ?o 11) (= ?arg2 19))"
," (proc :PROC ((+ ?arg1 111) (?arg2))"
," (bgp (?s ?p ?o))"
," ))"
) ;
String out = StrUtils.strjoinNL
("(filter ((= ?x 9) (= ?arg2 19))"
," (proc :PROC ((+ ?arg1 111) (?arg2))"
," (filter (= ?o 11)"
," (bgp (?s ?p ?o))"
," )))"
) ;
test( in, out ) ;
}) ;
}
@Test public void nondeterministic_functions_01() {
testNoChange("(filter (= ?x (rand)) (bgp (?s ?p ?x) (?s1 ?p1 ?x)))") ;
}
@Test public void nondeterministic_functions_02() {
testNoChange("(filter (= ?x (bnode)) (bgp (?s ?p ?x) (?s1 ?p1 ?x)))") ;
}
@Test public void nondeterministic_functions_03() {
testNoChange("(filter (= ?x (struuid)) (bgp (?s ?p ?x) (?s1 ?p1 ?x)))") ;
}
@Test public void nondeterministic_functions_04() {
testNoChange("(filter (= ?x (uuid)) (bgp (?s ?p ?x) (?s1 ?p1 ?x)))") ;
}
// NOW() is safe.
@Test public void nondeterministic_functions_05() {
test("(filter (= ?x (now)) (bgp (?s ?p ?x) (?s1 ?p1 ?x)))",
"(sequence (filter (= ?x (now)) (bgp (?s ?p ?x) )) (bgp (?s1 ?p1 ?x)) )") ;
}
@Test public void nondeterministic_functions_06() {
String in = StrUtils.strjoinNL
("(filter ( (!= ?x ?s) (= ?x (rand)) )"
," (bgp (?s ?p ?x) (?s1 ?p1 ?x))"
,")") ;
String out = StrUtils.strjoinNL
("(filter (= ?x (rand)) "
," (sequence"
," (filter (!= ?x ?s) (bgp (?s ?p ?x)))"
," (bgp (?s1 ?p1 ?x))"
,"))"
) ;
test(in,out) ;
}
@Test public void nondeterministic_functions_07() {
String in = StrUtils.strjoinNL
("(filter ( (!= ?x ?s) (|| ?x (rand)) )"
," (bgp (?s ?p ?x) (?s1 ?p1 ?x))"
,")") ;
String out = StrUtils.strjoinNL
("(filter (|| ?x (rand)) "
," (sequence"
," (filter (!= ?x ?s) (bgp (?s ?p ?x)))"
," (bgp (?s1 ?p1 ?x))"
,"))"
) ;
test(in,out) ;
}
public static void testNoChange(String input) {
test(input, null) ;
}
public static void test(String input, String output) {
test$(input, output, true) ;
}
public static void testNoBGP(String input , String output) {
test$(input, output, false) ;
}
public static void test$(String input, String output, boolean includeBGPs) {
Transform t_placement = new TransformFilterPlacement(includeBGPs) ;
Op op1 = SSE.parseOp(input) ;
Op op2 = Transformer.transform(t_placement, op1) ;
if ( output == null ) {
// No transformation.
Assert.assertEquals(op1, op2) ;
return ;
}
Op op3 = SSE.parseOp(output) ;
if ( ! Objects.equals(op2, op3) ) {
System.out.println("Expected:") ;
System.out.println(op3);
System.out.println("Got:") ;
System.out.println(op2);
}
Assert.assertEquals(op3, op2) ;
}
}