/** Copyright (C) SYSTAP, LLC DBA Blazegraph 2011. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com 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 */ package com.bigdata.rdf.sail; import java.io.IOException; import java.util.List; import org.openrdf.model.vocabulary.XMLSchema; import org.openrdf.query.MalformedQueryException; import org.openrdf.query.QueryEvaluationException; import org.openrdf.repository.RepositoryException; import org.openrdf.rio.RDFParseException; import com.bigdata.bop.BOp; import com.bigdata.rdf.internal.IV; import com.bigdata.rdf.model.BigdataValue; import com.bigdata.rdf.model.BigdataValueFactory; import com.bigdata.rdf.sail.sparql.Bigdata2ASTSPARQLParser; import com.bigdata.rdf.sail.sparql.ast.*; import com.bigdata.rdf.sparql.ast.ASTContainer; import com.bigdata.rdf.sparql.ast.ConstantNode; import com.bigdata.rdf.sparql.ast.FilterNode; import com.bigdata.rdf.sparql.ast.GraphPatternGroup; import com.bigdata.rdf.sparql.ast.QueryRoot; import com.bigdata.rdf.sparql.ast.eval.ASTDeferredIVResolution; /** * Test suite for an issue where IV resolution of vocabulary terms * interferes with query parsing and deferred IV resolution ({@link ASTDeferredIVResolution}. * * @see <a href="https://jira.blazegraph.com/browse/BLZG-1747"> * Persistent "Unknown extension" issue in WIkidata Query Service</a> */ @SuppressWarnings({"rawtypes", "unchecked"}) public class TestTicket1747 extends QuadsTestCase { public TestTicket1747() { } public TestTicket1747(String arg0) { super(arg0); } public void testBug() throws Exception { // Setup a triple store using a vocabulary that declares xsd:dateTime (this should be in the default vocabulary). final BigdataSail sail = getSail(); try { executeQuery(new BigdataSailRepository(sail)); } finally { sail.__tearDownUnitTest(); } } private void executeQuery(final BigdataSailRepository repo) throws RepositoryException, MalformedQueryException, QueryEvaluationException, RDFParseException, IOException, VisitorException { try { repo.initialize(); final BigdataSailRepositoryConnection conn = repo.getConnection(); try { BigdataValueFactory vf = conn.getValueFactory(); // Verify that you can resolve xsd:dateTime to a non-mock IV. IV xsdDateTimeIV = conn.getTripleStore().getLexiconRelation().resolve(vf.createURI(XMLSchema.DATETIME.stringValue())).getIV(); assertFalse(xsdDateTimeIV.isNullIV()); assertTrue(xsdDateTimeIV.isVocabulary()); // Parse the first query on this ticket. String query = "PREFIX wdt: <http://www.wikidata.org/prop/direct/>\r\n" + "PREFIX wikibase: <http://wikiba.se/ontology#>\r\n" + "PREFIX p: <http://www.wikidata.org/prop/>\r\n" + "PREFIX v: <http://www.wikidata.org/prop/statement/>\r\n" + "PREFIX q: <http://www.wikidata.org/prop/qualifier/>\r\n" + "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\r\n" + "SELECT ?entity (year(?date) as ?year)\r\n" + "WHERE\r\n" + "{\r\n" + "?entityS wdt:P569 ?date .\r\n" + "SERVICE wikibase:label {\r\n" + "bd:serviceParam wikibase:language \"en\" .\r\n" + "?entityS rdfs:label ?entity\r\n" + "}\r\n" + "FILTER (datatype(?date) = xsd:dateTime)\r\n" + "FILTER (month(?date) = month(now()))\r\n" + "FILTER (day(?date) = day(now()))\r\n" + "}\r\n" + "LIMIT 10"; final ASTContainer astContainer = new Bigdata2ASTSPARQLParser().parseQuery2(query, null); // Verify that re-resolution of xsd:dateTime does not return a MockIV. xsdDateTimeIV = conn.getTripleStore().getLexiconRelation().resolve(XMLSchema.DATETIME).getIV(); assertFalse(xsdDateTimeIV.isNullIV()); assertTrue(xsdDateTimeIV.isVocabulary()); // Invoke deferred IV resolution on the parsed query. ASTDeferredIVResolution.resolveQuery(conn.getTripleStore(), astContainer); // astContainer instance is updated with resolved IVs at this point // Verify that re-resolution of xsd:dateTime does not return a MockIV. xsdDateTimeIV = conn.getTripleStore().getLexiconRelation().resolve(XMLSchema.DATETIME).getIV(); assertFalse(xsdDateTimeIV.isNullIV()); assertTrue(xsdDateTimeIV.isVocabulary()); // Verify that the parsed query does not contain a MockIV for xsd:dateTime QueryRoot queryRoot = astContainer.getOriginalAST(); GraphPatternGroup whereClause = queryRoot.getWhereClause(); List<FilterNode> filterNodes = whereClause.getChildren(FilterNode.class); for (FilterNode filterNode: filterNodes) { checkNode(filterNode); } } finally { conn.close(); } } finally { repo.shutDown(); } } private void checkNode(BOp bop) { if (bop instanceof ConstantNode) { BigdataValue value = ((ConstantNode)bop).getValue(); if (XMLSchema.DATETIME.equals(value)) { IV xsdDateTimeIV = value.getIV(); assertFalse(xsdDateTimeIV.isNullIV()); assertTrue(xsdDateTimeIV.isVocabulary()); } } else { for (BOp arg: bop.args()) { checkNode(arg); } } } }