All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.rdf.sparql.ast.optimizers.TestASTFlattenUnionsOptimizer Maven / Gradle / Ivy

There is a newer version: 2.1.4
Show newest version
/**

Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
/*
 * Created on Aug 29, 2011
 */

package com.bigdata.rdf.sparql.ast.optimizers;

import org.openrdf.model.impl.URIImpl;
import org.openrdf.query.algebra.StatementPattern.Scope;

import com.bigdata.bop.IBindingSet;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.sparql.ast.AbstractASTEvaluationTestCase;
import com.bigdata.rdf.sparql.ast.ConstantNode;
import com.bigdata.rdf.sparql.ast.IQueryNode;
import com.bigdata.rdf.sparql.ast.JoinGroupNode;
import com.bigdata.rdf.sparql.ast.ProjectionNode;
import com.bigdata.rdf.sparql.ast.QueryNodeWithBindingSet;
import com.bigdata.rdf.sparql.ast.QueryRoot;
import com.bigdata.rdf.sparql.ast.QueryType;
import com.bigdata.rdf.sparql.ast.StatementPatternNode;
import com.bigdata.rdf.sparql.ast.UnionNode;
import com.bigdata.rdf.sparql.ast.VarNode;

/**
 * Test suite for {@link ASTFlattenUnionsOptimizer}.
 * 
 * @author Bryan Thompson
 * @version $Id$
 * 
 * FIXME Add counter examples.
 */
public class TestASTFlattenUnionsOptimizer extends AbstractASTEvaluationTestCase {

    /**
     * 
     */
    public TestASTFlattenUnionsOptimizer() {
    }

    /**
     * @param name
     */
    public TestASTFlattenUnionsOptimizer(String name) {
        super(name);
    }

    /**
     * Given
     * 
     * 
     * Select ?score
     *     {
     *       ?product bsbm:producer  .
     *       ?review bsbm:reviewFor ?product .
     *       { ?review bsbm:rating1 ?score . } UNION
     *       { ?review bsbm:rating2 ?score . } UNION
     *       { ?review bsbm:rating3 ?score . } UNION
     *       { ?review bsbm:rating4 ?score . }
     *     }
     * 
* * which turns into * *
     *       SELECT VarNode(score)
     *         JoinGroupNode {
     *           StatementPatternNode(VarNode(product), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/producer]), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/instances/dataFromProducer1/Producer1]), DEFAULT_CONTEXTS)
     *           StatementPatternNode(VarNode(review), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/reviewFor]), VarNode(product), DEFAULT_CONTEXTS)
     *           UnionNode { ### Find a UnionNode
     *             JoinGroupNode { ### The direct children are JoinGroupNodes
     *               StatementPatternNode(VarNode(review), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating1]), VarNode(score), DEFAULT_CONTEXTS)
     *             }
     *             JoinGroupNode { ### Having child JoinGroupNode
     *               UnionNode {   ### Where JoinGroupNode has child UnionNode
     *                 JoinGroupNode { ### Lift child JoinGroupNode into parent UnionNode
     *                   StatementPatternNode(VarNode(review), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating2]), VarNode(score), DEFAULT_CONTEXTS)
     *                 }
     *                 JoinGroupNode { ### Lift child JoinGroupNode into parent UnionNode
     *                   UnionNode {
     *                     JoinGroupNode {
     *                       StatementPatternNode(VarNode(review), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating3]), VarNode(score), DEFAULT_CONTEXTS)
     *                     }
     *                     JoinGroupNode {
     *                       StatementPatternNode(VarNode(review), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating4]), VarNode(score), DEFAULT_CONTEXTS)
     *                     }
     *                   }
     *                 }
     *               }
     *             }
     *           }
     *         }
     * 
* * Flatten the UNIONs such that we have: * *
     *       SELECT ?score
     *         JoinGroupNode {
     *           StatementPatternNode(VarNode(product), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/producer]), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/instances/dataFromProducer1/Producer1]), DEFAULT_CONTEXTS)
     *           StatementPatternNode(VarNode(review), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/reviewFor]), VarNode(product), DEFAULT_CONTEXTS)
     *           UnionNode {
     *             JoinGroupNode {
     *               StatementPatternNode(VarNode(review), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating1]), VarNode(score), DEFAULT_CONTEXTS)
     *             }
     *             JoinGroupNode {
     *               StatementPatternNode(VarNode(review), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating2]), VarNode(score), DEFAULT_CONTEXTS)
     *             }
     *             JoinGroupNode {
     *               StatementPatternNode(VarNode(review), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating3]), VarNode(score), DEFAULT_CONTEXTS)
     *             }
     *             JoinGroupNode {
     *               StatementPatternNode(VarNode(review), ConstantNode(TermId(0U)[http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating4]), VarNode(score), DEFAULT_CONTEXTS)
     *             }
     *           }
     *         }
     * 
*/ @SuppressWarnings("rawtypes") public void test_flattenUnions1() { /* * Note: DO NOT share structures in this test!!!! */ final IBindingSet[] bsets = new IBindingSet[]{}; /* * Set up constants. */ final IV producerIV = makeIV(new URIImpl( "http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/producer")); final IV producer1IV = makeIV(new URIImpl( "http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/instances/dataFromProducer1/Producer1")); final IV reviewForIV = makeIV(new URIImpl( "http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/reviewFor")); final IV rating1IV = makeIV(new URIImpl( "http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating1")); final IV rating2IV = makeIV(new URIImpl( "http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating2")); final IV rating3IV = makeIV(new URIImpl( "http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating3")); final IV rating4IV = makeIV(new URIImpl( "http://www4.wiwiss.fu-berlin.de/bizer/bsbm/v01/vocabulary/rating4")); // The source AST. final QueryRoot given = new QueryRoot(QueryType.SELECT); { final ProjectionNode projection = new ProjectionNode(); given.setProjection(projection); projection.addProjectionVar(new VarNode("score")); final JoinGroupNode whereClause = new JoinGroupNode(); given.setWhereClause(whereClause); whereClause.addChild(new StatementPatternNode( new VarNode("product"), new ConstantNode(producerIV), new ConstantNode(producer1IV), null/* c */, Scope.DEFAULT_CONTEXTS)); whereClause.addChild(new StatementPatternNode( new VarNode("review"), new ConstantNode(reviewForIV), new VarNode("product"), null/* c */, Scope.DEFAULT_CONTEXTS)); final UnionNode union1 = new UnionNode(); // outer final UnionNode union2 = new UnionNode(); // middle final UnionNode union3 = new UnionNode(); // inner whereClause.addChild(union1); final JoinGroupNode group1a = new JoinGroupNode(); final JoinGroupNode group1b = new JoinGroupNode(); union1.addChild(group1a); union1.addChild(group1b); group1a.addChild(new StatementPatternNode( new VarNode("review"), new ConstantNode(rating1IV), new VarNode("score"), null/* c */, Scope.DEFAULT_CONTEXTS)); group1b.addChild(union2); final JoinGroupNode group2a = new JoinGroupNode(); final JoinGroupNode group2b = new JoinGroupNode(); union2.addChild(group2a); union2.addChild(group2b); group2a.addChild(new StatementPatternNode( new VarNode("review"), new ConstantNode(rating2IV), new VarNode("score"), null/* c */, Scope.DEFAULT_CONTEXTS)); group2b.addChild(union3); final JoinGroupNode group3a = new JoinGroupNode(); final JoinGroupNode group3b = new JoinGroupNode(); union3.addChild(group3a); union3.addChild(group3b); group3a.addChild(new StatementPatternNode( new VarNode("review"), new ConstantNode(rating3IV), new VarNode("score"), null/* c */, Scope.DEFAULT_CONTEXTS)); group3b.addChild(new StatementPatternNode( new VarNode("review"), new ConstantNode(rating4IV), new VarNode("score"), null/* c */, Scope.DEFAULT_CONTEXTS)); } // The expected AST after the rewrite. final QueryRoot expected = new QueryRoot(QueryType.SELECT); { final ProjectionNode projection = new ProjectionNode(); expected.setProjection(projection); projection.addProjectionVar(new VarNode("score")); final JoinGroupNode whereClause = new JoinGroupNode(); expected.setWhereClause(whereClause); whereClause.addChild(new StatementPatternNode( new VarNode("product"), new ConstantNode(producerIV), new ConstantNode(producer1IV), null/* c */, Scope.DEFAULT_CONTEXTS)); whereClause.addChild(new StatementPatternNode( new VarNode("review"), new ConstantNode(reviewForIV), new VarNode("product"), null/* c */, Scope.DEFAULT_CONTEXTS)); final UnionNode union1 = new UnionNode(); // outer whereClause.addChild(union1); final JoinGroupNode group1a = new JoinGroupNode(); final JoinGroupNode group1b = new JoinGroupNode(); final JoinGroupNode group1c = new JoinGroupNode(); final JoinGroupNode group1d = new JoinGroupNode(); union1.addChild(group1a); union1.addChild(group1b); union1.addChild(group1c); union1.addChild(group1d); group1a.addChild(new StatementPatternNode( new VarNode("review"), new ConstantNode(rating1IV), new VarNode("score"), null/* c */, Scope.DEFAULT_CONTEXTS)); group1b.addChild(new StatementPatternNode( new VarNode("review"), new ConstantNode(rating2IV), new VarNode("score"), null/* c */, Scope.DEFAULT_CONTEXTS)); group1c.addChild(new StatementPatternNode( new VarNode("review"), new ConstantNode(rating3IV), new VarNode("score"), null/* c */, Scope.DEFAULT_CONTEXTS)); group1d.addChild(new StatementPatternNode( new VarNode("review"), new ConstantNode(rating4IV), new VarNode("score"), null/* c */, Scope.DEFAULT_CONTEXTS)); } final IASTOptimizer rewriter = new ASTFlattenUnionsOptimizer(); final IQueryNode actual = rewriter.optimize(null/* AST2BOpContext */, new QueryNodeWithBindingSet(given, bsets)).getQueryNode(); assertSameAST(expected, actual); } /** * A unit test which verifies a case where a child union can not be * flattened. * *
     *  SELECT ?s ?o {
     *     { ?s ?p1 ?o } UNION
     *     { ?x ?y ?x .
     *       { ?s ?p2 ?o } UNION
     *       { ?s ?p3 ?o }
     *     }
     *  }
     * 
* * which turns into: * *
     * 
     * SELECT ( VarNode(s) AS VarNode(s) ) ( VarNode(o) AS VarNode(o) )
     *   JoinGroupNode {
     *     UnionNode {
     *       JoinGroupNode {
     *         StatementPatternNode(VarNode(s), VarNode(p1), VarNode(o), DEFAULT_CONTEXTS)
     *       }
     *       JoinGroupNode {
     *         StatementPatternNode(VarNode(x), VarNode(y), VarNode(x), DEFAULT_CONTEXTS)
     *         UnionNode {
     *           JoinGroupNode {
     *             StatementPatternNode(VarNode(s), VarNode(p2), VarNode(o), DEFAULT_CONTEXTS)
     *           }
     *           JoinGroupNode {
     *             StatementPatternNode(VarNode(s), VarNode(p3), VarNode(o), DEFAULT_CONTEXTS)
     *           }
     *         }
     *       }
     *     }
     *   }
     * 
* * This case can not be flatten because the child UnionNode is not the sole * child of its parent group node. * * @throws Exception */ public void test_flattenUnions2() throws Exception { /* * Note: DO NOT share structures in this test!!!! */ final IBindingSet[] bsets = new IBindingSet[]{}; // The source AST. final QueryRoot given = new QueryRoot(QueryType.SELECT); { final ProjectionNode projection = new ProjectionNode(); given.setProjection(projection); projection.addProjectionVar(new VarNode("s")); projection.addProjectionVar(new VarNode("o")); final JoinGroupNode whereClause = new JoinGroupNode(); given.setWhereClause(whereClause); final UnionNode union1 = new UnionNode(); // outer final UnionNode union3 = new UnionNode(); // inner whereClause.addChild(union1); final JoinGroupNode group1a = new JoinGroupNode(); final JoinGroupNode group1b = new JoinGroupNode(); union1.addChild(group1a); union1.addChild(group1b); group1a.addChild(new StatementPatternNode(new VarNode("s"), new VarNode("p1"), new VarNode("o"), null/* c */, Scope.DEFAULT_CONTEXTS)); final JoinGroupNode group2 = new JoinGroupNode(); group1b.addChild(group2); group2.addChild(new StatementPatternNode(new VarNode("x"), new VarNode("y"), new VarNode("x"), null/* c */, Scope.DEFAULT_CONTEXTS)); group2.addChild(union3); final JoinGroupNode group3a = new JoinGroupNode(); final JoinGroupNode group3b = new JoinGroupNode(); union3.addChild(group3a); union3.addChild(group3b); group3a.addChild(new StatementPatternNode(new VarNode("s"), new VarNode("p2"), new VarNode("o"), null/* c */, Scope.DEFAULT_CONTEXTS)); group3b.addChild(new StatementPatternNode(new VarNode("s"), new VarNode("p3"), new VarNode("o"), null/* c */, Scope.DEFAULT_CONTEXTS)); } // The expected AST after the rewrite. final QueryRoot expected = new QueryRoot(QueryType.SELECT); { final ProjectionNode projection = new ProjectionNode(); expected.setProjection(projection); projection.addProjectionVar(new VarNode("s")); projection.addProjectionVar(new VarNode("o")); final JoinGroupNode whereClause = new JoinGroupNode(); expected.setWhereClause(whereClause); final UnionNode union1 = new UnionNode(); // outer final UnionNode union3 = new UnionNode(); // inner whereClause.addChild(union1); final JoinGroupNode group1a = new JoinGroupNode(); final JoinGroupNode group1b = new JoinGroupNode(); union1.addChild(group1a); union1.addChild(group1b); group1a.addChild(new StatementPatternNode(new VarNode("s"), new VarNode("p1"), new VarNode("o"), null/* c */, Scope.DEFAULT_CONTEXTS)); final JoinGroupNode group2 = new JoinGroupNode(); group1b.addChild(group2); group2.addChild(new StatementPatternNode(new VarNode("x"), new VarNode("y"), new VarNode("x"), null/* c */, Scope.DEFAULT_CONTEXTS)); group2.addChild(union3); final JoinGroupNode group3a = new JoinGroupNode(); final JoinGroupNode group3b = new JoinGroupNode(); union3.addChild(group3a); union3.addChild(group3b); group3a.addChild(new StatementPatternNode(new VarNode("s"), new VarNode("p2"), new VarNode("o"), null/* c */, Scope.DEFAULT_CONTEXTS)); group3b.addChild(new StatementPatternNode(new VarNode("s"), new VarNode("p3"), new VarNode("o"), null/* c */, Scope.DEFAULT_CONTEXTS)); } final IASTOptimizer rewriter = new ASTFlattenUnionsOptimizer(); final IQueryNode actual = rewriter.optimize(null/* AST2BOpContext */, new QueryNodeWithBindingSet(given, bsets)).getQueryNode(); assertSameAST(expected, actual); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy