com.bigdata.rdf.sparql.ast.ASTContainer Maven / Gradle / Ivy
/**
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 Sep 15, 2011
*/
package com.bigdata.rdf.sparql.ast;
import java.util.Map;
import org.openrdf.model.Value;
import com.bigdata.bop.BOp;
import com.bigdata.bop.BOpUtility;
import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.PipelineOp;
import com.bigdata.rdf.lexicon.BigdataValueCentricFullTextIndex;
import com.bigdata.rdf.sail.sparql.ast.SimpleNode;
import com.bigdata.rdf.sparql.ast.optimizers.IASTOptimizer;
/**
* A super container for the AST.
*
* @author Bryan Thompson
* @version $Id$
*/
public class ASTContainer extends ASTBase {
/**
*
*/
private static final long serialVersionUID = 1L;
public interface Annotations extends QueryBase.Annotations {
/**
* The original query from which this AST was generated.
*/
String QUERY_STRING = "queryString";
/**
* The parse tree generated from the query string (optional). For the
* default integration, this is the parse tree assembled by the Sesame
* sparql.jjt
grammar. Other integrations may produce
* different parse trees using different object models.
*
* Note: There is no guarantee that the parse tree is a serializable
* object. It may not need to be stripped off of the {@link QueryRoot}
* if the {@link QueryRoot} is persisted or shipped to another node in a
* cluster.
*/
String PARSE_TREE = "parseTree";
/**
* The AST as received from the parser. This is either a
* {@link QueryRoot} or an {@link UpdateRoot}.
*/
String ORIGINAL_AST = "originalAST";
/**
* The AST as rewritten by the {@link IASTOptimizer}s.
*/
String OPTIMIZED_AST = "optimizedAST";
/**
* The physical query plan (pipeline bops).
*/
String QUERY_PLAN = "queryPlan";
/**
* The incoming binding set associated with the query plan, as
* resulting from the query optimization phase.
*/
String OPTIMIZED_AST_BINDING_SETS = "optimizedASTBindingSets";
/**
* The parsing time for the query (nanoseconds).
*/
String QUERY_PARSE_TIME = "queryParseTime";
/**
* The time to batch resolve RDF {@link Value}s in the query to
* {@link BigdataValue}s in the database (nanoseconds).
*/
String RESOLVE_VALUES_TIME = "resolveValuesTime";
/**
* Flag which indicates completed resolution of IVs.
* Used to prevent running resolution again on consequent calls to query.evaluate
*/
String RESOLVED = "resolved";
}
/**
* Deep copy constructor.
*/
public ASTContainer(final ASTContainer op) {
super(op);
}
/**
* Shallow copy constructor.
*/
public ASTContainer(final BOp[] args, final Map annotations) {
super(args, annotations);
}
public ASTContainer(final QueryRoot queryRoot) {
super(BOp.NOARGS, null/*anns*/);
setOriginalAST(queryRoot);
}
public ASTContainer(final UpdateRoot updateRoot) {
super(BOp.NOARGS, null/*anns*/);
setOriginalUpdateAST(updateRoot);
}
/**
* Return the original SPARQL QUERY -or- UPDATE from which this AST model was
* generated.
*
* @return The original Query or Update -or- null
if the AST
* was not generated by the parser.
*/
public String getQueryString() {
return (String) getProperty(Annotations.QUERY_STRING);
}
/**
* Set the SPARQL QUERY -or- UPDATE string used to generate the AST model.
*
* @param queryString
* The query string.
*/
public void setQueryString(final String queryString) {
setProperty(Annotations.QUERY_STRING, queryString);
}
/**
* Return the parse tree generated from the query string.
*/
public Object getParseTree() {
return getProperty(Annotations.PARSE_TREE);
}
/**
* Set the parse tree generated from the query string.
*
* @param parseTree
* The parse tree (may be null
).
*/
public void setParseTree(final Object parseTree) {
setProperty(Annotations.PARSE_TREE, parseTree);
}
/**
* Return true
iff this {@link ASTContainer} models a SPARQL
* UPDATE operation.
*/
public boolean isUpdate() {
return getProperty(Annotations.ORIGINAL_AST) instanceof UpdateRoot;
}
/**
* Return true
iff this {@link ASTContainer} models a SPARQL
* QUERY operation.
*/
public boolean isQuery() {
return getProperty(Annotations.ORIGINAL_AST) instanceof QueryRoot;
}
/**
* Return the original AST model (before any optimization).
*/
public UpdateRoot getOriginalUpdateAST() {
return (UpdateRoot) getProperty(Annotations.ORIGINAL_AST);
}
/**
* Set the original AST model (before any optimizations).
*/
public void setOriginalUpdateAST(final UpdateRoot updateRoot) {
setProperty(Annotations.ORIGINAL_AST, updateRoot);
}
/**
* Return the original AST model (before any optimization).
*/
public QueryRoot getOriginalAST() {
return (QueryRoot) getProperty(Annotations.ORIGINAL_AST);
}
/**
* Set the incoming binding sets associated with the optimized AST.
*/
public void setOptimizedASTBindingSets(final IBindingSet[] bindingSets) {
setProperty(Annotations.OPTIMIZED_AST_BINDING_SETS, bindingSets);
}
/**
* Return the incoming binding sets associated with the optimized AST.
*/
public IBindingSet[] getOptimizedASTBindingSets() {
return (IBindingSet[]) getProperty(Annotations.OPTIMIZED_AST_BINDING_SETS);
}
/**
* Set the original AST model (before any optimizations).
*/
public void setOriginalAST(final QueryRoot queryRoot) {
setProperty(Annotations.ORIGINAL_AST, queryRoot);
}
/**
* Return the optimized AST model.
*/
public QueryRoot getOptimizedAST() {
return (QueryRoot) getProperty(Annotations.OPTIMIZED_AST);
}
/**
* Set the query parse time in nanoseconds.
*/
public void setQueryParseTime(final Long parseTime) {
setProperty(Annotations.QUERY_PARSE_TIME, parseTime);
}
/**
* Get the query parse time in nanoseconds.
*/
public Long getQueryParseTime() {
return (Long) getProperty(Annotations.QUERY_PARSE_TIME);
}
/**
* Set the RDF value resolution time in nanoseconds.
*/
public void setResolveValuesTime(final Long nanos) {
setProperty(Annotations.RESOLVE_VALUES_TIME, nanos);
}
/**
* Get the resolve values time in nanoseconds.
*/
public Long getResolveValuesTime() {
return (Long) getProperty(Annotations.RESOLVE_VALUES_TIME);
}
/**
* Set the optimized AST model.
*
* Note: You MUST deep copy the original AST to avoid destructive side
* effects when the {@link IASTOptimizer}s are run.
*/
public void setOptimizedAST(final QueryRoot queryRoot) {
setProperty(Annotations.OPTIMIZED_AST, queryRoot);
}
/**
* Clears the optimized AST model (necessary when something on which it
* depends has been changed in the original AST model, for example, if you
* replace the {@link DatasetNode}).
*/
public void clearOptimizedAST() {
clearProperty(Annotations.OPTIMIZED_AST);
}
/**
* Return the physical query plan (pipeline bops).
*/
public PipelineOp getQueryPlan() {
return (PipelineOp) getProperty(Annotations.QUERY_PLAN);
}
/**
* Set the physical plan for query or update (pipeline bops).
*/
public void setQueryPlan(final PipelineOp queryPlan) {
setProperty(Annotations.QUERY_PLAN, queryPlan);
}
public String toString() {
final StringBuilder sb = new StringBuilder();
final String queryString = getQueryString();
final Object parseTree = getParseTree();
/*
* Note: Resolve the original AST without regard to query versus update.
*/
final ASTBase originalAST = (ASTBase) getProperty(Annotations.ORIGINAL_AST);
/*
* Note: Resolve the optimized AST without regard to query versus
* update.
*/
final ASTBase optimizedAST = (ASTBase) getProperty(Annotations.OPTIMIZED_AST);
final PipelineOp queryPlan = getQueryPlan();
if (queryString != null) {
sb.append("\n");
sb.append(Annotations.QUERY_STRING);
sb.append("\n");
sb.append(queryString);
sb.append("\n");
}
if (parseTree != null) {
sb.append("\n");
sb.append(Annotations.PARSE_TREE);
sb.append("\n");
if(parseTree instanceof SimpleNode) {
// Dump parse tree for sparql.jjt grammar.
sb.append(((SimpleNode)parseTree).dump(""));
} else {
/*
* Dump some other parse tree, assuming it implements toString()
* as pretty print.
*/
sb.append(parseTree.toString());
sb.append("\n");
}
}
if (originalAST != null) {
sb.append("\n");
sb.append(Annotations.ORIGINAL_AST);
sb.append(originalAST);
}
if (optimizedAST != null) {
sb.append("\n");
sb.append(Annotations.OPTIMIZED_AST);
sb.append(optimizedAST);
}
if (queryPlan != null) {
sb.append("\n");
sb.append(Annotations.QUERY_PLAN);
sb.append("\n");
sb.append(BOpUtility.toString(queryPlan));
}
return sb.toString();
}
}