com.bigdata.rdf.sparql.ast.optimizers.AbstractOptimizerTestCaseWithUtilityMethods Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bigdata-rdf-test Show documentation
Show all versions of bigdata-rdf-test Show documentation
Blazegraph(TM) RDF Test Suites
/**
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 June 20, 2015
*/
package com.bigdata.rdf.sparql.ast.optimizers;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import com.bigdata.bop.BOpUtility;
import com.bigdata.bop.Constant;
import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.IVariable;
import com.bigdata.bop.Var;
import com.bigdata.bop.bindingSet.ListBindingSet;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.VTE;
import com.bigdata.rdf.internal.impl.TermId;
import com.bigdata.rdf.model.BigdataURI;
import com.bigdata.rdf.model.BigdataValue;
import com.bigdata.rdf.model.BigdataValueFactory;
import com.bigdata.rdf.sparql.ast.ASTContainer;
import com.bigdata.rdf.sparql.ast.ArbitraryLengthPathNode;
import com.bigdata.rdf.sparql.ast.AssignmentNode;
import com.bigdata.rdf.sparql.ast.BindingsClause;
import com.bigdata.rdf.sparql.ast.FilterNode;
import com.bigdata.rdf.sparql.ast.FunctionNode;
import com.bigdata.rdf.sparql.ast.GlobalAnnotations;
import com.bigdata.rdf.sparql.ast.HavingNode;
import com.bigdata.rdf.sparql.ast.IGroupMemberNode;
import com.bigdata.rdf.sparql.ast.IValueExpressionNode;
import com.bigdata.rdf.sparql.ast.IValueExpressionNodeContainer;
import com.bigdata.rdf.sparql.ast.JoinGroupNode;
import com.bigdata.rdf.sparql.ast.ProjectionNode;
import com.bigdata.rdf.sparql.ast.PropertyPathNode;
import com.bigdata.rdf.sparql.ast.QueryHints;
import com.bigdata.rdf.sparql.ast.QueryRoot;
import com.bigdata.rdf.sparql.ast.QueryType;
import com.bigdata.rdf.sparql.ast.RangeNode;
import com.bigdata.rdf.sparql.ast.StatementPatternNode;
import com.bigdata.rdf.sparql.ast.StaticAnalysis;
import com.bigdata.rdf.sparql.ast.SubqueryRoot;
import com.bigdata.rdf.sparql.ast.UnionNode;
import com.bigdata.rdf.sparql.ast.ValueExpressionNode;
import com.bigdata.rdf.sparql.ast.VarNode;
import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext;
import com.bigdata.rdf.sparql.ast.eval.AST2BOpUtility;
import com.bigdata.rdf.sparql.ast.service.ServiceNode;
import com.bigdata.rdf.store.BDS;
import com.bigdata.service.fts.FTS;
import cutthecrap.utils.striterators.Filter;
import cutthecrap.utils.striterators.IStriterator;
import cutthecrap.utils.striterators.Striterator;
/**
* Test case helper class in the style of {@link Helper} exposing additional
* methods for constructing ASTs with different properties.
*
* @author Michael Schmidt
*/
@SuppressWarnings({ "rawtypes" })
public abstract class AbstractOptimizerTestCaseWithUtilityMethods
extends AbstractOptimizerTestCase {
public AbstractOptimizerTestCaseWithUtilityMethods() {
}
public AbstractOptimizerTestCaseWithUtilityMethods(String name) {
super(name);
}
/**
* Returns a fresh statement pattern with the specified variable bound.
*/
StatementPatternNode stmtPatternWithVar(final String varName) {
return stmtPatternWithVar(varName, false);
}
/**
* Returns a fresh statement pattern with the specified variables bound.
*/
StatementPatternNode stmtPatternWithVars(
final String varName1, final String varName2) {
final StatementPatternNode spn =
(StatementPatternNode) new Helper(){{
tmp = statementPatternNode(
varNode(varName1),constantNode(a),varNode(varName2));
}}.getTmp();
return spn;
}
/**
* Returns a fresh statement pattern with the specified variables bound.
*/
StatementPatternNode stmtPatternWithVarsOptional(
final String varName1, final String varName2) {
final StatementPatternNode spn = stmtPatternWithVars(varName1, varName2);
spn.setOptional(true);
return spn;
}
/**
* Returns a fresh optional statement pattern with the specified variable bound.
*/
StatementPatternNode stmtPatternWithVarOptional(final String varName) {
return stmtPatternWithVar(varName, true);
}
/**
* Returns a fresh statement pattern with the specified variable bound that
* is either optional or not, as specified by the second parameter.
*/
StatementPatternNode stmtPatternWithVar(
final String varName, final boolean optional) {
final StatementPatternNode spn =
(StatementPatternNode) new Helper(){{
tmp = statementPatternNode(varNode(varName),constantNode(a),constantNode(b));
}}.getTmp();
spn.setOptional(optional);
return spn;
}
/**
* For each variable, a fresh statement pattern with the variable is created
* and the list of statement patterns is returned.
*/
StatementPatternNode[] stmtPatternsWithVars(final String... varNames) {
final StatementPatternNode[] statementPatterns =
new StatementPatternNode[varNames.length];
for (int i=0; i> declaredVars =
new LinkedHashSet>();
for (String varName : varNames) {
declaredVars.add(Var.var(varName));
}
final List bindingSets = new ArrayList();
IBindingSet bs = new ListBindingSet();
for (String varName : varNames) {
bs.set(Var.var(varName), new Constant<>(TermId.mockIV(VTE.URI)));
}
return new BindingsClause(declaredVars, bindingSets);
}
/**
* Returns a {@link SubqueryRoot} projecting the specified vars.
*/
SubqueryRoot subqueryWithVars(final String... varNames) {
final AssignmentNode[] assignments =
assignmentWithVars(varNames);
final StatementPatternNode[] statementPatterns =
stmtPatternsWithVars(varNames);
final SubqueryRoot subquery = (SubqueryRoot) new Helper() {{
tmp =
selectSubQuery(
projection(assignments),
where(joinGroupNode((Object[])statementPatterns)));
}}.getTmp();
return subquery;
}
/**
* Returns an {@link ArbitraryLengthPathNode} binding varNames in their
* body, where the first parameter specified the
* {@link ArbitraryLengthPathNode}s internal variable.
*/
PropertyPathNode alpNodeWithVars(
final String varName1, final String varName2) {
final PropertyPathNode alpNode =
(PropertyPathNode) new Helper() {{
tmp = propertyPathNode(varNode(varName1), "c*", varNode(varName2));
}}.getTmp();
return alpNode;
}
/**
* Returns a SPARQL 1.1 {@link ServiceNode} using the specified vars in its
* body, with a constant endpoint.
*/
ServiceNode serviceSparql11WithConstant(final String... varNames) {
final JoinGroupNode jgn = joinGroupWithVars(varNames);
final BigdataValueFactory f = store.getValueFactory();
final BigdataURI serviceEndpoint = f.createURI("http://custom.endpoint");
final IV serviceEndpointIV = makeIV(serviceEndpoint);
final BigdataValue[] values = new BigdataValue[] { serviceEndpoint };
store.getLexiconRelation().addTerms(
values, values.length, false/* readOnly */);
final ServiceNode serviceNode =
(ServiceNode) new Helper(){{
tmp = service(constantNode(serviceEndpointIV),jgn);
}}.getTmp();
return serviceNode;
}
/**
* Returns a SPARQL 1.1 {@link ServiceNode} using the specified vars in its
* body, with an endpoint specified through endpointVar.
*/
ServiceNode serviceSparql11WithVariable(
final String endpointVar, final String... varNames) {
final JoinGroupNode jgn = joinGroupWithVars(varNames);
final ServiceNode serviceNode =
(ServiceNode) new Helper(){{
tmp = service(varNode(endpointVar),jgn);
}}.getTmp();
return serviceNode;
}
/**
* Returns a BDS type {@link ServiceNode} using the specified vars in its
* body.
*/
ServiceNode serviceBDSWithVariable(final String inputVar) {
final BigdataValueFactory f = store.getValueFactory();
final BigdataURI bdsSearch = f.createURI(BDS.NAMESPACE + "search");
final BigdataURI predSearch = f.createURI(BDS.SEARCH.toString());
final BigdataURI predSearchTimeout = f.createURI(BDS.SEARCH_TIMEOUT.toString());
final BigdataURI predMatchExact = f.createURI(BDS.MATCH_EXACT.toString());
final BigdataValue[] values =
new BigdataValue[] { bdsSearch, predSearch, predSearchTimeout, predMatchExact };
store.getLexiconRelation().addTerms(values, values.length, false/* readOnly */);
final ServiceNode serviceNode =
(ServiceNode) new Helper(){{
tmp =
service(
constantNode(makeIV(bdsSearch)),
joinGroupNode(
statementPatternNode(varNode(inputVar), constantNode(makeIV(predSearch)), constantNode("search")),
statementPatternNode(varNode(inputVar), constantNode(makeIV(predSearchTimeout)), constantNode("1000")),
statementPatternNode(varNode(inputVar), constantNode(makeIV(predMatchExact)), constantNode("false"))));
}}.getTmp();
return serviceNode;
}
/**
* Return a FTS type {@link ServiceNode} using the specified variables.
*/
ServiceNode serviceFTSWithVariable(
// output variables:
final String resultVar, final String scoreVar, final String snippetVar,
// input variables:
final String searchVar, final String endpointVar, final String paramsVar) {
final BigdataValueFactory f = store.getValueFactory();
final BigdataURI ftsSearch = f.createURI(FTS.NAMESPACE + "search");
final BigdataURI predSearch = f.createURI(FTS.SEARCH.toString());
final BigdataURI predEndpoint = f.createURI(FTS.ENDPOINT.toString());
final BigdataURI predParams = f.createURI(FTS.PARAMS.toString());
final BigdataValue[] values =
new BigdataValue[] {
ftsSearch, predSearch, predEndpoint, predParams };
store.getLexiconRelation().addTerms(values, values.length, false/* readOnly */);
final ServiceNode serviceNode = (ServiceNode) new Helper(){{
tmp =
service(
constantNode(makeIV(ftsSearch)),
joinGroupNode(
statementPatternNode(varNode(resultVar), constantNode(makeIV(predSearch)), varNode(searchVar)),
statementPatternNode(varNode(resultVar), constantNode(makeIV(predEndpoint)), varNode(endpointVar)),
statementPatternNode(varNode(resultVar), constantNode(makeIV(predParams)), varNode(paramsVar))));
}}.getTmp();
return serviceNode;
}
public Set> varSet(String... varNames) {
final Set> varSet = new HashSet>();
for (String varName : varNames) {
varSet.add(Var.var(varName));
}
return varSet;
}
/**
* Properly resolves the value expressions in the {@link IGroupMemberNode}.
*/
IGroupMemberNode resolveVEs(final IGroupMemberNode groupNode) {
final QueryRoot query = new QueryRoot(QueryType.SELECT);
final JoinGroupNode jgn = new JoinGroupNode(groupNode);
query.setWhereClause(jgn);
final AST2BOpContext context =
new AST2BOpContext(new ASTContainer(query), store);
final GlobalAnnotations globals =
new GlobalAnnotations(
context.getLexiconNamespace(), context.getTimestamp());
/*
* Visit nodes that require modification.
*/
final IStriterator it = new Striterator(
BOpUtility.preOrderIteratorWithAnnotations(groupNode))
.addFilter(new Filter() {
private static final long serialVersionUID = 1L;
@Override
public boolean isValid(Object obj) {
if (obj instanceof IValueExpressionNodeContainer)
return true;
if (obj instanceof HavingNode)
return true;
if (obj instanceof StatementPatternNode)
return true;
return false;
}
});
while (it.hasNext()) {
final Object op = it.next();
if (op instanceof IValueExpressionNodeContainer) {
// AssignmentNode, FilterNode, OrderByExpr
AST2BOpUtility.toVE(getBOpContext(), globals,
((IValueExpressionNodeContainer) op).getValueExpressionNode());
} else if (op instanceof HavingNode) {
final HavingNode havingNode = (HavingNode)op;
for(IValueExpressionNode node : havingNode) {
AST2BOpUtility.toVE(getBOpContext(), globals, node);
}
} else if (op instanceof StatementPatternNode) {
final StatementPatternNode sp = (StatementPatternNode) op;
final RangeNode range = sp.getRange();
if (range != null) {
if (range.from() != null)
AST2BOpUtility.toVE(getBOpContext(), globals, range.from());
if (range.to() != null)
AST2BOpUtility.toVE(getBOpContext(), globals, range.to());
}
}
}
return groupNode;
}
/**
* Creates a {@link StaticAnalysis} object for the nodes by setting up a
* SELECT query with a single {@link JoinGroupNode} comprising the nodes
* in its body to retrieve the {@link StaticAnalysis} object.
*/
StaticAnalysis statisAnalysisForNodes(List nodes) {
final IGroupMemberNode[] nodesArr =
nodes.toArray(new IGroupMemberNode[nodes.size()]);
final JoinGroupNode jgn =
(JoinGroupNode) new Helper(){{
tmp = joinGroupNode((Object[])nodesArr);
}}.getTmp();
final QueryRoot queryRoot = new QueryRoot(QueryType.SELECT);
queryRoot.setWhereClause(jgn);
return new StaticAnalysis(
queryRoot, new AST2BOpContext(new ASTContainer(queryRoot), store));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy