| /* |
| * 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.rya.indexing.external; |
| |
| import java.net.UnknownHostException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.accumulo.core.client.AccumuloException; |
| import org.apache.accumulo.core.client.AccumuloSecurityException; |
| import org.apache.accumulo.core.client.Connector; |
| import org.apache.accumulo.core.client.TableExistsException; |
| import org.apache.accumulo.core.client.TableNotFoundException; |
| import org.apache.accumulo.core.client.mock.MockInstance; |
| import org.apache.accumulo.core.client.security.tokens.PasswordToken; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.rya.api.persist.RyaDAOException; |
| import org.apache.rya.indexing.external.PrecompJoinOptimizerIT.CountingResultHandler; |
| import org.apache.rya.indexing.external.PrecompJoinOptimizerTest.NodeCollector; |
| import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet; |
| import org.apache.rya.indexing.external.tupleSet.SimpleExternalTupleSet; |
| import org.apache.rya.indexing.pcj.matching.PCJOptimizer; |
| import org.apache.rya.indexing.pcj.matching.provider.AccumuloIndexSetProvider; |
| import org.apache.rya.indexing.pcj.storage.PcjException; |
| import org.apache.rya.indexing.pcj.storage.accumulo.PcjVarOrderFactory; |
| import org.apache.rya.rdftriplestore.inference.InferenceEngineException; |
| import org.junit.After; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.openrdf.model.URI; |
| import org.openrdf.model.impl.LiteralImpl; |
| import org.openrdf.model.impl.URIImpl; |
| import org.openrdf.model.vocabulary.RDF; |
| import org.openrdf.model.vocabulary.RDFS; |
| import org.openrdf.query.MalformedQueryException; |
| import org.openrdf.query.QueryEvaluationException; |
| import org.openrdf.query.QueryLanguage; |
| import org.openrdf.query.TupleQuery; |
| import org.openrdf.query.TupleQueryResultHandlerException; |
| import org.openrdf.query.algebra.Projection; |
| import org.openrdf.query.algebra.QueryModelNode; |
| import org.openrdf.query.algebra.TupleExpr; |
| import org.openrdf.query.parser.ParsedQuery; |
| import org.openrdf.query.parser.sparql.SPARQLParser; |
| import org.openrdf.repository.RepositoryException; |
| import org.openrdf.repository.sail.SailRepository; |
| import org.openrdf.repository.sail.SailRepositoryConnection; |
| import org.openrdf.sail.SailException; |
| |
| import com.google.common.base.Optional; |
| import com.google.common.collect.Lists; |
| |
| public class PCJOptionalTestIT { |
| |
| |
| private SailRepositoryConnection conn, pcjConn; |
| private SailRepository repo, pcjRepo; |
| private Connector accCon; |
| String tablePrefix = "table_"; |
| URI sub, sub2, obj, obj2, subclass, subclass2, talksTo, sub3, subclass3; |
| |
| @Before |
| public void init() throws RepositoryException, |
| TupleQueryResultHandlerException, QueryEvaluationException, |
| MalformedQueryException, AccumuloException, |
| AccumuloSecurityException, TableExistsException, RyaDAOException, |
| TableNotFoundException, InferenceEngineException, NumberFormatException, |
| UnknownHostException, SailException { |
| |
| repo = PcjIntegrationTestingUtil.getAccumuloNonPcjRepo(tablePrefix, "instance"); |
| conn = repo.getConnection(); |
| |
| pcjRepo = PcjIntegrationTestingUtil.getAccumuloPcjRepo(tablePrefix, "instance"); |
| pcjConn = pcjRepo.getConnection(); |
| |
| sub = new URIImpl("uri:entity"); |
| subclass = new URIImpl("uri:class"); |
| obj = new URIImpl("uri:obj"); |
| talksTo = new URIImpl("uri:talksTo"); |
| |
| conn.add(sub, RDF.TYPE, subclass); |
| conn.add(sub, RDFS.LABEL, new LiteralImpl("label")); |
| conn.add(sub, talksTo, obj); |
| |
| sub2 = new URIImpl("uri:entity2"); |
| subclass2 = new URIImpl("uri:class2"); |
| obj2 = new URIImpl("uri:obj2"); |
| sub3 = new URIImpl("uri:entity3"); |
| subclass3 = new URIImpl("uri:class3"); |
| |
| |
| conn.add(sub2, RDF.TYPE, subclass2); |
| conn.add(sub2, RDFS.LABEL, new LiteralImpl("label2")); |
| conn.add(sub2, talksTo, obj2); |
| conn.add(sub3, RDF.TYPE, subclass3); |
| conn.add(sub3, RDFS.LABEL, new LiteralImpl("label3")); |
| |
| |
| accCon = new MockInstance("instance").getConnector("root", |
| new PasswordToken("")); |
| |
| } |
| |
| @After |
| public void close() throws RepositoryException, AccumuloException, |
| AccumuloSecurityException, TableNotFoundException { |
| |
| PcjIntegrationTestingUtil.closeAndShutdown(conn, repo); |
| PcjIntegrationTestingUtil.closeAndShutdown(pcjConn, pcjRepo); |
| PcjIntegrationTestingUtil.deleteCoreRyaTables(accCon, tablePrefix); |
| PcjIntegrationTestingUtil.deleteIndexTables(accCon, 2, tablePrefix); |
| |
| } |
| |
| |
| @Test |
| public void testEvaluateSingeIndexExactMatch() |
| throws TupleQueryResultHandlerException, QueryEvaluationException, |
| MalformedQueryException, RepositoryException, AccumuloException, |
| AccumuloSecurityException, TableExistsException, RyaDAOException, |
| SailException, TableNotFoundException, PcjException, InferenceEngineException { |
| |
| final String indexSparqlString = ""// |
| + "SELECT ?e ?c ?l ?o" // |
| + "{" // |
| + " ?e a ?c . "// |
| + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l "// |
| + " OPTIONAL{?e <uri:talksTo> ?o } . "// |
| + "}";// |
| |
| PcjIntegrationTestingUtil.createAndPopulatePcj(conn, accCon, tablePrefix |
| + "INDEX_1", indexSparqlString, new String[] { "e", "c", "l", "o" }, |
| Optional.<PcjVarOrderFactory> absent()); |
| final String queryString = ""// |
| + "SELECT ?e ?c ?l ?o " // |
| + "{" // |
| + " ?e a ?c . "// |
| + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "// |
| + " OPTIONAL {?e <uri:talksTo> ?o } . "// |
| + "}";// |
| final CountingResultHandler crh = new CountingResultHandler(); |
| PcjIntegrationTestingUtil.deleteCoreRyaTables(accCon, tablePrefix); |
| PcjIntegrationTestingUtil.closeAndShutdown(conn, repo); |
| final TupleQuery tupQuery = pcjConn.prepareTupleQuery(QueryLanguage.SPARQL, queryString); |
| tupQuery.evaluate(crh); |
| |
| Assert.assertEquals(3, crh.getCount()); |
| |
| } |
| |
| |
| |
| @Test |
| public void testEvaluateSingeIndex() |
| throws TupleQueryResultHandlerException, QueryEvaluationException, |
| MalformedQueryException, RepositoryException, AccumuloException, |
| AccumuloSecurityException, TableExistsException, RyaDAOException, |
| SailException, TableNotFoundException, PcjException, InferenceEngineException, |
| NumberFormatException, UnknownHostException { |
| |
| final String indexSparqlString = ""// |
| + "SELECT ?e ?l ?o" // |
| + "{" // |
| + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l "// |
| + " OPTIONAL{?e <uri:talksTo> ?o } . "// |
| + "}";// |
| |
| PcjIntegrationTestingUtil.createAndPopulatePcj(conn, accCon, tablePrefix |
| + "INDEX_1", indexSparqlString, new String[] { "e", "l", "o" }, |
| Optional.<PcjVarOrderFactory> absent()); |
| final String queryString = ""// |
| + "SELECT ?e ?c ?l ?o " // |
| + "{" // |
| + " ?e <http://www.w3.org/2000/01/rdf-schema#label> ?l . "// |
| + " OPTIONAL {?e <uri:talksTo> ?o } . "// |
| + " ?e a ?c . "// |
| + "}";// |
| |
| final CountingResultHandler crh = new CountingResultHandler(); |
| PcjIntegrationTestingUtil.deleteCoreRyaTables(accCon, tablePrefix); |
| PcjIntegrationTestingUtil.closeAndShutdown(conn, repo); |
| |
| repo = PcjIntegrationTestingUtil.getAccumuloPcjRepo(tablePrefix, "instance"); |
| conn = repo.getConnection(); |
| conn.add(sub, RDF.TYPE, subclass); |
| conn.add(sub2, RDF.TYPE, subclass2); |
| conn.add(sub3, RDF.TYPE, subclass3); |
| |
| |
| final TupleQuery tupQuery = pcjConn.prepareTupleQuery(QueryLanguage.SPARQL, queryString); |
| tupQuery.evaluate(crh); |
| |
| Assert.assertEquals(3, crh.getCount()); |
| |
| } |
| |
| |
| |
| |
| |
| |
| @Test |
| public void testSimpleOptionalTest1() throws Exception { |
| |
| final String query = ""// |
| + "SELECT ?u ?s ?t " // |
| + "{" // |
| + " ?s a ?t ."// |
| + " OPTIONAL{?t <http://www.w3.org/2000/01/rdf-schema#label> ?u } ."// |
| + " ?u <uri:talksTo> ?s . "// |
| + "}";// |
| |
| final SPARQLParser parser = new SPARQLParser(); |
| |
| final ParsedQuery pq1 = parser.parseQuery(query, null); |
| |
| final SimpleExternalTupleSet extTup1 = new SimpleExternalTupleSet( |
| (Projection) pq1.getTupleExpr().clone()); |
| |
| final List<ExternalTupleSet> list = new ArrayList<ExternalTupleSet>(); |
| |
| list.add(extTup1); |
| |
| final List<QueryModelNode> optTupNodes = Lists.newArrayList(); |
| optTupNodes.add(extTup1); |
| |
| final PCJOptimizer pcj = new PCJOptimizer(list, true, new AccumuloIndexSetProvider(new Configuration(), list)); |
| final TupleExpr te = pq1.getTupleExpr(); |
| pcj.optimize(te, null, null); |
| |
| final NodeCollector nc = new NodeCollector(); |
| te.visit(nc); |
| |
| final List<QueryModelNode> qNodes = nc.getNodes(); |
| |
| Assert.assertEquals(qNodes.size(), optTupNodes.size()); |
| for (final QueryModelNode node : qNodes) { |
| Assert.assertTrue(optTupNodes.contains(node)); |
| } |
| |
| } |
| |
| |
| @Test |
| public void testSimpleOptionalTest2() throws Exception { |
| |
| final String query = ""// |
| + "SELECT ?u ?s ?t " // |
| + "{" // |
| + " ?s a ?t ."// |
| + " OPTIONAL{?t <http://www.w3.org/2000/01/rdf-schema#label> ?u } ."// |
| + " ?u <uri:talksTo> ?s . "// |
| + " ?s a ?u ."// |
| + "}";// |
| |
| |
| final String pcj = ""// |
| + "SELECT ?d ?b ?c " // |
| + "{" // |
| + " ?b a ?c ."// |
| + " OPTIONAL{?c <http://www.w3.org/2000/01/rdf-schema#label> ?d } ."// |
| + " ?d <uri:talksTo> ?b . "// |
| + "}";// |
| |
| |
| final String relabel_pcj = ""// |
| + "SELECT ?u ?s ?t " // |
| + "{" // |
| + " ?s a ?t ."// |
| + " OPTIONAL{?t <http://www.w3.org/2000/01/rdf-schema#label> ?u } ."// |
| + " ?u <uri:talksTo> ?s . "// |
| + "}";// |
| |
| |
| final SPARQLParser parser = new SPARQLParser(); |
| |
| final ParsedQuery pq1 = parser.parseQuery(query, null); |
| final ParsedQuery pq2 = parser.parseQuery(pcj, null); |
| final ParsedQuery pq3 = parser.parseQuery(relabel_pcj, null); |
| |
| final SimpleExternalTupleSet extTup1 = new SimpleExternalTupleSet( |
| (Projection) pq2.getTupleExpr()); |
| final SimpleExternalTupleSet extTup2 = new SimpleExternalTupleSet( |
| (Projection) pq3.getTupleExpr()); |
| |
| final List<ExternalTupleSet> list = new ArrayList<ExternalTupleSet>(); |
| |
| list.add(extTup1); |
| |
| final List<QueryModelNode> optTupNodes = Lists.newArrayList(); |
| optTupNodes.add(extTup2); |
| |
| final PCJOptimizer opt = new PCJOptimizer(list, true, new AccumuloIndexSetProvider(new Configuration(), list)); |
| final TupleExpr te = pq1.getTupleExpr(); |
| opt.optimize(te, null, null); |
| |
| final NodeCollector nc = new NodeCollector(); |
| te.visit(nc); |
| |
| final List<QueryModelNode> qNodes = nc.getNodes(); |
| |
| Assert.assertEquals(qNodes.size(), optTupNodes.size() + 1); |
| for (final QueryModelNode node : optTupNodes) { |
| Assert.assertTrue(qNodes.contains(node)); |
| } |
| |
| } |
| } |