/* * 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.query.ARQ ; import org.apache.jena.sparql.algebra.Transform ; import org.apache.jena.sparql.algebra.optimize.TransformDistinctToReduced ; import org.apache.jena.sparql.algebra.optimize.TransformOrderByDistinctApplication ; import org.junit.Test ; public class TestOptDistinctReduced extends AbstractTestTransform { Transform tDistinctToReduced = new TransformDistinctToReduced() ; Transform tOrderByDistinctApplication = new TransformOrderByDistinctApplication() ; @Test public void distinct_to_reduced_01() { // Not safe to transform because ORDER BY does not cover * which is ?s ?p ?o String queryString = "SELECT DISTINCT * { ?s ?p ?o } ORDER BY ?p ?o" ; String opExpectedString = "(distinct\n" + " (order (?p ?o)\n" + " (bgp (triple ?s ?p ?o))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_02() { // Safe to transform because ORDER BY does cover * which is ?s ?p String queryString = "SELECT DISTINCT * { ?s ?p 123 } ORDER BY ?s ?p" ; String opExpectedString = "(reduced\n" + " (order (?s ?p)\n" + " (bgp (triple ?s ?p 123))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_03() { String queryString = "SELECT DISTINCT * { ?s ?p ?o } ORDER BY ?s ?p ?o" ; String opExpectedString = "(reduced\n" + " (order (?s ?p ?o)\n" + " (bgp (triple ?s ?p ?o))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_04() { // This is safe to transform since all project variables // appear in the ORDER BY. // Ordering of variables in the ORDER BY is irrelevant as long as they appear // before any non-projected variables String queryString = "SELECT DISTINCT ?p { ?s ?p ?o } ORDER BY ?p ?o" ; String opExpectedString = "(reduced\n" + " (project (?p)\n" + " (order (?p ?o)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_05() { // Unsafe : ORDER BY has ?o before ?p String queryString = "SELECT DISTINCT ?p { ?s ?p ?o } ORDER BY ?o ?p" ; String opExpectedString = "(distinct\n" + " (project (?p)\n" + " (order (?o ?p)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_06() { // Per JENA-587 this is safe to transform since all project variables // appear in the ORDER BY // Ordering of variables in the ORDER BY is irrelevant as long as they appear // before any non-projected variables assertTrue(ARQ.isTrueOrUndef(ARQ.optDistinctToReduced)) ; String queryString = "SELECT DISTINCT ?p ?o { ?s ?p ?o } ORDER BY ?p ?o" ; String opExpectedString = "(reduced\n" + " (project (?p ?o)\n" + " (order (?p ?o)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_07() { // Per JENA-587 this is safe to transform since all project variables // appear in the ORDER BY // Ordering of variables in the ORDER BY is irrelevant as long as they appear // before any non-projected variables String queryString = "SELECT DISTINCT ?p ?o { ?s ?p ?o } ORDER BY ?o ?p" ; String opExpectedString = "(reduced\n" + " (project (?p ?o)\n" + " (order (?o ?p)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_08() { // Per JENA-587 this is safe to transform since all project variables // appear in the ORDER BY // Ordering of variables in the ORDER BY is irrelevant as long as they appear // before any non-projected variables assertTrue(ARQ.isTrueOrUndef(ARQ.optDistinctToReduced)) ; String queryString = "SELECT DISTINCT ?p ?o { ?s ?p ?o } ORDER BY ?o ?p ?s" ; String opExpectedString = "(reduced\n" + " (project (?p ?o)\n" + " (order (?o ?p ?s)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_09() { // Per JENA-587 this is safe to transform since all project variables // appear in the ORDER BY // Ordering of variables in the ORDER BY is irrelevant as long as they appear // before any non-projected variables assertTrue(ARQ.isTrueOrUndef(ARQ.optDistinctToReduced)) ; String queryString = "SELECT DISTINCT ?p ?o { ?s ?p ?o } ORDER BY ?p ?o ?s" ; String opExpectedString = "(reduced\n" + " (project (?p ?o)\n" + " (order (?p ?o ?s)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_10() { // Per JENA-587 this is unsafe to transform since a non-project variable // appears before all the projected variables are seen in the ORDER BY assertTrue(ARQ.isTrueOrUndef(ARQ.optDistinctToReduced)) ; String queryString = "SELECT DISTINCT ?p ?o { ?s ?p ?o } ORDER BY ?s ?p ?o" ; String opExpectedString = "(distinct\n" + " (project (?p ?o)\n" + " (order (?s ?p ?o)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_11() { // Per JENA-587 this is unsafe to transform since a non-project variable // appears before all the projected variables are seen in the ORDER BY assertTrue(ARQ.isTrueOrUndef(ARQ.optDistinctToReduced)) ; String queryString = "SELECT DISTINCT ?p ?o { ?s ?p ?o } ORDER BY ?p ?s ?o" ; String opExpectedString = "(distinct\n" + " (project (?p ?o)\n" + " (order (?p ?s ?o)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_12() { // Per JENA-587 this is unsafe to transform since a non-project variable // appears before all the projected variables are seen in the ORDER BY assertTrue(ARQ.isTrueOrUndef(ARQ.optDistinctToReduced)) ; String queryString = "SELECT DISTINCT ?p ?o { ?s ?p ?o } ORDER BY ?s" ; String opExpectedString = "(distinct\n" + " (project (?p ?o)\n" + " (order (?s)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_to_reduced_13() { // Per JENA-587 this is unsafe to transform since there is no ORDER BY assertTrue(ARQ.isTrueOrUndef(ARQ.optDistinctToReduced)) ; String queryString = "SELECT DISTINCT ?p ?o { ?s ?p ?o } " ; String opExpectedString = "(distinct\n" + " (project (?p ?o)\n" + " (bgp (triple ?s ?p ?o))))" ; testQuery(queryString, tDistinctToReduced, opExpectedString) ; } @Test public void distinct_order_by_application_01() { assertTrue(ARQ.isTrueOrUndef(ARQ.optOrderByDistinctApplication)) ; String queryString = "SELECT DISTINCT ?p { ?s ?p ?o } ORDER BY ?p"; String opExpectedString = "(order (?p)\n" + " (distinct\n" + " (project (?p)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tOrderByDistinctApplication, opExpectedString) ; } @Test public void distinct_order_by_application_03() { // Evaluation reordering optimization doesn't apply if it's a SELECT * // Also per JENA-587 DISTINCT -> REDUCED transformation cannot apply either assertTrue(ARQ.isTrueOrUndef(ARQ.optOrderByDistinctApplication)) ; String queryString = "SELECT DISTINCT * { ?s ?p ?o } ORDER BY ?p"; String opExpectedString = " (distinct\n" + " (order (?p)\n" + " (bgp (triple ?s ?p ?o))))" ; testQuery(queryString, tOrderByDistinctApplication, opExpectedString) ; } @Test public void distinct_order_by_application_04() { // The optimization still applies when order conditions are not simple variables // provided every variable used in an expression appears in the project list String queryString = "SELECT DISTINCT ?p { ?s ?p ?o } ORDER BY LCASE(STR(?p))"; String opExpectedString = "(order ((lcase (str (?p))))\n" + " (distinct\n" + " (project (?p)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tOrderByDistinctApplication, opExpectedString) ; } @Test public void distinct_order_by_application_05() { // The optimization still applies when order conditions are not simple variables // provided every variable used in an expression appears in the project list String queryString = "SELECT DISTINCT ?s ?p { ?s ?p ?o } ORDER BY LCASE(CONCAT(?s, ?p))"; String opExpectedString = "(order ((lcase (concat ?s ?p)))\n" + " (distinct\n" + " (project (?s ?p)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tOrderByDistinctApplication, opExpectedString) ; } @Test public void distinct_order_by_application_06() { // The optimization can apply when order conditions are not simple variables // provided every variable used in an expression appears in the project list // In this case it should not apply because the condition used a variable that // does not appear in the project list // Per JENA-587 the DISTINCT to REDUCED optimization also does not apply assertTrue(ARQ.isTrueOrUndef(ARQ.optOrderByDistinctApplication)) ; String queryString = "SELECT DISTINCT ?p { ?s ?p ?o } ORDER BY LCASE(CONCAT(?s, ?p))"; String opExpectedString = " (distinct\n" + " (project (?p)\n" + " (order ((lcase (concat ?s ?p)))\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tOrderByDistinctApplication, opExpectedString) ; } @Test public void reduced_order_by_application_01() { assertTrue(ARQ.isTrueOrUndef(ARQ.optOrderByDistinctApplication)) ; String queryString = "SELECT REDUCED ?p { ?s ?p ?o } ORDER BY ?p"; String opExpectedString = "(order (?p)\n" + " (reduced\n" + " (project (?p)\n" + " (bgp (triple ?s ?p ?o)))))" ; testQuery(queryString, tOrderByDistinctApplication, opExpectedString) ; } @Test public void reduced_order_by_application_02() { try { ARQ.setFalse(ARQ.optOrderByDistinctApplication) ; assertTrue(ARQ.isFalse(ARQ.optOrderByDistinctApplication)) ; String queryString = "SELECT REDUCED ?p { ?s ?p ?o } ORDER BY ?p" ; String opExpectedString = "(reduced\n" + " (project (?p)\n" + " (order (?p)\n" + " (bgp (triple ?s ?p ?o)))))" ; testOptimize(queryString, opExpectedString) ; } finally { ARQ.unset(ARQ.optOrderByDistinctApplication) ; } } }