com.bigdata.rdf.sparql.ast.SubqueryRoot 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
*/
package com.bigdata.rdf.sparql.ast;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.bigdata.bop.BOp;
import com.bigdata.bop.IVariable;
import com.bigdata.rdf.sparql.ast.optimizers.ASTSparql11SubqueryOptimizer;
/**
* A SPARQL 1.1 style subquery.
*/
public class SubqueryRoot extends SubqueryBase implements IJoinNode {
public interface Annotations extends //SubqueryBase.Annotations,
IJoinNode.Annotations {
/**
* Annotation provides a query hint indicating whether or not the
* subquery should be transformed into a named subquery, lifting its
* evaluation out of the main body of the query and replacing the
* subquery with an INCLUDE. When true
, the subquery will
* be lifted out. When false
, the subquery will not be
* lifted unless other semantics require that it be lifted out
* regardless.
*
* @see ASTSparql11SubqueryOptimizer
*/
String RUN_ONCE = "runOnce";
boolean DEFAULT_RUN_ONCE = false;
/**
* Annotation used to communicate the name of the anonymous variable
* supporting a NOT (EXISTS) graph pattern evaluation.
*/
String ASK_VAR = "askVar";
/**
* Used to specify the query plan for FILTER (NOT) EXISTS. There are two
* basic plans: vectored sub-plan and subquery with LIMIT ONE. Each plan
* has its advantages.
*
* Note: This annotation is propagated to the {@link SubqueryRoot} when
* the FILTER (NOT) EXISTS for a {@link SubqueryFunctionNodeBase} is
* turned into an ASK subquery.
*
* @see SubqueryFunctionNodeBase
* @see FilterExistsModeEnum
* @see bad performance
* for FILTER EXISTS
*/
String FILTER_EXISTS = QueryHints.FILTER_EXISTS;
FilterExistsModeEnum DEFAULT_FILTER_EXISTS = QueryHints.DEFAULT_FILTER_EXISTS;
}
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Deep copy constructor.
*/
public SubqueryRoot(final SubqueryRoot queryBase) {
super(queryBase);
}
/**
* Shallow copy constructor.
*/
public SubqueryRoot(final BOp[] args, final Map anns) {
super(args, anns);
}
/**
* Note: This constructor variant may be used with the implicit subquery for
* EXISTS to specify the type of the subquery as {@link QueryType#ASK}.
*
* @param queryType
*/
public SubqueryRoot(final QueryType queryType) {
super(queryType);
}
/**
* Indicate whether this subquery should run once rather than as-bound.
*
* @param runOnce
*
* @see Annotations#RUN_ONCE
*/
public void setRunOnce(final boolean runOnce) {
setProperty(Annotations.RUN_ONCE, runOnce);
}
public boolean isRunOnce() {
return getProperty(Annotations.RUN_ONCE, Annotations.DEFAULT_RUN_ONCE);
}
/**
*
* @see Annotations#ASK_VAR
*/
public void setAskVar(final IVariable> askVar) {
setProperty(Annotations.ASK_VAR, askVar);
}
/**
* @see Annotations#ASK_VAR
*/
public IVariable> getAskVar() {
return (IVariable>) getProperty(Annotations.ASK_VAR);
}
/**
*
* @see Annotations#FILTER_EXISTS
*/
public void setFilterExistsMode(final FilterExistsModeEnum newVal) {
setProperty(Annotations.FILTER_EXISTS, newVal);
}
/**
* @see Annotations#FILTER_EXISTS
*/
public FilterExistsModeEnum getFilterExistsMode() {
return getProperty(Annotations.FILTER_EXISTS,
Annotations.DEFAULT_FILTER_EXISTS);
}
/**
* Returns false
.
*/
@Override
final public boolean isOptional() {
return false;
}
/**
* Returns false
.
*/
@Override
final public boolean isMinus() {
return false;
}
@Override
final public List getAttachedJoinFilters() {
@SuppressWarnings("unchecked")
final List filters = (List) getProperty(Annotations.FILTERS);
if (filters == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(filters);
}
@Override
final public void setAttachedJoinFilters(final List filters) {
setProperty(Annotations.FILTERS, filters);
}
/**
* {@inheritDoc}
*
* Overridden to also report the {@link Annotations#RUN_ONCE} annotation.
*/
@Override
public String toString(final int indent) {
final StringBuilder sb = new StringBuilder();
sb.append(super.toString(indent));
final boolean runOnce = isRunOnce();
sb.append("\n");
sb.append(indent(indent));
if (runOnce)
sb.append("@" + Annotations.RUN_ONCE + "=" + runOnce);
final IVariable> askVar = getAskVar();
if(askVar != null)
sb.append("@" + Annotations.ASK_VAR + "=" + askVar);
final List filters = getAttachedJoinFilters();
if(!filters.isEmpty()) {
for (FilterNode filter : filters) {
sb.append(filter.toString(indent + 1));
}
}
return sb.toString();
}
}