use of org.apache.atlas.groovy.GroovyExpression in project incubator-atlas by apache.
the class Gremlin3ExpressionFactory method generateHasExpression.
@Override
public GroovyExpression generateHasExpression(GraphPersistenceStrategies s, GroovyExpression parent, String propertyName, String symbol, GroovyExpression requiredValue, FieldInfo fInfo) throws AtlasException {
AttributeInfo attrInfo = fInfo.attrInfo();
IDataType attrType = attrInfo.dataType();
GroovyExpression propertNameExpr = new LiteralExpression(propertyName);
if (s.isPropertyValueConversionNeeded(attrType)) {
// for some types, the logical value cannot be stored directly in
// the underlying graph,
// and conversion logic is needed to convert the persistent form of
// the value
// to the actual value. In cases like this, we generate a conversion
// expression to
// do this conversion and use the filter step to perform the
// comparsion in the gremlin query
GroovyExpression itExpr = getItVariable();
GroovyExpression vertexExpr = new CastExpression(new FunctionCallExpression(itExpr, GET_METHOD), VERTEX_CLASS);
GroovyExpression propertyValueExpr = new FunctionCallExpression(vertexExpr, VALUE_METHOD, propertNameExpr);
GroovyExpression conversionExpr = s.generatePersisentToLogicalConversionExpression(propertyValueExpr, attrType);
GroovyExpression propertyIsPresentExpression = new FunctionCallExpression(new FunctionCallExpression(vertexExpr, PROPERTY_METHOD, propertNameExpr), IS_PRESENT_METHOD);
GroovyExpression valueMatchesExpr = new ComparisonExpression(conversionExpr, getGroovyOperator(symbol), requiredValue);
GroovyExpression filterCondition = new LogicalExpression(propertyIsPresentExpression, LogicalOperator.AND, valueMatchesExpr);
GroovyExpression filterFunction = new ClosureExpression(filterCondition);
return new FunctionCallExpression(TraversalStepType.FILTER, parent, FILTER_METHOD, filterFunction);
} else {
GroovyExpression valueMatches = new FunctionCallExpression(getComparisonFunction(symbol), requiredValue);
return new FunctionCallExpression(TraversalStepType.FILTER, parent, HAS_METHOD, propertNameExpr, valueMatches);
}
}
use of org.apache.atlas.groovy.GroovyExpression in project incubator-atlas by apache.
the class Gremlin3ExpressionFactory method generateGetSelectedValueExpression.
@Override
public GroovyExpression generateGetSelectedValueExpression(LiteralExpression key, GroovyExpression rowMapExpr) {
rowMapExpr = new CastExpression(rowMapExpr, "Map");
GroovyExpression getExpr = new FunctionCallExpression(rowMapExpr, "get", key);
return getExpr;
}
use of org.apache.atlas.groovy.GroovyExpression in project incubator-atlas by apache.
the class Gremlin3ExpressionFactory method getFieldInSelect.
@Override
public GroovyExpression getFieldInSelect() {
// this logic is needed to remove extra results from
// what is emitted by repeat loops. Technically
// for queries that don't have a loop in them we could just use "it"
// the reason for this is that in repeat loops with an alias,
// although the alias gets set to the right value, for some
// reason the select actually includes all vertices that were traversed
// through in the loop. In these cases, we only want the last vertex
// traversed in the loop to be selected. The logic here handles that
// case by converting the result to a list and just selecting the
// last item from it.
GroovyExpression itExpr = getItVariable();
GroovyExpression expr1 = new TypeCoersionExpression(itExpr, VERTEX_ARRAY_CLASS);
GroovyExpression expr2 = new TypeCoersionExpression(expr1, VERTEX_LIST_CLASS);
return new FunctionCallExpression(expr2, LAST_METHOD);
}
use of org.apache.atlas.groovy.GroovyExpression in project incubator-atlas by apache.
the class ExpandAndsOptimization method apply.
/**
* Expands the given and expression. There is no need to recursively
* expand the children here. This method is called recursively by
* GremlinQueryOptimier on the children.
*
*/
@Override
public GroovyExpression apply(GroovyExpression expr, OptimizationContext context) {
FunctionCallExpression exprAsFunction = (FunctionCallExpression) expr;
GroovyExpression result = exprAsFunction.getCaller();
List<GroovyExpression> nonExtractableArguments = new ArrayList<>();
for (GroovyExpression argument : exprAsFunction.getArguments()) {
if (GremlinQueryOptimizer.isExtractable(argument)) {
//Set the caller of the deepest expression in the call hierarchy
//of the argument to point to the current result.
//For example, if result is "g.V()" and the updatedArgument is "has('x').has('y')",
//updatedArgument would be a tree like this:
//
// has('y')
// /
// / caller
// |/_
// has('x')
// /
// / caller
// |/_
// (null)
//
//We would set the caller of has('x') to be g.V(), so result would become g.V().has('x').has('y').
//
// Note: This operation is currently done by making a copy of the argument tree. That should
// be changed.
result = GremlinQueryOptimizer.copyWithNewLeafNode((AbstractFunctionExpression) argument, result);
} else {
logger_.warn("Found non-extractable argument '{}' in the 'and' expression '{}'", argument.toString(), expr.toString());
nonExtractableArguments.add(argument);
}
}
if (!nonExtractableArguments.isEmpty()) {
//add a final 'and' call with the arguments that could not be extracted
result = factory.generateLogicalExpression(result, "and", nonExtractableArguments);
}
return result;
}
use of org.apache.atlas.groovy.GroovyExpression in project incubator-atlas by apache.
the class ExpandOrsOptimization method moveTransformationsToResultExpression.
private GroovyExpression moveTransformationsToResultExpression(GroovyExpression expr, OptimizationContext context) {
GroovyExpression traveralExpression = expr;
// Determine the 'split point'. This is the expression that will become
// the deepest function call in the result expression. If a split
// point is found, its caller is changed. The new caller is
// set to the graph traversal expression in the result expression.
// The original caller becomes the new traversal expression that
// will be carried through the rest of the 'or' expansion processing.
//
// Example: g.V().has('x').as('x').select('x')
// Here, select('x') is the split expression
// so :
// 1) the result expression in OptimizationContext becomes [base result expression].select('x')
// 2) we return g.V().has('x').as('x')
SplitPointFinder finder = new SplitPointFinder(factory);
GremlinQueryOptimizer.visitCallHierarchy(traveralExpression, finder);
AbstractFunctionExpression splitPoint = finder.getSplitPoint();
List<LiteralExpression> aliases = new ArrayList<>();
//the aliases.
if (splitPoint != null) {
traveralExpression = splitPoint.getCaller();
AliasFinder aliasFinder = new AliasFinder();
GremlinQueryOptimizer.visitCallHierarchy(traveralExpression, aliasFinder);
aliases.addAll(aliasFinder.getAliases());
if (aliasFinder.isFinalAliasNeeded()) {
//The last alias in the expression does not capture the final vertex in the traverser,
//so we need to create an alias to record that.
traveralExpression = factory.generateAliasExpression(traveralExpression, context.getFinalAliasName());
aliases.add(new LiteralExpression(context.getFinalAliasName()));
}
GroovyExpression resultExpr = getBaseResultExpression(context, aliases);
splitPoint.setCaller(resultExpr);
expr = removeMapFromPathsIfNeeded(expr, aliases);
context.setResultExpression(expr);
}
//Add expression(s) to the end of the traversal expression to add the vertices
//that were found into the intermediate variable ('r')
traveralExpression = addCallToUpdateResultVariable(traveralExpression, aliases, context);
return traveralExpression;
}
Aggregations