From: <tho...@us...> - 2011-06-20 21:36:46
|
Revision: 4750 http://bigdata.svn.sourceforge.net/bigdata/?rev=4750&view=rev Author: thompsonbry Date: 2011-06-20 21:36:37 +0000 (Mon, 20 Jun 2011) Log Message: ----------- There is now only a single parser invocation per NanoSparqlServer request. In order to achieve this I had to bundle a modified version of the openrdf SPARQLParser, which is called "BigdataSPARQLParser". The modified version extracts the query hints and the query type (ASK, CONSTRUCT, DESCRIBE, or SELECT) and reports them out via an interface which is implemented by the returned ParsedQuery (IBigdataParsedQuery). The logic hacked into the BigdataSailRespositoryConnection (for query hints) and into QueryType (for SELECT, ASK, DESCRIBE or CONSTRUCT) has been removed. The NanoSparqlServer was also modified to report a BAD_REQUEST if there is an error in the SPARQL and to include the text of the syntax error message in the response line. I'm not sure whether we should register the BigdataSparqlParser over the SPARQLParser. The bigdata variant is used by the NanoSparqlServer and the BigdataSailResponsitoryConnection. It is pretty much a requirement for setting up a bigdata sail query, but there might not be any reason to explicitly override the existing SPARQL parser registration. See https://sourceforge.net/apps/trac/bigdata/ticket/336 Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataSailQuery.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataSailRepositoryConnection.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/QueryType.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/bench/NanoSparqlClient.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/BigdataRDFContext.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/webapp/QueryServlet.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestAll.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestQueryType.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/webapp/TestNanoSparqlServer.java Added Paths: ----------- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedBooleanQuery.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedGraphQuery.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedTupleQuery.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/IBigdataParsedQuery.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/BigdataSPARQLParser.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/BlankNodeVarProcessor.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/GraphPattern.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/TupleExprBuilder.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/WildcardProjectionProcessor.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/package.html branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestQueryHints.java Removed Paths: ------------- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/QueryHintsUtility.java branches/QUADS_QUERY_BRANCH/bigdata-sails/src/test/com/bigdata/rdf/sail/TestQueryHintsUtility.java Added: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedBooleanQuery.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedBooleanQuery.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedBooleanQuery.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -0,0 +1,72 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +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 Jun 20, 2011 + */ + +package com.bigdata.rdf.sail; + +import java.util.Properties; + +import org.openrdf.query.algebra.TupleExpr; +import org.openrdf.query.parser.ParsedBooleanQuery; + +/** + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class BigdataParsedBooleanQuery extends ParsedBooleanQuery implements + IBigdataParsedQuery { + + private final QueryType queryType; + private final Properties queryHints; + + /** + * @param tupleExpr + */ + public BigdataParsedBooleanQuery(final TupleExpr tupleExpr, + final QueryType queryType, final Properties queryHints) { + + super(tupleExpr); + + this.queryType = queryType; + + this.queryHints = queryHints; + + } + + public QueryType getQueryType() { + + return queryType; + + } + + public Properties getQueryHints() { + + return queryHints; + + } + +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedBooleanQuery.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Added: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedGraphQuery.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedGraphQuery.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedGraphQuery.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -0,0 +1,79 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +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 Jun 20, 2011 + */ + +package com.bigdata.rdf.sail; + +import java.util.Map; +import java.util.Properties; + +import org.openrdf.query.algebra.TupleExpr; +import org.openrdf.query.parser.ParsedGraphQuery; + +/** + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class BigdataParsedGraphQuery extends ParsedGraphQuery implements + IBigdataParsedQuery { + + private final QueryType queryType; + private final Properties queryHints; + + /** + * @param tupleExpr + * A tuple expression representing the query, formulated in Sail Query + * Model objects. + * @param namespaces + * A mapping of namespace prefixes to namespace names representing the + * namespaces that are used in the query. + */ + public BigdataParsedGraphQuery(final TupleExpr tupleExpr, + final Map<String, String> namespaces, final QueryType queryType, + final Properties queryHints) { + + super(tupleExpr, namespaces); + + this.queryType = queryType; + + this.queryHints = queryHints; + + } + + public QueryType getQueryType() { + + return queryType; + + } + + public Properties getQueryHints() { + + return queryHints; + + } + +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedGraphQuery.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Added: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedTupleQuery.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedTupleQuery.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedTupleQuery.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -0,0 +1,73 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +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 Jun 20, 2011 + */ + +package com.bigdata.rdf.sail; + +import java.util.Properties; + +import org.openrdf.query.algebra.TupleExpr; +import org.openrdf.query.parser.ParsedTupleQuery; + +/** + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class BigdataParsedTupleQuery extends ParsedTupleQuery implements + IBigdataParsedQuery { + + private final QueryType queryType; + private final Properties queryHints; + + /** + * @param tupleExpr + */ + public BigdataParsedTupleQuery(final TupleExpr tupleExpr, + final QueryType queryType, + final Properties queryHints) { + + super(tupleExpr); + + this.queryType = queryType; + + this.queryHints = queryHints; + + } + + public QueryType getQueryType() { + + return queryType; + + } + + public Properties getQueryHints() { + + return queryHints; + + } + +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataParsedTupleQuery.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Modified: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataSailQuery.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataSailQuery.java 2011-06-20 20:43:47 UTC (rev 4749) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataSailQuery.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -32,6 +32,8 @@ * Extension API for bigdata queries. * * @author <a href="mailto:mrp...@us...">Mike Personick</a> + * + * @see IBigdataParsedQuery */ public interface BigdataSailQuery { Modified: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataSailRepositoryConnection.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataSailRepositoryConnection.java 2011-06-20 20:43:47 UTC (rev 4749) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/BigdataSailRepositoryConnection.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -19,6 +19,7 @@ import com.bigdata.rdf.changesets.IChangeLog; import com.bigdata.rdf.changesets.IChangeRecord; import com.bigdata.rdf.sail.BigdataSail.BigdataSailConnection; +import com.bigdata.rdf.sail.sparql.BigdataSPARQLParser; import com.bigdata.rdf.store.AbstractTripleStore; /** @@ -72,18 +73,29 @@ final String qs, final String baseURI) throws MalformedQueryException { - final ParsedGraphQuery parsedQuery = QueryParserUtil.parseGraphQuery( - ql, qs, baseURI); + final SailQuery sailQuery = prepareQuery(ql, qs, baseURI); + + if(sailQuery.getParsedQuery() instanceof ParsedGraphQuery) { + + return (BigdataSailGraphQuery) sailQuery; + + } - final Properties queryHints = QueryHintsUtility.parseQueryHints(ql, qs, - baseURI); + // Wrong type of query. + throw new IllegalArgumentException(); + +// final ParsedGraphQuery parsedQuery = QueryParserUtil.parseGraphQuery( +// ql, qs, baseURI); +// +// final Properties queryHints = QueryHintsUtility.parseQueryHints(ql, qs, +// baseURI); +// +// final boolean describe = ql == QueryLanguage.SPARQL +// && QueryType.fromQuery(qs) == QueryType.DESCRIBE; +// +// return new BigdataSailGraphQuery(parsedQuery, this, queryHints, +// describe); - final boolean describe = ql == QueryLanguage.SPARQL - && QueryType.fromQuery(qs) == QueryType.DESCRIBE; - - return new BigdataSailGraphQuery(parsedQuery, this, queryHints, - describe); - } /** @@ -95,16 +107,27 @@ */ @Override public BigdataSailTupleQuery prepareTupleQuery(final QueryLanguage ql, - final String queryString, final String baseURI) + final String qs, final String baseURI) throws MalformedQueryException { - final ParsedTupleQuery parsedQuery = QueryParserUtil.parseTupleQuery( - ql, queryString, baseURI); + final SailQuery sailQuery = prepareQuery(ql, qs, baseURI); + + if(sailQuery.getParsedQuery() instanceof ParsedTupleQuery) { + + return (BigdataSailTupleQuery) sailQuery; + + } - final Properties queryHints = QueryHintsUtility.parseQueryHints(ql, - queryString, baseURI); + // Wrong type of query. + throw new IllegalArgumentException(); - return new BigdataSailTupleQuery(parsedQuery, this, queryHints); +// final ParsedTupleQuery parsedQuery = QueryParserUtil.parseTupleQuery( +// ql, queryString, baseURI); +// +// final Properties queryHints = QueryHintsUtility.parseQueryHints(ql, +// queryString, baseURI); +// +// return new BigdataSailTupleQuery(parsedQuery, this, queryHints); } @@ -117,36 +140,65 @@ */ @Override public BigdataSailBooleanQuery prepareBooleanQuery(final QueryLanguage ql, - final String queryString, final String baseURI) + final String qs, final String baseURI) throws MalformedQueryException { - final ParsedBooleanQuery parsedQuery = QueryParserUtil - .parseBooleanQuery(ql, queryString, baseURI); + final SailQuery sailQuery = prepareQuery(ql, qs, baseURI); + + if(sailQuery.getParsedQuery() instanceof ParsedBooleanQuery) { + + return (BigdataSailBooleanQuery) sailQuery; + + } - final Properties queryHints = QueryHintsUtility.parseQueryHints(ql, - queryString, baseURI); + // Wrong type of query. + throw new IllegalArgumentException(); - return new BigdataSailBooleanQuery(parsedQuery, this, queryHints); +// final ParsedBooleanQuery parsedQuery = QueryParserUtil +// .parseBooleanQuery(ql, queryString, baseURI); +// +// final Properties queryHints = QueryHintsUtility.parseQueryHints(ql, +// queryString, baseURI); +// +// return new BigdataSailBooleanQuery(parsedQuery, this, queryHints); } - /** - * {@inheritDoc} - * <p> - * Overridden to capture query hints from SPARQL queries. Query hints are - * embedded in query strings as namespaces. See {@link QueryHints#PREFIX} - * for more information. - */ + /** + * {@inheritDoc} + * <p> + * Overridden to capture query hints from SPARQL queries. Query hints are + * embedded in query strings as namespaces. See {@link QueryHints#PREFIX} + * for more information. + * <p> + * Note: In order to ensure that all code paths captures this information, + * all the other "prepare query" methods on this class delegate to this + * implementation. + */ @Override public SailQuery prepareQuery(final QueryLanguage ql, final String qs, final String baseURI) throws MalformedQueryException { - final ParsedQuery parsedQuery = QueryParserUtil.parseQuery(ql, qs, - baseURI); + final ParsedQuery parsedQuery; + final Properties queryHints; + final boolean describe; + if(QueryLanguage.SPARQL == ql) { + /* + * Make sure that we go through the overridden SPARQL parser. + */ + parsedQuery = new BigdataSPARQLParser().parseQuery(qs, baseURI); + queryHints = ((IBigdataParsedQuery) parsedQuery).getQueryHints(); + describe = QueryType.DESCRIBE == ((IBigdataParsedQuery) parsedQuery) + .getQueryType(); + } else { + /* + * Not a SPARQL query. + */ + parsedQuery = QueryParserUtil.parseQuery(ql, qs, baseURI); + queryHints = new Properties(); + describe = false; + } - final Properties queryHints = QueryHintsUtility.parseQueryHints(ql, qs, - baseURI); - if (parsedQuery instanceof ParsedTupleQuery) { return new BigdataSailTupleQuery((ParsedTupleQuery) parsedQuery, @@ -154,9 +206,6 @@ } else if (parsedQuery instanceof ParsedGraphQuery) { - final boolean describe = ql == QueryLanguage.SPARQL - && QueryType.fromQuery(qs) == QueryType.DESCRIBE; - return new BigdataSailGraphQuery((ParsedGraphQuery) parsedQuery, this, queryHints, describe); Added: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/IBigdataParsedQuery.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/IBigdataParsedQuery.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/IBigdataParsedQuery.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -0,0 +1,58 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +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 Jun 20, 2011 + */ + +package com.bigdata.rdf.sail; + +import java.util.Properties; + +/** + * Interface providing access to more state of the original SPARQL query AST. + * <p> + * Note: This interface is supported by various overrides of the openrdf SPARQL + * parser. Those overrides are required in order to gain access to the details + * of the AST. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + * + * @see BigdataSailQuery + */ +public interface IBigdataParsedQuery { + + /** + * The type of query. + */ + QueryType getQueryType(); + + /** + * Return query hints associated with this query. Query hints are embedded + * in query strings as namespaces. See {@link QueryHints#PREFIX} for more + * information. + */ + Properties getQueryHints(); + +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/IBigdataParsedQuery.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Deleted: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/QueryHintsUtility.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/QueryHintsUtility.java 2011-06-20 20:43:47 UTC (rev 4749) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/QueryHintsUtility.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -1,143 +0,0 @@ -/** - -Copyright (C) SYSTAP, LLC 2006-2011. All rights reserved. - -Contact: - SYSTAP, LLC - 4501 Tower Road - Greensboro, NC 27410 - lic...@bi... - -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 -*/ -/* -Portions of this code are: - -Copyright Aduna (http://www.aduna-software.com/) � 2001-2007 - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ -/* - * Created on Jun 20, 2011 - */ - -package com.bigdata.rdf.sail; - -import java.util.Map; -import java.util.Properties; -import java.util.StringTokenizer; - -import org.openrdf.query.MalformedQueryException; -import org.openrdf.query.QueryLanguage; -import org.openrdf.query.parser.sparql.ast.ASTQueryContainer; -import org.openrdf.query.parser.sparql.ast.ParseException; -import org.openrdf.query.parser.sparql.ast.SyntaxTreeBuilder; - -import com.bigdata.rdf.sail.sparql.BaseDeclProcessor; -import com.bigdata.rdf.sail.sparql.PrefixDeclProcessor; -import com.bigdata.rdf.sail.sparql.StringEscapesProcessor; - -/** - * A utility class for parsing {@link QueryHints}. - * - * @author <a href="mailto:mrp...@us...">Mike Personick</a> - * @version $Id$ - */ -public class QueryHintsUtility { - - /** - * Parse query hints from a query string. Query hints are embedded in the - * query string via special namespaces. - * <p> - * Note: The Sesame operator tree does not include the original query hints, - * which is why this method is not written against the operator tree. - * - * See {@link QueryHints#PREFIX} for more information. - */ - public static Properties parseQueryHints(final QueryLanguage ql, - final String queryString, final String baseURI) - throws MalformedQueryException { - try { - final Properties queryHints = new Properties(); - // currently only supporting SPARQL - if (ql == QueryLanguage.SPARQL) { - // the next four lines were taken directly from - // org.openrdf.query.parser.sparql.SPARQLParser.parseQuery(String queryStr, String baseURI) - final ASTQueryContainer qc = SyntaxTreeBuilder - .parseQuery(queryString); - StringEscapesProcessor.process(qc); - BaseDeclProcessor.process(qc, baseURI); - final Map<String, String> prefixes = PrefixDeclProcessor - .process(qc); - // iterate the namespaces - for (Map.Entry<String, String> prefix : prefixes.entrySet()) { - // if we see one that matches the magic namespace, try - // to parse it - if (prefix.getKey().equalsIgnoreCase(QueryHints.PREFIX)) { - String hints = prefix.getValue(); - // has to have a # and it can't be at the end - int i = hints.indexOf('#'); - if (i < 0 || i == hints.length() - 1) { - throw new MalformedQueryException( - "bad query hints: " + hints); - } - hints = hints.substring(i + 1); - // properties are separated by & - final StringTokenizer st = new StringTokenizer(hints, - "&"); - while (st.hasMoreTokens()) { - final String hint = st.nextToken(); - i = hint.indexOf('='); - if (i < 0 || i == hint.length() - 1) { - throw new MalformedQueryException( - "bad query hint: " + hint); - } - final String key = hint.substring(0, i); - final String val = hint.substring(i+1); - queryHints.put(key, val); - } - } - } - } - return queryHints; - } catch (ParseException e) { - throw new MalformedQueryException(e.getMessage(), e); - } - } - -} Modified: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/QueryType.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/QueryType.java 2011-06-20 20:43:47 UTC (rev 4749) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/QueryType.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -1,15 +1,5 @@ package com.bigdata.rdf.sail; -import org.openrdf.query.parser.sparql.ast.ASTAskQuery; -import org.openrdf.query.parser.sparql.ast.ASTConstructQuery; -import org.openrdf.query.parser.sparql.ast.ASTDescribeQuery; -import org.openrdf.query.parser.sparql.ast.ASTQuery; -import org.openrdf.query.parser.sparql.ast.ASTQueryContainer; -import org.openrdf.query.parser.sparql.ast.ASTSelectQuery; -import org.openrdf.query.parser.sparql.ast.ParseException; -import org.openrdf.query.parser.sparql.ast.SyntaxTreeBuilder; -import org.openrdf.query.parser.sparql.ast.TokenMgrError; - /** * Helper class to figure out the type of a query. */ @@ -21,32 +11,36 @@ } - /** - * Hack returns the query type based on the first occurrence of the - * keyword for any known query type in the query. - * - * @param queryStr - * The query. - * - * @return The query type. - */ - static public QueryType fromQuery(final String queryStr) { - - try { - final ASTQueryContainer queryContainer = SyntaxTreeBuilder - .parseQuery(queryStr); - final ASTQuery query = queryContainer.getQuery(); - if(query instanceof ASTSelectQuery) return QueryType.SELECT; - if(query instanceof ASTDescribeQuery) return QueryType.DESCRIBE; - if(query instanceof ASTConstructQuery) return QueryType.CONSTRUCT; - if(query instanceof ASTAskQuery) return QueryType.ASK; - throw new RuntimeException(queryContainer.toString()); - } catch (TokenMgrError ex) { - throw new RuntimeException(ex); - } catch (ParseException ex) { - throw new RuntimeException(ex); - } - - } +// /** +// * Hack returns the query type based on the first occurrence of the keyword +// * for any known query type in the query. +// * +// * @param queryStr +// * The query. +// * +// * @return The query type. +// * +// * @deprecated by {@link BigdataSPARQLParser#parseQuery(String, String)} +// * which makes this information available as metadata via the +// * {@link IBigdataParsedQuery} interface. +// */ +// static public QueryType fromQuery(final String queryStr) { +// +// try { +// final ASTQueryContainer queryContainer = SyntaxTreeBuilder +// .parseQuery(queryStr); +// final ASTQuery query = queryContainer.getQuery(); +// if(query instanceof ASTSelectQuery) return QueryType.SELECT; +// if(query instanceof ASTDescribeQuery) return QueryType.DESCRIBE; +// if(query instanceof ASTConstructQuery) return QueryType.CONSTRUCT; +// if(query instanceof ASTAskQuery) return QueryType.ASK; +// throw new RuntimeException(queryContainer.toString()); +// } catch (TokenMgrError ex) { +// throw new RuntimeException(ex); +// } catch (ParseException ex) { +// throw new RuntimeException(ex); +// } +// +// } } Modified: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/bench/NanoSparqlClient.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/bench/NanoSparqlClient.java 2011-06-20 20:43:47 UTC (rev 4749) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/bench/NanoSparqlClient.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -65,7 +65,9 @@ import com.bigdata.counters.CAT; import com.bigdata.jsr166.LinkedBlockingQueue; +import com.bigdata.rdf.sail.IBigdataParsedQuery; import com.bigdata.rdf.sail.QueryType; +import com.bigdata.rdf.sail.sparql.BigdataSPARQLParser; /** * A flyweight utility for issuing queries to an http SPARQL endpoint. @@ -270,12 +272,15 @@ conn.setUseCaches(opts.useCaches); conn.setReadTimeout(opts.timeout); - /* - * Set an appropriate Accept header for the query. - */ - final QueryType queryType = opts.queryType = QueryType - .fromQuery(opts.queryStr); + /* + * Set an appropriate Accept header for the query. + */ + final ParsedQuery parsedQuery = new BigdataSPARQLParser() + .parseQuery(opts.queryStr, opts.baseURI); + final QueryType queryType = opts.queryType = ((IBigdataParsedQuery) parsedQuery) + .getQueryType(); + switch(queryType) { case DESCRIBE: case CONSTRUCT: Added: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/BigdataSPARQLParser.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/BigdataSPARQLParser.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/BigdataSPARQLParser.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -0,0 +1,201 @@ +/* + * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007. + * + * Licensed under the Aduna BSD-style license. + */ +package com.bigdata.rdf.sail.sparql; + +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.openrdf.model.impl.ValueFactoryImpl; +import org.openrdf.query.Dataset; +import org.openrdf.query.MalformedQueryException; +import org.openrdf.query.algebra.TupleExpr; +import org.openrdf.query.parser.ParsedQuery; +import org.openrdf.query.parser.QueryParser; +import org.openrdf.query.parser.sparql.DatasetDeclProcessor; +import org.openrdf.query.parser.sparql.SPARQLParser; +import org.openrdf.query.parser.sparql.ast.ASTAskQuery; +import org.openrdf.query.parser.sparql.ast.ASTConstructQuery; +import org.openrdf.query.parser.sparql.ast.ASTDescribeQuery; +import org.openrdf.query.parser.sparql.ast.ASTQuery; +import org.openrdf.query.parser.sparql.ast.ASTQueryContainer; +import org.openrdf.query.parser.sparql.ast.ASTSelectQuery; +import org.openrdf.query.parser.sparql.ast.ParseException; +import org.openrdf.query.parser.sparql.ast.SyntaxTreeBuilder; +import org.openrdf.query.parser.sparql.ast.TokenMgrError; +import org.openrdf.query.parser.sparql.ast.VisitorException; + +import com.bigdata.rdf.sail.BigdataParsedBooleanQuery; +import com.bigdata.rdf.sail.BigdataParsedGraphQuery; +import com.bigdata.rdf.sail.BigdataParsedTupleQuery; +import com.bigdata.rdf.sail.IBigdataParsedQuery; +import com.bigdata.rdf.sail.QueryHints; +import com.bigdata.rdf.sail.QueryType; + +/** + * Overridden version of the openrdf 2.3 {@link SPARQLParser} class which + * extracts additional information required by the and associates it with the + * {@link ParsedQuery}. + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class BigdataSPARQLParser implements QueryParser { + + /** + * {@inheritDoc} + * + * @return An object which implements {@link IBigdataParsedQuery}. + * Additional information is available by casting the returned + * object to that interface. + */ + public ParsedQuery parseQuery(String queryStr, String baseURI) + throws MalformedQueryException + { + try { + ASTQueryContainer qc = SyntaxTreeBuilder.parseQuery(queryStr); + StringEscapesProcessor.process(qc); + BaseDeclProcessor.process(qc, baseURI); + Map<String, String> prefixes = PrefixDeclProcessor.process(qc); + WildcardProjectionProcessor.process(qc); + BlankNodeVarProcessor.process(qc); + TupleExpr tupleExpr = buildQueryModel(qc); + + ParsedQuery query; + + // Note: Bigdata override. + final Properties queryHints = getQueryHints(qc); + + // Note: Constructors in if then else are overridden too. + ASTQuery queryNode = qc.getQuery(); + if (queryNode instanceof ASTSelectQuery) { + query = new BigdataParsedTupleQuery(tupleExpr, + QueryType.SELECT, queryHints); + } + else if (queryNode instanceof ASTConstructQuery) { + query = new BigdataParsedGraphQuery(tupleExpr, prefixes, + QueryType.CONSTRUCT, queryHints); + } + else if (queryNode instanceof ASTAskQuery) { + query = new BigdataParsedBooleanQuery(tupleExpr, QueryType.ASK, + queryHints); + } + else if (queryNode instanceof ASTDescribeQuery) { + query = new BigdataParsedGraphQuery(tupleExpr, prefixes, + QueryType.DESCRIBE, queryHints); + } + else { + throw new RuntimeException("Unexpected query type: " + queryNode.getClass()); + } + + // Handle dataset declaration + Dataset dataset = DatasetDeclProcessor.process(qc); + if (dataset != null) { + query.setDataset(dataset); + } + + return query; + } + catch (ParseException e) { + throw new MalformedQueryException(e.getMessage(), e); + } + catch (TokenMgrError e) { + throw new MalformedQueryException(e.getMessage(), e); + } + } + + private TupleExpr buildQueryModel(ASTQueryContainer qc) + throws MalformedQueryException + { + TupleExprBuilder tupleExprBuilder = new TupleExprBuilder(new ValueFactoryImpl()); + try { + return (TupleExpr)qc.jjtAccept(tupleExprBuilder, null); + } + catch (VisitorException e) { + throw new MalformedQueryException(e.getMessage(), e); + } + } + + static private Properties getQueryHints(final ASTQueryContainer qc) + throws MalformedQueryException { +// try { + final Properties queryHints = new Properties(); +// // currently only supporting SPARQL +// if (ql == QueryLanguage.SPARQL) { +// // the next four lines were taken directly from +// // org.openrdf.query.parser.sparql.SPARQLParser.parseQuery(String queryStr, String baseURI) +// final ASTQueryContainer qc = SyntaxTreeBuilder +// .parseQuery(queryString); +// StringEscapesProcessor.process(qc); +// BaseDeclProcessor.process(qc, baseURI); + final Map<String, String> prefixes = PrefixDeclProcessor + .process(qc); + // iterate the namespaces + for (Map.Entry<String, String> prefix : prefixes.entrySet()) { + // if we see one that matches the magic namespace, try + // to parse it + if (prefix.getKey().equalsIgnoreCase(QueryHints.PREFIX)) { + String hints = prefix.getValue(); + // has to have a # and it can't be at the end + int i = hints.indexOf('#'); + if (i < 0 || i == hints.length() - 1) { + throw new MalformedQueryException( + "bad query hints: " + hints); + } + hints = hints.substring(i + 1); + // properties are separated by & + final StringTokenizer st = new StringTokenizer(hints, + "&"); + while (st.hasMoreTokens()) { + final String hint = st.nextToken(); + i = hint.indexOf('='); + if (i < 0 || i == hint.length() - 1) { + throw new MalformedQueryException( + "bad query hint: " + hint); + } + final String key = hint.substring(0, i); + final String val = hint.substring(i+1); + queryHints.put(key, val); + } + } + } +// } + return queryHints; +// } catch (ParseException e) { +// throw new MalformedQueryException(e.getMessage(), e); +// } + } + +// public static void main(String[] args) +// throws java.io.IOException +// { +// System.out.println("Your SPARQL query:"); +// +// BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); +// +// StringBuilder buf = new StringBuilder(); +// String line = null; +// while ((line = in.readLine()) != null) { +// if (line.length() > 0) { +// buf.append(' ').append(line).append('\n'); +// } +// else { +// String queryStr = buf.toString().trim(); +// if (queryStr.length() > 0) { +// try { +// SPARQLParser parser = new SPARQLParser(); +// parser.parseQuery(queryStr, null); +// } +// catch (Exception e) { +// System.err.println(e.getMessage()); +// e.printStackTrace(); +// } +// } +// buf.setLength(0); +// } +// } +// } +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/BigdataSPARQLParser.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Added: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/BlankNodeVarProcessor.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/BlankNodeVarProcessor.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/BlankNodeVarProcessor.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -0,0 +1,121 @@ +/* + * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006. + * + * Licensed under the Aduna BSD-style license. + */ +package com.bigdata.rdf.sail.sparql; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.openrdf.query.MalformedQueryException; +import org.openrdf.query.parser.sparql.ast.ASTBasicGraphPattern; +import org.openrdf.query.parser.sparql.ast.ASTBlankNode; +import org.openrdf.query.parser.sparql.ast.ASTBlankNodePropertyList; +import org.openrdf.query.parser.sparql.ast.ASTCollection; +import org.openrdf.query.parser.sparql.ast.ASTQueryContainer; +import org.openrdf.query.parser.sparql.ast.ASTVar; +import org.openrdf.query.parser.sparql.ast.SyntaxTreeBuilderTreeConstants; +import org.openrdf.query.parser.sparql.ast.VisitorException; + +/** + * Processes blank nodes in the query body, replacing them with variables while + * retaining scope. + * + * @author Arjohn Kampman + */ +public class BlankNodeVarProcessor extends ASTVisitorBase { + + public static void process(ASTQueryContainer qc) + throws MalformedQueryException + { + try { + qc.jjtAccept(new BlankNodeToVarConverter(), null); + } + catch (VisitorException e) { + throw new MalformedQueryException(e); + } + } + + /*-------------------------------------* + * Inner class BlankNodeToVarConverter * + *-------------------------------------*/ + + private static class BlankNodeToVarConverter extends ASTVisitorBase { + + private int anonVarNo = 1; + + private Map<String, String> conversionMap = new HashMap<String, String>(); + + private Set<String> usedBNodeIDs = new HashSet<String>(); + + private String createAnonVarName() { + return "-anon-" + anonVarNo++; + } + + @Override + public Object visit(ASTBasicGraphPattern node, Object data) + throws VisitorException + { + // The same Blank node ID cannot be used across Graph Patterns + usedBNodeIDs.addAll(conversionMap.keySet()); + + // Blank nodes are scope to Basic Graph Patterns + conversionMap.clear(); + + return super.visit(node, data); + } + + @Override + public Object visit(ASTBlankNode node, Object data) + throws VisitorException + { + String bnodeID = node.getID(); + String varName = findVarName(bnodeID); + + if (varName == null) { + varName = createAnonVarName(); + + if (bnodeID != null) { + conversionMap.put(bnodeID, varName); + } + } + + ASTVar varNode = new ASTVar(SyntaxTreeBuilderTreeConstants.JJTVAR); + varNode.setName(varName); + varNode.setAnonymous(true); + + node.jjtReplaceWith(varNode); + + return super.visit(node, data); + } + + private String findVarName(String bnodeID) throws VisitorException { + if (bnodeID == null) + return null; + String varName = conversionMap.get(bnodeID); + if (varName == null && usedBNodeIDs.contains(bnodeID)) + throw new VisitorException( + "BNodeID already used in another scope: " + bnodeID); + return varName; + } + + @Override + public Object visit(ASTBlankNodePropertyList node, Object data) + throws VisitorException + { + node.setVarName(createAnonVarName()); + return super.visit(node, data); + } + + @Override + public Object visit(ASTCollection node, Object data) + throws VisitorException + { + node.setVarName(createAnonVarName()); + return super.visit(node, data); + } + } +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/BlankNodeVarProcessor.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Added: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/GraphPattern.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/GraphPattern.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/GraphPattern.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -0,0 +1,163 @@ +/* + * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007. + * + * Licensed under the Aduna BSD-style license. + */ +package com.bigdata.rdf.sail.sparql; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.openrdf.query.algebra.Join; +import org.openrdf.query.algebra.LeftJoin; +import org.openrdf.query.algebra.Filter; +import org.openrdf.query.algebra.SingletonSet; +import org.openrdf.query.algebra.StatementPattern; +import org.openrdf.query.algebra.TupleExpr; +import org.openrdf.query.algebra.ValueExpr; +import org.openrdf.query.algebra.Var; + +/** + * A graph pattern consisting of (required and optional) tuple expressions and + * boolean constraints. + * + * @author Arjohn Kampman + */ +public class GraphPattern { + + /** + * The context of this graph pattern. + */ + private Var contextVar; + + /** + * The StatementPattern-scope of this graph pattern. + */ + private StatementPattern.Scope spScope = StatementPattern.Scope.DEFAULT_CONTEXTS; + + /** + * The required tuple expressions in this graph pattern. + */ + private List<TupleExpr> requiredTEs = new ArrayList<TupleExpr>(); + + /** + * The optional tuple expressions in this graph pattern. + */ + private List<TupleExpr> optionalTEs = new ArrayList<TupleExpr>(); + + /** + * The boolean constraints in this graph pattern. + */ + private List<ValueExpr> constraints = new ArrayList<ValueExpr>(); + + /** + * Creates a new graph pattern. + */ + public GraphPattern() { + } + + /** + * Creates a new graph pattern that inherits the context and scope from a + * parent graph pattern. + */ + public GraphPattern(GraphPattern parent) { + contextVar = parent.contextVar; + spScope = parent.spScope; + } + + public void setContextVar(Var contextVar) { + this.contextVar = contextVar; + } + + public Var getContextVar() { + return contextVar; + } + + public void setStatementPatternScope(StatementPattern.Scope spScope) { + this.spScope = spScope; + } + + public StatementPattern.Scope getStatementPatternScope() { + return spScope; + } + + public void addRequiredTE(TupleExpr te) { + requiredTEs.add(te); + } + + public void addRequiredSP(Var subjVar, Var predVar, Var objVar) { + addRequiredTE(new StatementPattern(spScope, subjVar, predVar, objVar, contextVar)); + } + + public List<TupleExpr> getRequiredTEs() { + return Collections.unmodifiableList(requiredTEs); + } + + public void addOptionalTE(TupleExpr te) { + optionalTEs.add(te); + } + + public List<TupleExpr> getOptionalTEs() { + return Collections.unmodifiableList(optionalTEs); + } + + public void addConstraint(ValueExpr constraint) { + constraints.add(constraint); + } + + public void addConstraints(Collection<ValueExpr> constraints) { + this.constraints.addAll(constraints); + } + + public List<ValueExpr> getConstraints() { + return Collections.unmodifiableList(constraints); + } + + public List<ValueExpr> removeAllConstraints() { + List<ValueExpr> constraints = this.constraints; + this.constraints = new ArrayList<ValueExpr>(); + return constraints; + } + + /** + * Removes all tuple expressions and constraints. + */ + public void clear() { + requiredTEs.clear(); + optionalTEs.clear(); + constraints.clear(); + } + + /** + * Builds a combined tuple expression from the tuple expressions and + * constraints in this graph pattern. + * + * @return A tuple expression for this graph pattern. + */ + public TupleExpr buildTupleExpr() { + TupleExpr result; + + if (requiredTEs.isEmpty()) { + result = new SingletonSet(); + } + else { + result = requiredTEs.get(0); + + for (int i = 1; i < requiredTEs.size(); i++) { + result = new Join(result, requiredTEs.get(i)); + } + } + + for (TupleExpr optTE : optionalTEs) { + result = new LeftJoin(result, optTE); + } + + for (ValueExpr constraint : constraints) { + result = new Filter(result, constraint); + } + + return result; + } +} Property changes on: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/GraphPattern.java ___________________________________________________________________ Added: svn:keywords + Id Date Revision Author HeadURL Added: branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/TupleExprBuilder.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/TupleExprBuilder.java (rev 0) +++ branches/QUADS_QUERY_BRANCH/bigdata-sails/src/java/com/bigdata/rdf/sail/sparql/TupleExprBuilder.java 2011-06-20 21:36:37 UTC (rev 4750) @@ -0,0 +1,924 @@ +/* + * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007. + * + * Licensed under the Aduna BSD-style license. + */ +package com.bigdata.rdf.sail.sparql; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.openrdf.model.Literal; +import org.openrdf.model.URI; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.model.vocabulary.RDF; +import org.openrdf.query.algebra.And; +import org.openrdf.query.algebra.BNodeGenerator; +import org.openrdf.query.algebra.Bound; +import org.openrdf.query.algebra.Compare; +import org.openrdf.query.algebra.Datatype; +import org.openrdf.query.algebra.Distinct; +import org.openrdf.query.algebra.EmptySet; +import org.openrdf.query.algebra.Extension; +import org.openrdf.query.algebra.ExtensionElem; +import org.openrdf.query.algebra.Filter; +import org.openrdf.query.algebra.FunctionCall; +import org.openrdf.query.algebra.IsBNode; +import org.openrdf.query.algebra.IsLiteral; +import org.openrdf.query.algebra.IsURI; +import org.openrdf.query.algebra.Join; +import org.openrdf.query.algebra.Lang; +import org.openrdf.query.algebra.LangMatches; +import org.openrdf.query.algebra.LeftJoin; +import org.openrdf.query.algebra.MathExpr; +import org.openrdf.query.algebra.MultiProjection; +import org.openrdf.query.algebra.Not; +import org.openrdf.query.algebra.Or; +import org.openrdf.query.algebra.Order; +import org.openrdf.query.algebra.OrderElem; +import org.openrdf.query.algebra.Projection; +import org.openrdf.query.algebra.ProjectionElem; +import org.openrdf.query.algebra.ProjectionElemList; +import org.openrdf.query.algebra.Reduced; +import org.openrdf.query.algebra.Regex; +import org.openrdf.query.algebra.SameTerm; +import org.openrdf.query.algebra.Slice; +import org.openrdf.query.algebra.StatementPattern; +import org.openrdf.query.algebra.Str; +import org.openrdf.query.algebra.TupleExpr; +import org.openrdf.query.algebra.Union; +import org.openrdf.query.algebra.ValueConstant; +import org.openrdf.query.algebra.ValueExpr; +import org.openrdf.query.algebra.Var; +import org.openrdf.query.algebra.StatementPattern.Scope; +import org.openrdf.query.algebra.helpers.StatementPatternCollector; +import org.openrdf.query.parser.sparql.ast.ASTAnd; +import org.openrdf.query.parser.sparql.ast.ASTAskQuery; +import org.openrdf.query.parser.sparql.ast.ASTBlankNode; +import org.openrdf.query.parser.sparql.ast.ASTBlankNodePropertyList; +import org.openrdf.query.parser.sparql.ast.ASTBound; +import org.openrdf.query.parser.sparql.ast.ASTCollection; +import org.openrdf.query.parser.sparql.ast.ASTCompare; +import org.openrdf.query.parser.sparql.ast.ASTConstraint; +import org.openrdf.query.parser.sparql.ast.ASTConstruct; +import org.openrdf.query.parser.sparql.ast.ASTConstructQuery; +import org.openrdf.query.parser.sparql.ast.ASTDatatype; +import org.openrdf.query.parser.sparql.ast.ASTDescribe; +import org.openrdf.query.parser.sparql.ast.ASTDescribeQuery; +import org.openrdf.query.parser.sparql.ast.ASTFalse; +import org.openrdf.query.parser.sparql.ast.ASTFunctionCall; +import org.openrdf.query.parser.sparql.ast.ASTGraphGraphPattern; +import org.openrdf.query.parser.sparql.ast.ASTGraphPatternGroup; +import org.openrdf.query.parser.sparql.ast.ASTIRI; +import org.openrdf.query.parser.sparql.ast.ASTIsBlank; +import org.openrdf.query.parser.sparql.ast.ASTIsIRI; +import org.openrdf.query.parser.sparql.ast.ASTIsLiteral; +import org.openrdf.query.parser.sparql.ast.ASTLang; +import org.openrdf.query.parser.sparql.ast.ASTLangMatches; +import org.openrdf.query.parser.sparql.ast.ASTLimit; +import org.openrdf.query.parser.sparql.ast.ASTMath; +import org.openrdf.query.parser.sparql.ast.ASTNot; +import org.openrdf.query.parser.sparql.ast.ASTNumericLiteral; +import org.openrdf.query.parser.sparql.ast.ASTObjectList; +import org.openrdf.query.parser.sparql.ast.ASTOffset; +import org.openrdf.query.parser.sparql.ast.ASTOptionalGraphPattern; +import org.openrdf.query.parser.sparql.ast.ASTOr; +import org.openrdf.query.parser.sparql.ast.ASTOrderClause; +import org.openrdf.query.parser.sparql.ast.ASTOrderCondition; +import org.openrdf.query.parser.sparql.ast.ASTPropertyList; +import org.openrdf.query.parser.sparql.ast.ASTQName; +import org.openrdf.query.parser.sparql.ast.ASTQueryContainer; +import org.openrdf.query.parser.sparql.ast.ASTRDFLiteral; +import org.openrdf.query.parser.sparql.ast.ASTRegexExpression; +import org.openrdf.query.parser.sparql.ast.ASTSameTerm; +import org.openrdf.query.parser.sparql.ast.ASTSelect; +import org.openrdf.query.parser.sparql.ast.ASTSelectQuery; +import org.openrdf.query.parser.sparql.ast.ASTStr; +import org.openrdf.query.parser.sparql.ast.ASTString; +import org.openrdf.query.parser.sparql.ast.ASTTrue; +import org.openrdf.query.parser.sparql.ast.ASTUnionGraphPattern; +import org.openrdf.query.parser.sparql.ast.ASTVar; +import org.openrdf.query.parser.sparql.ast.Node; +import org.openrdf.query.parser.sparql.ast.VisitorException; + +/** + * @author Arjohn Kampman + */ +public class TupleExprBuilder extends ASTVisitorBase { + + /*-----------* + * Variables * + *-----------*/ + + private ValueFactory valueFactory; + + private GraphPattern graphPattern; + + private int constantVarID = 1; + + /*--------------* + * Constructors * + *--------------*/ + + public TupleExprBuilder(ValueFactory valueFactory) { + this.valueFactory = valueFactory; + } + + /*---------* + * Methods * + *---------*/ + + private Var valueExpr2Var(ValueExpr valueExpr) { + if (valueExpr instanceof Var) { + return (Var)valueExpr; + } + else if (valueExpr instanceof ValueConstant) { + return createConstVar(((ValueConstant)valueExpr).getValue()); + } + else if (valueExpr == null) { + throw new IllegalArgumentException("valueExpr is null"); + } + else { + throw new IllegalArgumentException("valueExpr is a: " + valueExpr.getClass()); + } + } + + private Var createConstVar(Value value) { + Var var = createAnonVar("-const-" + constantVarID++); + var.setValue(value); + return var; + } + + private Var createAnonVar(String varName) { + Var var = new Var(varName); + var.setAnonymous(true); + return var; + } + + @Override + public TupleExpr visit(ASTQueryContainer node, Object data) + throws VisitorException + { + // Skip the prolog, any information it contains should already have been + // processed + return (TupleExpr)node.getQuery().jjtAccept(this, null); + } + + @Override + public TupleExpr visit(ASTSelectQuery node, Object data) + throws VisitorException + { + // Start with building the graph pattern + graphPattern = new GraphPattern(); + node.getWhereClause().jjtAccept(this, null); + TupleExpr tupleExpr = graphPattern.buildTupleExpr(); + + // Apply result ordering + ASTOrderClause orderNode = node.getOrderClause(); + if (orderNode != null) { + List<OrderElem> orderElemements = (List<OrderElem>)orderNode.jjtAccept(this, null); + tupleExpr = new Order(tupleExpr, orderElemements); + } + + // Apply projection + tupleExpr = (TupleExpr)node.getSelect().jjtAccept(this, tupleExpr); + + // Process limit and offset clauses + ASTLimit limitNode = node.getLimit(); + int limit = -1; + if (limitNode != null) { + limit = (Integer)limitNode.jjtAccept(this, null); + } + + ASTOffset offsetNode = node.getOffset(); + int offset = -1; + if (offsetNode != null) { + offset = (Integer)offsetNode.jjtAccept(this, null); + } + + if (offset >= 1 || limit >= 0) { + tupleExpr = new Slice(tupleExpr, offset, limit); + } + + return tupleExpr; + } + + @Override + public TupleExpr visit(ASTSelect node, Object data) + throws VisitorException + { + TupleExpr result = (TupleExpr)data; + + ProjectionElemList projElemList = new ProjectionElemList(); + + for (int i = 0; i < node.jjtGetNumChildren(); i++) { + Var projVar = (Var)node.jjtGetChild(i).jjtAccept(this, null); + projElemList.addElement(new ProjectionElem(projVar.getName())); + } + + result = new Projection(result, projElemList); + + if (node.isDistinct()) { + result = new Distinct(result); + } + else if (node.isReduced()) { + result = new Reduced(result); + } + + return result; + } + + @Override + public TupleExpr visit(ASTConstructQuery node, Object data) + throws VisitorException + { + // Start wit... [truncated message content] |