use of org.apache.atlas.groovy.AbstractFunctionExpression in project incubator-atlas by apache.
the class AbstractGremlinQueryOptimizerTest method testRangeWithOrderBy.
@Test
public void testRangeWithOrderBy() throws Exception {
// The range optimization is not supported with order, so the optimizer should not add range expressions
// to the expanded or's.
GroovyExpression toOptimize = getVerticesExpression();
GroovyExpression expr0 = makeHasExpression("__typeName", "OMAS_OMRSAsset");
GroovyExpression expr1 = makeHasExpression("__superTypeNames", "OMAS_OMRSAsset");
toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr0, expr1));
toOptimize = getFactory().generateRangeExpression(toOptimize, 5, 10);
toOptimize = getFactory().generateAliasExpression(toOptimize, "inst");
//toOptimize = getFactory().generateSelectExpression(toOptimize, Collections.singletonList(new LiteralExpression("inst")), Collections.<GroovyExpression>emptyList());
GroovyExpression orderFielda = makeFieldExpression(getFactory().getCurrentTraverserObject(getFactory().getClosureArgumentValue()), "name");
GroovyExpression orderFieldb = makeFieldExpression(getFactory().getCurrentTraverserObject(getFactory().getClosureArgumentValue()), "name");
toOptimize = getFactory().generateOrderByExpression(toOptimize, Arrays.asList(orderFielda, orderFieldb), true);
RangeFinder visitor = new RangeFinder(getFactory());
GremlinQueryOptimizer.visitCallHierarchy(toOptimize, visitor);
List<AbstractFunctionExpression> rangeExpressions = visitor.getRangeExpressions();
assertEquals(rangeExpressions.size(), 1);
int[] rangeParameters = getFactory().getRangeParameters(rangeExpressions.get(0));
assertNotNull(rangeParameters);
GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize);
assertEquals(optimized.toString(), getExpectedGremlinForTestRangeWithOrderBy());
}
use of org.apache.atlas.groovy.AbstractFunctionExpression in project incubator-atlas by apache.
the class ExpandOrsOptimization method setupRangeOptimization.
private void setupRangeOptimization(GroovyExpression expr, OptimizationContext context) {
// Find any range expressions in the expression tree.
RangeFinder rangeFinder = new RangeFinder(factory);
GremlinQueryOptimizer.visitCallHierarchy(expr, rangeFinder);
List<AbstractFunctionExpression> rangeExpressions = rangeFinder.getRangeExpressions();
if (rangeExpressions.size() == 1) {
OrderFinder orderFinder = new OrderFinder(factory);
GremlinQueryOptimizer.visitCallHierarchy(expr, orderFinder);
if (!orderFinder.hasOrderExpression()) {
// If there is one range expression and no order expression in the unoptimized gremlin,
// save the range parameters to use for adding a range expression to
// each expanded "or" expression result, such that it will only contain the specified range of vertices.
// For now, apply this optimization only if the range start index is zero.
AbstractFunctionExpression rangeExpression = rangeExpressions.get(0);
int[] rangeParameters = factory.getRangeParameters(rangeExpression);
if (rangeParameters[0] == 0) {
context.setRangeExpression(rangeExpression);
}
}
}
}
use of org.apache.atlas.groovy.AbstractFunctionExpression in project incubator-atlas by apache.
the class GremlinQueryOptimizer method visitCallHierarchy.
/**
* Visits all expressions in the call hierarchy of an expression. For example,
* in the expression g.V().has('x','y'), the order would be
* <ol>
* <li>pre-visit has('x','y')</li>
* <li>pre-visit V()</li>
* <li>visit g (non-function caller)</li>
* <li>post-visit V()</li>
* <li>post-visit has('x','y')</li>
* </ol>
* @param expr
* @param visitor
*/
public static void visitCallHierarchy(GroovyExpression expr, CallHierarchyVisitor visitor) {
if (expr == null) {
visitor.visitNullCaller();
return;
}
if (expr instanceof AbstractFunctionExpression) {
AbstractFunctionExpression functionCall = (AbstractFunctionExpression) expr;
if (!visitor.preVisitFunctionCaller(functionCall)) {
return;
}
GroovyExpression caller = functionCall.getCaller();
visitCallHierarchy(caller, visitor);
if (!visitor.postVisitFunctionCaller(functionCall)) {
return;
}
} else {
visitor.visitNonFunctionCaller(expr);
}
}
use of org.apache.atlas.groovy.AbstractFunctionExpression in project incubator-atlas by apache.
the class GremlinQueryOptimizer method copyWithNewLeafNode.
/**
* Recursively copies and follows the caller hierarchy of the expression until we come
* to a function call with a null caller. The caller of that expression is set
* to newLeaf.
*
* @param expr
* @param newLeaf
* @return the updated (/copied) expression
*/
public static GroovyExpression copyWithNewLeafNode(AbstractFunctionExpression expr, GroovyExpression newLeaf) {
AbstractFunctionExpression result = (AbstractFunctionExpression) expr.copy();
//remove leading anonymous traversal expression, if there is one
if (FACTORY.isLeafAnonymousTraversalExpression(expr)) {
result = (AbstractFunctionExpression) newLeaf;
} else {
GroovyExpression newCaller = null;
if (expr.getCaller() == null) {
newCaller = newLeaf;
} else {
newCaller = copyWithNewLeafNode((AbstractFunctionExpression) result.getCaller(), newLeaf);
}
result.setCaller(newCaller);
}
return result;
}
use of org.apache.atlas.groovy.AbstractFunctionExpression in project incubator-atlas by apache.
the class IsOrParent method apply.
@Override
public Boolean apply(GroovyExpression expr) {
if (!(expr instanceof AbstractFunctionExpression)) {
return false;
}
AbstractFunctionExpression functionCall = (AbstractFunctionExpression) expr;
GroovyExpression target = functionCall.getCaller();
if (!(target instanceof FunctionCallExpression)) {
return false;
}
if (target.getType() != TraversalStepType.FILTER) {
return false;
}
FunctionCallExpression targetFunction = (FunctionCallExpression) target;
return targetFunction.getFunctionName().equals("or");
}
Aggregations