Search in sources :

Example 1 with FunctionCallExpression

use of org.apache.atlas.groovy.FunctionCallExpression 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);
    }
}
Also used : AttributeInfo(org.apache.atlas.typesystem.types.AttributeInfo) ComparisonExpression(org.apache.atlas.groovy.ComparisonExpression) LogicalExpression(org.apache.atlas.groovy.LogicalExpression) LiteralExpression(org.apache.atlas.groovy.LiteralExpression) GroovyExpression(org.apache.atlas.groovy.GroovyExpression) CastExpression(org.apache.atlas.groovy.CastExpression) ClosureExpression(org.apache.atlas.groovy.ClosureExpression) IDataType(org.apache.atlas.typesystem.types.IDataType) FunctionCallExpression(org.apache.atlas.groovy.FunctionCallExpression)

Example 2 with FunctionCallExpression

use of org.apache.atlas.groovy.FunctionCallExpression 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;
}
Also used : GroovyExpression(org.apache.atlas.groovy.GroovyExpression) CastExpression(org.apache.atlas.groovy.CastExpression) FunctionCallExpression(org.apache.atlas.groovy.FunctionCallExpression)

Example 3 with FunctionCallExpression

use of org.apache.atlas.groovy.FunctionCallExpression 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);
}
Also used : TypeCoersionExpression(org.apache.atlas.groovy.TypeCoersionExpression) GroovyExpression(org.apache.atlas.groovy.GroovyExpression) FunctionCallExpression(org.apache.atlas.groovy.FunctionCallExpression)

Example 4 with FunctionCallExpression

use of org.apache.atlas.groovy.FunctionCallExpression 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;
}
Also used : ArrayList(java.util.ArrayList) GroovyExpression(org.apache.atlas.groovy.GroovyExpression) AbstractFunctionExpression(org.apache.atlas.groovy.AbstractFunctionExpression) FunctionCallExpression(org.apache.atlas.groovy.FunctionCallExpression)

Example 5 with FunctionCallExpression

use of org.apache.atlas.groovy.FunctionCallExpression in project incubator-atlas by apache.

the class FunctionGenerator method createFunctionIfNeeded.

/**
     * Creates a function whose body goes from the child of parentExpr
     * up to (and including) the functionBodyEndExpr.
     * @param parentExpr
     */
private void createFunctionIfNeeded(AbstractFunctionExpression parentExpr) {
    GroovyExpression potentialFunctionBody = parentExpr.getCaller();
    if (creatingFunctionShortensGremlin(potentialFunctionBody)) {
        GroovyExpression functionCall = null;
        if (nextFunctionBodyStart instanceof AbstractFunctionExpression) {
            //The function body start is a a function call.  In this
            //case, we generate a function that takes one argument, which
            //is a graph traversal.  We have an expression tree that
            //looks kind of like the following:
            //
            //                     parentExpr
            //                       /
            //                      / caller
            //                    |/_
            //           potentialFunctionBody
            //                   /
            //                  / caller
            //                |/_
            //               ...
            //               /
            //              / caller
            //            |/_
            //    nextFunctionBodyStart
            //           /
            //          / caller
            //        |/_
            //    oldCaller
            //
            //
            // Note that potentialFunctionBody and nextFunctionBodyStart
            // could be the same expression.  Let's say that the next
            // function name is f1
            //
            // We reshuffle these expressions to the following:
            //
            //                     parentExpr
            //                       /
            //                      / caller
            //                    |/_
            //                f1(oldCaller)
            //
            //
            //           potentialFunctionBody   <- body of new function "f1(GraphTraversal x)"
            //                   /
            //                  / caller
            //                |/_
            //               ...
            //               /
            //              / caller
            //            |/_
            //    nextFunctionBodyStart
            //           /
            //          / caller
            //        |/_
            //        x
            //
            // As an example, suppose parentExpr is g.V().or(x,y).has(a).has(b).has(c)
            // where has(a) is nextFunctionBodyStart.
            //
            // We generate a function f1 = { GraphTraversal x -> x.has(a).has(b) }
            // parentExpr would become : f1(g.V().or(x,y)).has(c)
            AbstractFunctionExpression nextFunctionBodyStartFunction = (AbstractFunctionExpression) nextFunctionBodyStart;
            String variableName = "x";
            IdentifierExpression var = new IdentifierExpression(variableName);
            GroovyExpression oldCaller = nextFunctionBodyStartFunction.getCaller();
            nextFunctionBodyStartFunction.setCaller(var);
            currentFunctionName = context.addFunctionDefinition(new VariableDeclaration(factory.getTraversalExpressionClass(), "x"), potentialFunctionBody);
            functionCall = new FunctionCallExpression(potentialFunctionBody.getType(), currentFunctionName, oldCaller);
        } else {
            //The function body start is a not a function call.  In this
            //case, we generate a function that takes no arguments.
            // As an example, suppose parentExpr is g.V().has(a).has(b).has(c)
            // where g is nextFunctionBodyStart.
            //
            // We generate a function f1 = { g.V().has(a).has(b) }
            // parentExpr would become : f1().has(c)
            currentFunctionName = context.addFunctionDefinition(null, potentialFunctionBody);
            functionCall = new FunctionCallExpression(potentialFunctionBody.getType(), currentFunctionName);
        }
        //functionBodyEnd is now part of a function definition, don't propagate it
        nextFunctionBodyStart = null;
        parentExpr.setCaller(functionCall);
    }
}
Also used : GroovyExpression(org.apache.atlas.groovy.GroovyExpression) AbstractFunctionExpression(org.apache.atlas.groovy.AbstractFunctionExpression) VariableDeclaration(org.apache.atlas.groovy.ClosureExpression.VariableDeclaration) FunctionCallExpression(org.apache.atlas.groovy.FunctionCallExpression) IdentifierExpression(org.apache.atlas.groovy.IdentifierExpression)

Aggregations

FunctionCallExpression (org.apache.atlas.groovy.FunctionCallExpression)42 GroovyExpression (org.apache.atlas.groovy.GroovyExpression)34 LiteralExpression (org.apache.atlas.groovy.LiteralExpression)15 ClosureExpression (org.apache.atlas.groovy.ClosureExpression)14 CastExpression (org.apache.atlas.groovy.CastExpression)5 TypeCoersionExpression (org.apache.atlas.groovy.TypeCoersionExpression)5 AbstractFunctionExpression (org.apache.atlas.groovy.AbstractFunctionExpression)4 ComparisonExpression (org.apache.atlas.groovy.ComparisonExpression)4 FieldExpression (org.apache.atlas.groovy.FieldExpression)4 IdentifierExpression (org.apache.atlas.groovy.IdentifierExpression)4 TernaryOperatorExpression (org.apache.atlas.groovy.TernaryOperatorExpression)4 Test (org.testng.annotations.Test)4 ArrayList (java.util.ArrayList)3 ComparisonOperatorExpression (org.apache.atlas.groovy.ComparisonOperatorExpression)2 LogicalExpression (org.apache.atlas.groovy.LogicalExpression)2 AttributeInfo (org.apache.atlas.typesystem.types.AttributeInfo)2 IDataType (org.apache.atlas.typesystem.types.IDataType)2 VariableDeclaration (org.apache.atlas.groovy.ClosureExpression.VariableDeclaration)1 ListExpression (org.apache.atlas.groovy.ListExpression)1 TraversalStepType (org.apache.atlas.groovy.TraversalStepType)1