/*
* 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 org.apache.jena.JenaRuntime ;
import org.apache.jena.atlas.lib.StrUtils ;
import org.apache.jena.sparql.algebra.Op ;
import org.apache.jena.sparql.algebra.Transform ;
import org.apache.jena.sparql.algebra.TransformCopy ;
import org.apache.jena.sparql.algebra.Transformer ;
import org.apache.jena.sparql.sse.SSE ;
import org.junit.Test ;
/** Tests of transforms related to filters */
public class TestTransformFilterEquality extends AbstractTestTransform
{
private Transform t_equality = new TransformFilterEquality() ;
@Test public void equality01() {
testOp("(filter (= ?x <x>) (bgp ( ?s ?p ?x)) )",
t_equality,
"(assign ((?x <x>)) (bgp ( ?s ?p <x>)) )") ;
}
@Test public void equality02() {
if ( JenaRuntime.isRDF11 ) {
// Safe on strings (RDF 1.1)
testOp("(filter (= ?x 'x') (bgp ( ?s ?p ?x)) )",
t_equality,
"(assign ((?x 'x')) (bgp ( ?s ?p 'x')) )") ;
} else {
// Not safe on strings (RDF 1.0)
testOp("(filter (= ?x 'x') (bgp ( ?s ?p ?x)) )",
t_equality,
(String[])null) ;
}
}
@Test public void equality02a() {
if ( JenaRuntime.isRDF11 ) {
// Safe on strings (RDF 1.1)
testOp("(filter (= ?x 'x'^^xsd:string) (bgp ( ?s ?p ?x)) )",
t_equality,
"(assign ((?x 'x')) (bgp ( ?s ?p 'x')) )") ;
} else {
// Not safe on strings (RDF 1.0)
testOp("(filter (= ?x 'x'^^xsd:string) (bgp ( ?s ?p ?x)) )",
t_equality,
(String[])null) ;
}
}
@Test public void equality03() {
// Not safe on numbers
testOp("(filter (= ?x 123) (bgp ( ?s ?p ?x)) )",
t_equality,
(String[])null) ;
}
// // JENA-1184 workaround - this optimization is current not active.
// @Test public void equality04() {
// // Eliminate unused
// testOp("(filter (= ?UNUSED <x>) (bgp ( ?s ?p ?x)) )",
// t_equality,
// "(table empty)") ;
// }
@Test public void equality05() {
// Can't optimize if filter does not cover vars in LHS
testOp("(filter (= ?x2 <x>) (conditional (bgp ( ?s1 ?p1 ?x1)) (bgp ( ?s2 ?p2 ?x2))))",
t_equality,
"(filter (= ?x2 <x>) (conditional (bgp ( ?s1 ?p1 ?x1)) (bgp ( ?s2 ?p2 ?x2))))") ;
}
@Test public void equality06() {
testOp("(filter (= ?x <x>) (conditional (bgp ( ?s ?p ?x)) (bgp ( ?s ?p ?x))))",
t_equality,
"(assign((?x <x>)) (conditional (bgp ( ?s ?p <x>)) (bgp ( ?s ?p <x>))))") ;
}
@Test public void equality07() {
testOp("(filter (= ?x <x>) (conditional (bgp ( ?s ?p ?x)) (bgp ( ?s ?p ?x1))))",
t_equality,
"(assign((?x <x>)) (conditional (bgp ( ?s ?p <x>)) (bgp ( ?s ?p ?x1))))") ;
}
@Test public void equality08() {
testOp("(filter (= ?x1 <x>) (conditional (bgp ( ?s ?p ?x)) (bgp ( ?s ?p ?x1))))",
t_equality,
"(filter (= ?x1 <x>) (conditional (bgp ( ?s ?p ?x)) (bgp ( ?s ?p ?x1))))") ;
}
@Test public void equality09() {
// Can't optimize if filter does not cover vars in LHS
testOp("(filter (= ?x2 <x>) (leftjoin (bgp ( ?s1 ?p1 ?x1)) (bgp ( ?s2 ?p2 ?x2))))",
t_equality,
"(filter (= ?x2 <x>) (leftjoin (bgp ( ?s1 ?p1 ?x1)) (bgp ( ?s2 ?p2 ?x2))))") ;
}
@Test public void equality10() {
testOp("(filter (= ?x <x>) (leftjoin (bgp ( ?s ?p ?x)) (bgp ( ?s ?p ?x))))",
t_equality,
"(assign((?x <x>)) (leftjoin (bgp ( ?s ?p <x>)) (bgp ( ?s ?p <x>))))") ;
}
@Test public void equality11() {
testOp("(filter (= ?x <x>) (leftjoin (bgp ( ?s ?p ?x)) (bgp ( ?s ?p ?x1))))",
t_equality,
"(assign((?x <x>)) (leftjoin (bgp ( ?s ?p <x>)) (bgp ( ?s ?p ?x1))))") ;
}
@Test public void equality12() {
testOp("(filter (= ?x1 <x>) (leftjoin (bgp ( ?s ?p ?x)) (bgp ( ?s ?p ?x1))))",
t_equality,
"(filter (= ?x1 <x>) (leftjoin (bgp ( ?s ?p ?x)) (bgp ( ?s ?p ?x1))))") ;
}
@Test public void equality13() {
testOp("(filter (= ?x1 <x>) (join (bgp ( ?s ?p ?x1)) (bgp ( ?s ?p ?x1))))",
t_equality,
"(assign((?x1 <x>)) (join (bgp ( ?s ?p <x>)) (bgp ( ?s ?p <x>))))") ;
}
@Test public void equality14() {
testOp("(filter (= ?x1 <x>) (union (bgp ( ?s ?p ?x1)) (bgp ( ?s ?p ?x1))))",
t_equality,
"(assign((?x1 <x>)) (union (bgp ( ?s ?p <x>)) (bgp ( ?s ?p <x>))))") ;
}
@Test public void equality15() {
// assign-push-in optimization.
testOp("(filter (= ?x1 <x>) (leftjoin (leftjoin (table unit) (bgp ( ?s ?p ?x1)) ) (bgp ( ?s ?p ?x1)) ))",
t_equality,
"(filter (= ?x1 <x>)",
" (leftjoin",
" (leftjoin",
" (table unit)",
" (assign ((?x1 <x>)) (bgp (triple ?s ?p <x>)))",
" )",
" (assign ((?x1 <x>)) (bgp (triple ?s ?p <x>)))",
" ))" ) ;
}
// JENA-432 (simplified)
@Test public void equality16() {
/*
SELECT *
WHERE {
?test ?p1 ?o1.
FILTER ( ?test = <http://localhost/t2> )
OPTIONAL {
SELECT ?s1
{ ?s1 ?p2 ?o2 }
}
} */
String qs = StrUtils.strjoinNL
( "(filter (= ?test <http://localhost/t2>)"
, " (leftjoin"
, " (bgp (triple ?test ?p1 ?o1))"
, " (project (?s1)"
, " (bgp (triple ?s1 ?p2 ?o2)))))"
) ;
testOp(qs,
t_equality,
"(assign ((?test <http://localhost/t2>))" ,
" (leftjoin" ,
" (bgp (triple <http://localhost/t2> ?p1 ?o1))" ,
" (project (?s1)" ,
" (bgp (triple ?s1 ?p2 ?o2)))))"
) ;
}
@Test public void equality17() {
// Conflicting constraints should result in no optimization
testOp("(filter ((= ?x <http://constant1>) (= ?x <http://constant2>)) (join (bgp (?x <http://p1> ?o1)) (bgp (?x <http://p2> ?o2))))",
t_equality,
(String[])null);
}
// JENA -1202
@Test public void equality_expression_1() {
// Need to fold to a string or URI to trigger equality.
Op op = SSE.parseOp("(filter (= ?o (+ 'a' 'b')) (bgp (?x <http://p2> ?o)))") ;
// Fold constants.
Op op1 = Transformer.transform(new TransformCopy(), new ExprTransformConstantFold(), op);
// Then apply filter-equality.
check(op1, t_equality, "(assign ((?o 'ab')) (bgp (?x <http://p2> 'ab')) )") ;
}
@Test public void equality_path_1() {
testOp("(filter (= ?x <http://constant1/>) (path ?x (path+ :p) ?y))",
t_equality,
"(assign ((?x <http://constant1/>)) (path <http://constant1/> (path+ :p) ?y) )") ;
}
@Test public void equality_path_2() {
testOp("(filter (= ?y <http://constant1/>) (path ?x (path+ :p) ?y))",
t_equality,
"(assign ((?y <http://constant1/>)) (path ?x (path+ :p) <http://constant1/>) )") ;
}
@Test public void equality_path_3() {
testOp("(filter ((= ?x <http://constant1/>) (= ?y <http://constant2/>)) (path ?x (path+ :p) ?y))",
t_equality,
"(assign ((?x <http://constant1/>) (?y <http://constant2/>)) (path <http://constant1/> (path+ :p) <http://constant2/>) )") ;
}
@Test public void equality_path_4() {
testOp("(filter (= ?x <http://constant1/>) (join (bgp (?x :q ?z)) (path ?x (path+ :p) ?y) ))",
t_equality,
"(assign ((?x <http://constant1/>)) (join (bgp (<http://constant1/> :q ?z)) (path <http://constant1/> (path+ :p) ?y) ))") ;
}
}