/**
* 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.sparql.algebra.Op ;
import org.apache.jena.sparql.algebra.TransformCopy ;
import org.apache.jena.sparql.algebra.Transformer ;
import org.apache.jena.sparql.algebra.optimize.ExprTransformConstantFold ;
import org.apache.jena.sparql.expr.ExprTransform ;
import org.apache.jena.sparql.sse.SSE ;
import org.junit.Assert;
import org.junit.Test;
/**
* Tests for the {@link ExprTransformConstantFold}
*/
public class TestTransformConstantFolding {
private ExprTransform transform = new ExprTransformConstantFold();
private void testNoTransform(String input, ExprTransform transform) {
test(input, null, transform);
}
private void test(String input, String expected, ExprTransform transform) {
Op opOrig = SSE.parseOp(input);
Op opExpected = SSE.parseOp(expected != null ? expected : input);
Op opOptimized = Transformer.transform(new TransformCopy(), transform, opOrig);
Assert.assertEquals(opExpected, opOptimized);
}
@Test
public void constant_fold_extend_01() {
test("(extend (?x (+ 1 2)) (table unit))", "(extend (?x 3) (table unit))", transform);
}
@Test
public void constant_fold_extend_02() {
test("(extend (?x (+ (+ 1 2) 3)) (table unit))", "(extend (?x 6) (table unit))", transform);
}
@Test
public void constant_fold_extend_03() {
test("(extend (?x (/ 1 2)) (table unit))", "(extend (?x 0.5) (table unit))", transform);
}
@Test
public void constant_fold_extend_04() {
// When an error occurs we don't fold
testNoTransform("(extend (?x (/ 1 0)) (table unit))", transform);
}
@Test
public void constant_fold_extend_05() {
test("(extend (?x (abs -1)) (table unit))", "(extend (?x 1) (table unit))", transform);
}
@Test
public void constant_fold_extend_06() {
test("(extend (?x (regex 'something' 'thing')) (table unit))", "(extend (?x true) (table unit))", transform);
}
@Test
public void constant_fold_extend_07() {
// Constant folding does not take advantage of any knowledge about the
// specific function being folded
// In this case the first expression to coalesce will always error and
// so could be removed entirely but isn't currently
testNoTransform("(extend (?x (coalesce (/ 1 0) 0)) (table unit))", transform);
}
@Test
public void constant_fold_extend_08() {
// Zero argument functions should not be treated as constants
testNoTransform("(extend (?x (rand)))", transform);
testNoTransform("(extend (?x (now)))", transform);
testNoTransform("(extend (?x (uuid)))", transform);
testNoTransform("(extend (?x (struuid)))", transform);
}
@Test
public void constant_fold_filter_01() {
test("(filter (exprlist (+ 1 2)) (table unit))", "(filter (exprlist 3) (table unit))", transform);
}
@Test
public void constant_fold_filter_02() {
test("(filter (exprlist (+ (+ 1 2) 3)) (table unit))", "(filter (exprlist 6) (table unit))", transform);
}
@Test
public void constant_fold_filter_03() {
test("(filter (exprlist (/ 1 2)) (table unit))", "(filter (exprlist 0.5) (table unit))", transform);
}
@Test
public void constant_fold_filter_04() {
// When an error occurs we don't fold
testNoTransform("(filter (exprlist (/ 1 0)) (table unit))", transform);
}
@Test
public void constant_fold_filter_05() {
test("(filter (exprlist (abs -1)) (table unit))", "(filter (exprlist 1) (table unit))", transform);
}
@Test
public void constant_fold_filter_06() {
test("(filter (regex 'something' 'thing') (table unit))", "(filter (exprlist true) (table unit))", transform);
}
@Test
public void constant_fold_filter_07() {
testNoTransform("(filter (exprlist (coalesce (/ 1 0) 0)) (table unit))", transform);
}
@Test
public void constant_fold_filter_08() {
test("(filter (exists (filter (exprlist (+ 1 2)) (table unit))) (table unit))", "(filter (exists (filter (exprlist 3) (table unit))) (table unit))", transform);
}
@Test
public void constant_fold_filter_09() {
test("(filter (exprlist (= ?x (+ 1 2))) (table unit))", "(filter (exprlist (= ?x 3)) (table unit))", transform);
}
@Test
public void constant_fold_filter_10() {
test("(filter (exprlist (+ 1 (* (+ 5 6 ) (+ 8 9)))) (table unit))", "(filter (exprlist 188) (table unit))", transform);
}
@Test
public void constant_fold_filter_11() {
test("(filter (exprlist (* ?y (+ (* ?x 4) (* ?z 6 )))) (table unit))", null, transform);
}
@Test
public void constant_fold_filter_12() {
// Zero argument functions should not be treated as constants
testNoTransform("(filter (exprlist (rand)) (table unit))", transform);
testNoTransform("(filter (exprlist (now)) (table unit))", transform);
testNoTransform("(filter (exprlist (uuid)) (table unit))", transform);
testNoTransform("(filter (exprlist (struuid)) (table unit))", transform);
}
@Test
public void constant_fold_group_01() {
test("(project (?count) (extend ((?count ?.0)) (group () ((?.0 (count (+ 1 2)))) (table unit))))", "(project (?count) (extend ((?count ?.0)) (group () ((?.0 (count 3))) (table unit))))", transform);
}
@Test
public void constant_fold_leftjoin_01() {
test("(leftjoin (table unit) (table unit) (+ 1 2))", "(leftjoin (table unit) (table unit) (exprlist 3))", transform);
}
}