atlas-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jeffrey N Hagelberg" <jnhagelb...@us.ibm.com>
Subject RE: [5/5] incubator-atlas git commit: ATLAS-1369 - Optimize gremlin queries generated by DSL translator
Date Wed, 01 Feb 2017 23:26:13 GMT


FYI - This is fixed now.

-----Original Message-----
From: Madhan Neethiraj [mailto:madhan@apache.org]
Sent: Wednesday, February 01, 2017 5:21 PM
To: jnhagelberg@apache.org
Cc: dev@atlas.incubator.apache.org
Subject: Re: [5/5] incubator-atlas git commit: ATLAS-1369 - Optimize
gremlin queries generated by DSL translator

Jeff,

Does this patch require JDK8? Compiling with JDK7 fails with the failures
like:

[ERROR] /Users/mneethiraj/Apache/git/incubator-atlas/repository/src/main/java/org/apache/atlas/gremlin/optimizer/ExpressionFinder.java:20:
 error: package java.util.function does not exist
    [ERROR] import java.util.function.Function;
    [ERROR]                          ^

[ERROR] /Users/mneethiraj/Apache/git/incubator-atlas/repository/src/main/java/org/apache/atlas/gremlin/optimizer/ExpressionFinder.java:32:
 error: cannot find symbol
    [ERROR]     private final Function<GroovyExpression, Boolean>
predicate;
    [ERROR]                   ^


Can you please review and update to make it compatible with JDK7?

Thanks,
Madhan




On 2/1/17, 1:05 PM, "jnhagelberg@apache.org" <jnhagelberg@apache.org>
wrote:

    ATLAS-1369 - Optimize gremlin queries generated by DSL translator


    Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo
    Commit:
http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/aa74c73d
    Tree:
http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/aa74c73d
    Diff:
http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/aa74c73d

    Branch: refs/heads/master
    Commit: aa74c73d0e9fbfd9c51de9f6cdcdea6141575e8e
    Parents: f640da7
    Author: Jeff Hagelberg <jnhagelberg@us.ibm.com>
    Authored: Wed Feb 1 16:03:34 2017 -0500
    Committer: Jeff Hagelberg <jnhagelberg@us.ibm.com>
    Committed: Wed Feb 1 16:04:39 2017 -0500

    ----------------------------------------------------------------------
     .../groovy/AbstractFunctionExpression.java      |  57 ++
     .../atlas/groovy/AbstractGroovyExpression.java  |   9 +
     .../atlas/groovy/ArithmeticExpression.java      |  12 +
     .../apache/atlas/groovy/BinaryExpression.java   |   9 +-
     .../org/apache/atlas/groovy/CastExpression.java |  14 +-
     .../apache/atlas/groovy/ClosureExpression.java  |  90 ++-
     .../atlas/groovy/CodeBlockExpression.java       |  61 --
     .../atlas/groovy/ComparisonExpression.java      |  12 +
     .../groovy/ComparisonOperatorExpression.java    |   8 +
     .../apache/atlas/groovy/FieldExpression.java    |  21 +-
     .../atlas/groovy/FunctionCallExpression.java    |  88 ++-
     .../apache/atlas/groovy/GroovyExpression.java   |  42 +-
     .../atlas/groovy/IdentifierExpression.java      |  31 +
     .../apache/atlas/groovy/LabeledExpression.java  |  54 ++
     .../org/apache/atlas/groovy/ListExpression.java |  12 +
     .../apache/atlas/groovy/LiteralExpression.java  |  25 +-
     .../apache/atlas/groovy/LogicalExpression.java  |  12 +
     .../apache/atlas/groovy/RangeExpression.java    |  62 +-
     .../atlas/groovy/StatementListExpression.java   |  98 +++
     .../atlas/groovy/TernaryOperatorExpression.java |  25 +-
     .../apache/atlas/groovy/TraversalStepType.java  | 121 ++++
     .../atlas/groovy/TypeCoersionExpression.java    |  19 +-
     .../groovy/VariableAssignmentExpression.java    |  16 +-
     distro/src/conf/atlas-application.properties    |   7 +
     graphdb/titan0/pom.xml                          |   8 +
     intg/pom.xml                                    |   1 -
     pom.xml                                         |   8 +-
     release-log.txt                                 |   5 +-
     .../atlas/discovery/DataSetLineageService.java  |   7 +-
     .../gremlin/Gremlin2ExpressionFactory.java      | 139 +++-
     .../gremlin/Gremlin3ExpressionFactory.java      | 184 +++--
     .../atlas/gremlin/GremlinExpressionFactory.java | 274 +++++--
     .../atlas/gremlin/optimizer/AliasFinder.java    | 103 +++
     .../gremlin/optimizer/CallHierarchyVisitor.java |  62 ++
     .../optimizer/ExpandAndsOptimization.java       | 130 ++++
     .../optimizer/ExpandOrsOptimization.java        | 584 +++++++++++++++
     .../gremlin/optimizer/ExpressionFinder.java     |  69 ++
     .../gremlin/optimizer/FunctionGenerator.java    | 326 +++++++++
     .../gremlin/optimizer/GremlinOptimization.java  |  48 ++
     .../optimizer/GremlinQueryOptimizer.java        | 262 +++++++
     .../gremlin/optimizer/HasForbiddenType.java     |  52 ++
     .../apache/atlas/gremlin/optimizer/IsOr.java    |  48 ++
     .../atlas/gremlin/optimizer/IsOrParent.java     |  60 ++
     .../gremlin/optimizer/OptimizationContext.java  | 116 +++
     .../atlas/gremlin/optimizer/OrderFinder.java    |  68 ++
     .../gremlin/optimizer/PathExpressionFinder.java |  61 ++
     .../atlas/gremlin/optimizer/RangeFinder.java    |  68 ++
     .../gremlin/optimizer/SplitPointFinder.java     | 161 +++++
     .../gremlin/optimizer/UpdatedExpressions.java   |  45 ++
     .../graph/GraphBackedMetadataRepository.java    |  23 +-
     .../graph/GraphToTypedInstanceMapper.java       |  13 +-
     .../util/AtlasRepositoryConfiguration.java      |  19 +-
     .../org/apache/atlas/query/GremlinQuery.scala   | 103 ++-
     .../GraphBackedDiscoveryServiceTest.java        |   3 +
     .../AbstractGremlinQueryOptimizerTest.java      | 705 ++++++++++++++++
+++
     .../graph/Gremlin2QueryOptimizerTest.java       | 363 ++++++++++
     .../graph/Gremlin3QueryOptimizerTest.java       | 364 ++++++++++
     .../atlas/repository/graph/TestIntSequence.java |  35 +
     .../org/apache/atlas/query/GremlinTest.scala    |   4 +-
     59 files changed, 5157 insertions(+), 269 deletions(-)
    ----------------------------------------------------------------------



http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/AbstractFunctionExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/AbstractFunctionExpression.java

b/common/src/main/java/org/apache/atlas/groovy/AbstractFunctionExpression.java

    new file mode 100644
    index 0000000..2e2307c
    --- /dev/null
    +++
b/common/src/main/java/org/apache/atlas/groovy/AbstractFunctionExpression.java

    @@ -0,0 +1,57 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +package org.apache.atlas.groovy;
    +
    +/**
    + * Base class for all expression that can have a caller.
    + */
    +public abstract class AbstractFunctionExpression extends
AbstractGroovyExpression {
    +
    +    // null for global functions
    +    private GroovyExpression caller;
    +    private TraversalStepType type = TraversalStepType.NONE;
    +
    +    public AbstractFunctionExpression(GroovyExpression target) {
    +        this.caller = target;
    +    }
    +
    +    public AbstractFunctionExpression(TraversalStepType type,
GroovyExpression target) {
    +        this.caller = target;
    +        this.type = type;
    +    }
    +
    +    public  GroovyExpression getCaller() {
    +        return caller;
    +    }
    +
    +    public void setCaller(GroovyExpression expr) {
    +        caller = expr;
    +    }
    +
    +
    +    public void setType(TraversalStepType type) {
    +        this.type = type;
    +    }
    +
    +    @Override
    +    public TraversalStepType getType() {
    +        return type;
    +    }
    +
    +
    +}


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/AbstractGroovyExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/AbstractGroovyExpression.java

b/common/src/main/java/org/apache/atlas/groovy/AbstractGroovyExpression.java

    index 49eaae8..e4a7781 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/AbstractGroovyExpression.java

    +++
b/common/src/main/java/org/apache/atlas/groovy/AbstractGroovyExpression.java

    @@ -33,4 +33,13 @@ public abstract class AbstractGroovyExpression
implements GroovyExpression {
             return ctx.getQuery();
         }

    +    @Override
    +    public TraversalStepType getType() {
    +        return TraversalStepType.NONE;
    +    }
    +
    +    @Override
    +    public GroovyExpression copy() {
    +        return copy(getChildren());
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java
b/common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java
    index 0aec5d0..a6e1689 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java
    +++
b/common/src/main/java/org/apache/atlas/groovy/ArithmeticExpression.java
    @@ -17,6 +17,8 @@
      */
     package org.apache.atlas.groovy;

    +import java.util.List;
    +
     import org.apache.atlas.AtlasException;

     /**
    @@ -56,4 +58,14 @@ public class ArithmeticExpression extends
BinaryExpression {
         public ArithmeticExpression(GroovyExpression left,
ArithmeticOperator op, GroovyExpression right) {
             super(left, op.getGroovyValue(), right);
         }
    +
    +    private ArithmeticExpression(GroovyExpression left, String op,
GroovyExpression right) {
    +        super(left, op, right);
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 2;
    +        return new ArithmeticExpression(newChildren.get(0), op,
newChildren.get(1));
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/BinaryExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/BinaryExpression.java
b/common/src/main/java/org/apache/atlas/groovy/BinaryExpression.java
    index ccc9204..852845e 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/BinaryExpression.java
    +++
b/common/src/main/java/org/apache/atlas/groovy/BinaryExpression.java
    @@ -18,6 +18,9 @@

     package org.apache.atlas.groovy;

    +import java.util.Arrays;
    +import java.util.List;
    +
     /**
      * Represents any kind of binary expression.  This could
      * be an arithmetic expression, such as a + 3, a boolean
    @@ -30,7 +33,7 @@ public abstract class BinaryExpression extends
AbstractGroovyExpression {

         private GroovyExpression left;
         private GroovyExpression right;
    -    private String op;
    +    protected String op;

         public BinaryExpression(GroovyExpression left, String op,
GroovyExpression right) {
             this.left = left;
    @@ -48,4 +51,8 @@ public abstract class BinaryExpression extends
AbstractGroovyExpression {
             right.generateGroovy(context);
         }

    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Arrays.asList(left, right);
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/CastExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/CastExpression.java
b/common/src/main/java/org/apache/atlas/groovy/CastExpression.java
    index 963724c..808f327 100644
    --- a/common/src/main/java/org/apache/atlas/groovy/CastExpression.java
    +++ b/common/src/main/java/org/apache/atlas/groovy/CastExpression.java
    @@ -18,6 +18,9 @@

     package org.apache.atlas.groovy;

    +import java.util.Collections;
    +import java.util.List;
    +
     /**
      * Groovy expression that represents a cast.
      */
    @@ -28,7 +31,7 @@ public class CastExpression extends
AbstractGroovyExpression {

         public CastExpression(GroovyExpression expr, String className) {
             this.expr = expr;
    -        this.className  =className;
    +        this.className  = className;
         }

         @Override
    @@ -41,4 +44,13 @@ public class CastExpression extends
AbstractGroovyExpression {
             context.append(")");
         }

    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.singletonList(expr);
    +    }
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 1;
    +        return new CastExpression(newChildren.get(0), className);
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/ClosureExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/ClosureExpression.java
b/common/src/main/java/org/apache/atlas/groovy/ClosureExpression.java
    index 2d70209..a5ca0b6 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/ClosureExpression.java
    +++
b/common/src/main/java/org/apache/atlas/groovy/ClosureExpression.java
    @@ -20,6 +20,7 @@ package org.apache.atlas.groovy;

     import java.util.ArrayList;
     import java.util.Arrays;
    +import java.util.Collections;
     import java.util.Iterator;
     import java.util.List;

    @@ -28,28 +29,79 @@ import java.util.List;
      */
     public class ClosureExpression extends AbstractGroovyExpression {

    -    private List<String> varNames = new ArrayList<>();
    -    private GroovyExpression body;
    +    /**
    +     * Variable declaration in a closure.
    +     */
    +    public static class VariableDeclaration {
    +        private String type;
    +        private String varName;

    -    public ClosureExpression(GroovyExpression body, String...
varNames) {
    -        this.body = body;
    -        this.varNames.addAll(Arrays.asList(varNames));
    +        public VariableDeclaration(String type, String varName) {
    +            super();
    +            this.type = type;
    +            this.varName = varName;
    +        }
    +
    +        public VariableDeclaration(String varName) {
    +            this.varName = varName;
    +        }
    +
    +        public void append(GroovyGenerationContext context) {
    +            if (type != null) {
    +                context.append(type);
    +                context.append(" ");
    +            }
    +            context.append(varName);
    +        }
    +    }
    +    private List<VariableDeclaration> vars = new ArrayList<>();
    +    private StatementListExpression body = new StatementListExpression
();
    +
    +    public ClosureExpression(String... varNames) {
    +        this(null, varNames);
    +    }
    +
    +    public ClosureExpression(GroovyExpression initialStmt, String...
varNames) {
    +        this(Arrays.asList(varNames), initialStmt);
    +    }
    +
    +    public ClosureExpression(List<String> varNames, GroovyExpression
initialStmt) {
    +        if (initialStmt != null) {
    +            this.body.addStatement(initialStmt);
    +        }
    +        for (String varName : varNames) {
    +            vars.add(new VariableDeclaration(varName));
    +        }
         }

    -    public ClosureExpression(List<String> varNames, GroovyExpression
body) {
    -        this.body = body;
    -        this.varNames.addAll(varNames);
    +    public ClosureExpression(GroovyExpression initialStmt,
List<VariableDeclaration> varNames) {
    +        if (initialStmt != null) {
    +            this.body.addStatement(initialStmt);
    +        }
    +        vars.addAll(varNames);
    +    }
    +
    +    public void addStatement(GroovyExpression expr) {
    +        body.addStatement(expr);
    +    }
    +
    +    public void addStatements(List<GroovyExpression> exprs) {
    +        body.addStatements(exprs);
    +    }
    +
    +    public void replaceStatement(int index, GroovyExpression newExpr)
{
    +        body.replaceStatement(index, newExpr);
         }

         @Override
         public void generateGroovy(GroovyGenerationContext context) {

             context.append("{");
    -        if (!varNames.isEmpty()) {
    -            Iterator<String> varIt = varNames.iterator();
    +        if (!vars.isEmpty()) {
    +            Iterator<VariableDeclaration> varIt = vars.iterator();
                 while(varIt.hasNext()) {
    -                String varName = varIt.next();
    -                context.append(varName);
    +                VariableDeclaration var = varIt.next();
    +                var.append(context);
                     if (varIt.hasNext()) {
                         context.append(", ");
                     }
    @@ -58,6 +110,20 @@ public class ClosureExpression extends
AbstractGroovyExpression {
             }
             body.generateGroovy(context);
             context.append("}");
    +    }
    +
    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.<GroovyExpression>singletonList(body);
    +    }

    +    public List<GroovyExpression> getStatements() {
    +        return body.getStatements();
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 1;
    +        return new ClosureExpression(newChildren.get(0), vars);
         }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/CodeBlockExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/CodeBlockExpression.java
b/common/src/main/java/org/apache/atlas/groovy/CodeBlockExpression.java
    deleted file mode 100644
    index 9a726f2..0000000
    ---
a/common/src/main/java/org/apache/atlas/groovy/CodeBlockExpression.java
    +++ /dev/null
    @@ -1,61 +0,0 @@
    -/**
    - * Licensed to the Apache Software Foundation (ASF) under one
    - * or more contributor license agreements.  See the NOTICE file
    - * distributed with this work for additional information
    - * regarding copyright ownership.  The ASF licenses this file
    - * to you under the Apache License, Version 2.0 (the
    - * "License"); you may not use this file except in compliance
    - * with the License.  You may obtain a copy of the License at
    - *
    - *     http://www.apache.org/licenses/LICENSE-2.0
    - *
    - * Unless required by applicable law or agreed to in writing, software
    - * distributed under the License is distributed on an "AS IS" BASIS,
    - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
    - * See the License for the specific language governing permissions and
    - * limitations under the License.
    - */
    -
    -package org.apache.atlas.groovy;
    -
    -import java.util.ArrayList;
    -import java.util.Iterator;
    -import java.util.List;
    -
    -/**
    - * Groovy expression that represents a block of code
    - * that contains 0 or more statements that are delimited
    - * by semicolons.
    - */
    -public class CodeBlockExpression extends AbstractGroovyExpression {
    -
    -    private List<GroovyExpression> body = new ArrayList<>();
    -
    -    public void addStatement(GroovyExpression expr) {
    -        body.add(expr);
    -    }
    -
    -    public void addStatements(List<GroovyExpression> exprs) {
    -        body.addAll(exprs);
    -    }
    -
    -    @Override
    -    public void generateGroovy(GroovyGenerationContext context) {
    -
    -        /*
    -         * the L:{} represents a groovy code block; the label is
needed
    -         * to distinguish it from a groovy closure.
    -         */
    -        context.append("L:{");
    -        Iterator<GroovyExpression> stmtIt = body.iterator();
    -        while(stmtIt.hasNext()) {
    -            GroovyExpression stmt = stmtIt.next();
    -            stmt.generateGroovy(context);
    -            if (stmtIt.hasNext()) {
    -                context.append(";");
    -            }
    -        }
    -        context.append("}");
    -
    -    }
    -}


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/ComparisonExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/ComparisonExpression.java
b/common/src/main/java/org/apache/atlas/groovy/ComparisonExpression.java
    index 345f838..b64533f 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/ComparisonExpression.java
    +++
b/common/src/main/java/org/apache/atlas/groovy/ComparisonExpression.java
    @@ -17,6 +17,8 @@
      */
     package org.apache.atlas.groovy;

    +import java.util.List;
    +
     import org.apache.atlas.AtlasException;

     /**
    @@ -61,4 +63,14 @@ public class ComparisonExpression extends
BinaryExpression {
         public ComparisonExpression(GroovyExpression left,
ComparisonOperator op, GroovyExpression right) {
             super(left, op.getGroovyValue(), right);
         }
    +
    +    private ComparisonExpression(GroovyExpression left, String op,
GroovyExpression right) {
    +        super(left, op, right);
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 2;
    +        return new ComparisonExpression(newChildren.get(0), op,
newChildren.get(1));
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/ComparisonOperatorExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/ComparisonOperatorExpression.java

b/common/src/main/java/org/apache/atlas/groovy/ComparisonOperatorExpression.java

    index 63638b7..c9e363e 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/ComparisonOperatorExpression.java

    +++
b/common/src/main/java/org/apache/atlas/groovy/ComparisonOperatorExpression.java

    @@ -17,6 +17,8 @@
      */
     package org.apache.atlas.groovy;

    +import java.util.List;
    +
     /**
      * Represents an expression that compares two expressions using
      * the Groovy "spaceship" operator.  This is basically the
    @@ -29,4 +31,10 @@ public class ComparisonOperatorExpression extends
BinaryExpression {
         public ComparisonOperatorExpression(GroovyExpression left,
GroovyExpression right) {
             super(left, "<=>", right);
         }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 2;
    +        return new ComparisonOperatorExpression(newChildren.get(0),
newChildren.get(1));
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/FieldExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/FieldExpression.java
b/common/src/main/java/org/apache/atlas/groovy/FieldExpression.java
    index f6d06bd..6a182ad 100644
    --- a/common/src/main/java/org/apache/atlas/groovy/FieldExpression.java
    +++ b/common/src/main/java/org/apache/atlas/groovy/FieldExpression.java
    @@ -18,27 +18,38 @@

     package org.apache.atlas.groovy;

    +import java.util.Collections;
    +import java.util.List;
    +
     /**
      * Groovy expression that accesses a field in an object.
      */
    -public class FieldExpression extends AbstractGroovyExpression {
    +public class FieldExpression extends AbstractFunctionExpression {

    -    private GroovyExpression target;
         private String fieldName;

         public FieldExpression(GroovyExpression target, String fieldName)
{
    -        this.target = target;
    +        super(target);
             this.fieldName = fieldName;
         }

         @Override
         public void generateGroovy(GroovyGenerationContext context) {
    -
    -        target.generateGroovy(context);
    +        getCaller().generateGroovy(context);
             context.append(".'");

             context.append(fieldName);
             context.append("'");
         }

    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.singletonList(getCaller());
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 1;
    +        return new FieldExpression(newChildren.get(0), fieldName);
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/FunctionCallExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/FunctionCallExpression.java
b/common/src/main/java/org/apache/atlas/groovy/FunctionCallExpression.java
    index dd9b1d5..ad09e3f 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/FunctionCallExpression.java
    +++
b/common/src/main/java/org/apache/atlas/groovy/FunctionCallExpression.java
    @@ -20,41 +20,52 @@ package org.apache.atlas.groovy;

     import java.util.ArrayList;
     import java.util.Arrays;
    +import java.util.Collections;
     import java.util.Iterator;
     import java.util.List;

     /**
      * Groovy expression that calls a method on an object.
      */
    -public class FunctionCallExpression extends AbstractGroovyExpression {
    -
    -    // null for global functions
    -    private GroovyExpression target;
    +public class FunctionCallExpression extends AbstractFunctionExpression
{

         private String functionName;
         private List<GroovyExpression> arguments = new ArrayList<>();

    -    public FunctionCallExpression(String functionName, List<? extends
GroovyExpression> arguments) {
    -        this.target = null;
    +    public FunctionCallExpression(TraversalStepType type, String
functionName, GroovyExpression... arguments) {
    +        super(type, null);
             this.functionName = functionName;
    -        this.arguments.addAll(arguments);
    +        this.arguments.addAll(Arrays.asList(arguments));
         }

    -    public FunctionCallExpression(GroovyExpression target, String
functionName,
    -            List<? extends GroovyExpression> arguments) {
    -        this.target = target;
    +    public FunctionCallExpression(String functionName,
GroovyExpression... arguments) {
    +        super(null);
    +        this.functionName = functionName;
    +        this.arguments.addAll(Arrays.asList(arguments));
    +    }
    +
    +    public FunctionCallExpression(TraversalStepType type, String
functionName, List<GroovyExpression> arguments) {
    +        super(type, null);
             this.functionName = functionName;
             this.arguments.addAll(arguments);
         }

    -    public FunctionCallExpression(String functionName,
GroovyExpression... arguments) {
    -        this.target = null;
    +    public FunctionCallExpression(GroovyExpression target, String
functionName, GroovyExpression... arguments) {
    +        super(target);
             this.functionName = functionName;
             this.arguments.addAll(Arrays.asList(arguments));
         }

    -    public FunctionCallExpression(GroovyExpression target, String
functionName, GroovyExpression... arguments) {
    -        this.target = target;
    +    public FunctionCallExpression(TraversalStepType type,
GroovyExpression target, String functionName,
    +                                  List<? extends GroovyExpression>
arguments) {
    +        super(type, target);
    +        this.functionName = functionName;
    +        this.arguments.addAll(arguments);
    +    }
    +
    +    public FunctionCallExpression(TraversalStepType type,
GroovyExpression target, String functionName,
    +                                  GroovyExpression... arguments) {
    +        super(type, target);
             this.functionName = functionName;
             this.arguments.addAll(Arrays.asList(arguments));
         }
    @@ -63,11 +74,20 @@ public class FunctionCallExpression extends
AbstractGroovyExpression {
             arguments.add(expr);
         }

    +    public List<GroovyExpression> getArguments() {
    +        return Collections.unmodifiableList(arguments);
    +    }
    +
    +
    +    public String getFunctionName() {
    +        return functionName;
    +    }
    +
         @Override
         public void generateGroovy(GroovyGenerationContext context) {

    -        if (target != null) {
    -            target.generateGroovy(context);
    +        if (getCaller() != null) {
    +            getCaller().generateGroovy(context);
                 context.append(".");
             }
             context.append(functionName);
    @@ -77,10 +97,44 @@ public class FunctionCallExpression extends
AbstractGroovyExpression {
                 GroovyExpression expr = it.next();
                 expr.generateGroovy(context);
                 if (it.hasNext()) {
    -                context.append(", ");
    +                context.append(",");
                 }
             }
             context.append(")");
         }

    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        List<GroovyExpression> result = new ArrayList<>(arguments.size
() + 1);
    +        if (getCaller() != null) {
    +            result.add(getCaller());
    +        }
    +        result.addAll(arguments);
    +        return result;
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +
    +        if (getCaller() == null) {
    +            return new FunctionCallExpression(getType(), functionName,
newChildren);
    +        }
    +
    +        GroovyExpression newTarget = newChildren.get(0);
    +        List<GroovyExpression> args = null;
    +        if (newChildren.size() > 1) {
    +            args = newChildren.subList(1, newChildren.size());
    +        } else {
    +            args = Collections.emptyList();
    +        }
    +        return new FunctionCallExpression(getType(), newTarget,
functionName, args);
    +
    +    }
    +
    +    public void setArgument(int index, GroovyExpression value) {
    +        if (index < 0 || index >= arguments.size()) {
    +            throw new IllegalArgumentException("Invalid argIndex " +
index);
    +        }
    +        arguments.set(index, value);
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/GroovyExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/GroovyExpression.java
b/common/src/main/java/org/apache/atlas/groovy/GroovyExpression.java
    index 493bd3d..8399147 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/GroovyExpression.java
    +++
b/common/src/main/java/org/apache/atlas/groovy/GroovyExpression.java
    @@ -18,17 +18,55 @@

     package org.apache.atlas.groovy;

    +import java.util.List;
    +
     /**
      * Represents an expression in the Groovy programming language, which
      * is the language that Gremlin scripts are written and interpreted
in.
      */
     public interface GroovyExpression  {
    -
         /**
    -     * Generates a groovy script from the expression.
    +     * Generates a Groovy script from the expression.
          *
          * @param context
          */
         void generateGroovy(GroovyGenerationContext context);

    +    /**
    +     * Gets all of the child expressions of this expression.
    +     * s
    +     * @return
    +     */
    +    List<GroovyExpression> getChildren();
    +
    +    /**
    +     * Makes a copy of the expression, keeping everything the
    +     * same except its child expressions.  These are replaced
    +     * with the provided children.  The order of the children
    +     * is important.  It is expected that the children provided
    +     * here are updated versions of the children returned by
    +     * getChildren().  The order of the children must be the
    +     * same as the order in which the children were returned
    +     * by getChildren()
    +     *
    +     * @param newChildren
    +     * @return
    +     */
    +    GroovyExpression copy(List<GroovyExpression> newChildren);
    +
    +    /**
    +     * Makes a shallow copy of the GroovyExpression.  This
    +     * is equivalent to copy(getChildren());
    +     *
    +     * @return
    +     */
    +    GroovyExpression copy();
    +
    +    /**
    +     * Gets the type of traversal step represented by this
    +     * expression (or TraversalStepType.NONE if it is not part of a
graph traversal).
    +     *
    +     * @return
    +     */
    +    TraversalStepType getType();
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/IdentifierExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/IdentifierExpression.java
b/common/src/main/java/org/apache/atlas/groovy/IdentifierExpression.java
    index 6abdbf0..4c0694a 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/IdentifierExpression.java
    +++
b/common/src/main/java/org/apache/atlas/groovy/IdentifierExpression.java
    @@ -18,18 +18,28 @@

     package org.apache.atlas.groovy;

    +import java.util.Collections;
    +import java.util.List;
    +
     /**
      * Groovy expression that references the variable with the given name.
      *
      */
     public class IdentifierExpression extends AbstractGroovyExpression {

    +    private TraversalStepType type = TraversalStepType.NONE;
         private String varName;

         public IdentifierExpression(String varName) {
             this.varName = varName;
         }

    +    public IdentifierExpression(TraversalStepType type, String
varName) {
    +        this.varName = varName;
    +        this.type = type;
    +    }
    +
    +
         public String getVariableName() {
             return varName;
         }
    @@ -39,4 +49,25 @@ public class IdentifierExpression extends
AbstractGroovyExpression {
             context.append(varName);
         }

    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.emptyList();
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.isEmpty();
    +        IdentifierExpression result =  new IdentifierExpression
(varName);
    +        result.setType(type);
    +        return result;
    +    }
    +
    +    public void setType(TraversalStepType type) {
    +        this.type = type;
    +    }
    +
    +    @Override
    +    public TraversalStepType getType() {
    +        return type;
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/LabeledExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/LabeledExpression.java
b/common/src/main/java/org/apache/atlas/groovy/LabeledExpression.java
    new file mode 100644
    index 0000000..a993410
    --- /dev/null
    +++
b/common/src/main/java/org/apache/atlas/groovy/LabeledExpression.java
    @@ -0,0 +1,54 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.atlas.groovy;
    +
    +import java.util.Collections;
    +import java.util.List;
    +
    +/**
    + * Represents a Groovy expression that has a label.
    + */
    +public class LabeledExpression extends AbstractGroovyExpression {
    +
    +    private String label;
    +    private GroovyExpression expr;
    +
    +    public LabeledExpression(String label, GroovyExpression expr) {
    +        this.label = label;
    +        this.expr = expr;
    +    }
    +
    +    @Override
    +    public void generateGroovy(GroovyGenerationContext context) {
    +        context.append(label);
    +        context.append(":");
    +        expr.generateGroovy(context);
    +    }
    +
    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.singletonList(expr);
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 1;
    +        return new LabeledExpression(label, newChildren.get(0));
    +    }
    +}


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/ListExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/ListExpression.java
b/common/src/main/java/org/apache/atlas/groovy/ListExpression.java
    index f7acaac..7969426 100644
    --- a/common/src/main/java/org/apache/atlas/groovy/ListExpression.java
    +++ b/common/src/main/java/org/apache/atlas/groovy/ListExpression.java
    @@ -20,6 +20,7 @@ package org.apache.atlas.groovy;

     import java.util.ArrayList;
     import java.util.Arrays;
    +import java.util.Collections;
     import java.util.Iterator;
     import java.util.List;

    @@ -57,4 +58,15 @@ public class ListExpression extends
AbstractGroovyExpression {
             context.append("]");
         }

    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.unmodifiableList(values);
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        return new ListExpression(newChildren);
    +    }
    +
    +
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/LiteralExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/LiteralExpression.java
b/common/src/main/java/org/apache/atlas/groovy/LiteralExpression.java
    index 008c885..1407499 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/LiteralExpression.java
    +++
b/common/src/main/java/org/apache/atlas/groovy/LiteralExpression.java
    @@ -18,13 +18,15 @@

     package org.apache.atlas.groovy;

    +import java.util.Collections;
    +import java.util.List;
     import java.util.regex.Matcher;
     import java.util.regex.Pattern;

     /**
      * Represents a literal value.
      */
    -public class LiteralExpression implements GroovyExpression {
    +public class LiteralExpression extends AbstractGroovyExpression {

         public static final LiteralExpression TRUE = new LiteralExpression
(true);
         public static final LiteralExpression FALSE = new
LiteralExpression(false);
    @@ -40,6 +42,12 @@ public class LiteralExpression implements
GroovyExpression {
             this.addTypeSuffix = addTypeSuffix;
         }

    +    public LiteralExpression(Object value, boolean addTypeSuffix,
boolean translateToParameter) {
    +        this.value = value;
    +        this.translateToParameter = translateToParameter;
    +        this.addTypeSuffix = addTypeSuffix;
    +    }
    +
         public LiteralExpression(Object value) {
             this.value = value;
             this.translateToParameter = value instanceof String;
    @@ -86,6 +94,10 @@ public class LiteralExpression implements
GroovyExpression {

         }

    +    public Object getValue() {
    +        return value;
    +    }
    +
         private String getEscapedValue() {
             String escapedValue = (String)value;
             escapedValue = escapedValue.replaceAll(Pattern.quote("\\"),
Matcher.quoteReplacement("\\\\"));
    @@ -96,4 +108,15 @@ public class LiteralExpression implements
GroovyExpression {
         public void setTranslateToParameter(boolean translateToParameter)
{
             this.translateToParameter = translateToParameter;
         }
    +
    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.emptyList();
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 0;
    +        return new LiteralExpression(value, addTypeSuffix,
translateToParameter);
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/LogicalExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/LogicalExpression.java
b/common/src/main/java/org/apache/atlas/groovy/LogicalExpression.java
    index ee5829b..68e6847 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/LogicalExpression.java
    +++
b/common/src/main/java/org/apache/atlas/groovy/LogicalExpression.java
    @@ -17,6 +17,8 @@
      */
     package org.apache.atlas.groovy;

    +import java.util.List;
    +
     /**
      * Represents a logical (and/or) expression.
      *
    @@ -43,4 +45,14 @@ public class LogicalExpression extends
BinaryExpression {
         public LogicalExpression(GroovyExpression left, LogicalOperator
op, GroovyExpression right) {
             super(left, op.getGroovyValue(), right);
         }
    +
    +    private LogicalExpression(GroovyExpression left, String op,
GroovyExpression right) {
    +        super(left, op, right);
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 2;
    +        return new LogicalExpression(newChildren.get(0), op,
newChildren.get(1));
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/RangeExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/RangeExpression.java
b/common/src/main/java/org/apache/atlas/groovy/RangeExpression.java
    index 7322f69..977adb6 100644
    --- a/common/src/main/java/org/apache/atlas/groovy/RangeExpression.java
    +++ b/common/src/main/java/org/apache/atlas/groovy/RangeExpression.java
    @@ -18,28 +18,68 @@

     package org.apache.atlas.groovy;

    +import java.util.Collections;
    +import java.util.List;
    +
     /**
      * Represents an "exclusive" range expression, e.g. [0..&lt;10].
      */
    -public class RangeExpression extends AbstractGroovyExpression {
    +public class RangeExpression extends AbstractFunctionExpression {

    -    private GroovyExpression parent;
    -    private int offset;
    -    private int count;
    +    private TraversalStepType stepType;
    +    private int startIndex;
    +    private int endIndex;

    -    public RangeExpression(GroovyExpression parent, int offset, int
count) {
    -        this.parent = parent;
    -        this.offset = offset;
    -        this.count = count;
    +    public RangeExpression(TraversalStepType stepType,
GroovyExpression parent, int offset, int count) {
    +        super(parent);
    +        this.startIndex = offset;
    +        this.endIndex = count;
    +        this.stepType = stepType;
         }

         @Override
         public void generateGroovy(GroovyGenerationContext context) {
    -        parent.generateGroovy(context);
    +        getCaller().generateGroovy(context);
             context.append(" [");
    -        new LiteralExpression(offset).generateGroovy(context);
    +        new LiteralExpression(startIndex).generateGroovy(context);
             context.append("..<");
    -        new LiteralExpression(count).generateGroovy(context);
    +        new LiteralExpression(endIndex).generateGroovy(context);
             context.append("]");
         }
    +
    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.singletonList(getCaller());
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 1;
    +        return new RangeExpression(stepType, newChildren.get(0),
startIndex, endIndex);
    +    }
    +
    +    @Override
    +    public TraversalStepType getType() {
    +        return stepType;
    +    }
    +
    +    public int getStartIndex() {
    +
    +        return startIndex;
    +    }
    +
    +    public void setStartIndex(int startIndex) {
    +
    +        this.startIndex = startIndex;
    +    }
    +
    +    public int getEndIndex() {
    +
    +        return endIndex;
    +    }
    +
    +    public void setEndIndex(int endIndex) {
    +
    +        this.endIndex = endIndex;
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/StatementListExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/StatementListExpression.java
b/common/src/main/java/org/apache/atlas/groovy/StatementListExpression.java
    new file mode 100644
    index 0000000..f9c88ec
    --- /dev/null
    +++
b/common/src/main/java/org/apache/atlas/groovy/StatementListExpression.java
    @@ -0,0 +1,98 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.atlas.groovy;
    +
    +import java.util.ArrayList;
    +import java.util.Collections;
    +import java.util.Iterator;
    +import java.util.List;
    +
    +/**
    + * Represents a semi-colon delimited list of Groovy expressions.
    + */
    +public class StatementListExpression extends AbstractGroovyExpression
{
    +
    +    private List<GroovyExpression> stmts = new ArrayList<>();
    +
    +    public StatementListExpression() {
    +
    +    }
    +
    +    /**
    +     * @param newChildren
    +     */
    +    public StatementListExpression(List<GroovyExpression> newChildren)
{
    +        stmts.addAll(newChildren);
    +    }
    +
    +    public void addStatement(GroovyExpression expr) {
    +        if (expr instanceof StatementListExpression) {
    +            stmts.addAll(((StatementListExpression)expr).getStatements
());
    +        } else {
    +            stmts.add(expr);
    +        }
    +    }
    +
    +    public void addStatements(List<GroovyExpression> exprs) {
    +        for(GroovyExpression expr : exprs) {
    +            addStatement(expr);
    +        }
    +    }
    +
    +    @Override
    +    public void generateGroovy(GroovyGenerationContext context) {
    +
    +        Iterator<GroovyExpression> stmtIt = stmts.iterator();
    +        while(stmtIt.hasNext()) {
    +            GroovyExpression stmt = stmtIt.next();
    +            stmt.generateGroovy(context);
    +            if (stmtIt.hasNext()) {
    +                context.append(";");
    +            }
    +        }
    +    }
    +
    +
    +    public List<GroovyExpression> getStatements() {
    +        return stmts;
    +    }
    +
    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.unmodifiableList(stmts);
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        return new StatementListExpression(newChildren);
    +    }
    +
    +    @Override
    +    public TraversalStepType getType() {
    +        return TraversalStepType.NONE;
    +    }
    +
    +    /**
    +     * @param oldExpr
    +     * @param newExpr
    +     */
    +    public void replaceStatement(int index, GroovyExpression newExpr)
{
    +        stmts.set(index, newExpr);
    +    }
    +}


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/TernaryOperatorExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/TernaryOperatorExpression.java

b/common/src/main/java/org/apache/atlas/groovy/TernaryOperatorExpression.java

    index 75a2f86..8835dd2 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/TernaryOperatorExpression.java

    +++
b/common/src/main/java/org/apache/atlas/groovy/TernaryOperatorExpression.java

    @@ -18,6 +18,9 @@

     package org.apache.atlas.groovy;

    +import java.util.Arrays;
    +import java.util.List;
    +
     /**
      * Groovy expression that represents the ternary operator (expr ?
trueValue :
      * falseValue)
    @@ -29,7 +32,7 @@ public class TernaryOperatorExpression extends
AbstractGroovyExpression {
         private GroovyExpression falseValue;

         public TernaryOperatorExpression(GroovyExpression booleanExpr,
GroovyExpression trueValue,
    -            GroovyExpression falseValue) {
    +                                     GroovyExpression falseValue) {

             this.booleanExpr = booleanExpr;
             this.trueValue = trueValue;
    @@ -41,9 +44,9 @@ public class TernaryOperatorExpression extends
AbstractGroovyExpression {

             context.append("((");
             booleanExpr.generateGroovy(context);
    -        context.append(") ? (");
    +        context.append(")?(");
             trueValue.generateGroovy(context);
    -        context.append(") : (");
    +        context.append("):(");
             falseValue.generateGroovy(context);
             context.append("))");
         }
    @@ -53,4 +56,20 @@ public class TernaryOperatorExpression extends
AbstractGroovyExpression {
             generateGroovy(context);
             return context.getQuery();
         }
    +
    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Arrays.asList(booleanExpr, trueValue, falseValue);
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 3;
    +        return new TernaryOperatorExpression(newChildren.get(0),
newChildren.get(1), newChildren.get(2));
    +    }
    +
    +    @Override
    +    public TraversalStepType getType() {
    +        return trueValue.getType();
    +    }
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/TraversalStepType.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/TraversalStepType.java
b/common/src/main/java/org/apache/atlas/groovy/TraversalStepType.java
    new file mode 100644
    index 0000000..fde8814
    --- /dev/null
    +++
b/common/src/main/java/org/apache/atlas/groovy/TraversalStepType.java
    @@ -0,0 +1,121 @@
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +package org.apache.atlas.groovy;
    +
    +/**
    + * Types of graph traversal steps.  These are based on the traversal
steps
    + * described in the TinkerPop documentation at
    + *
http://tinkerpop.apache.org/docs/current/reference/#graph-traversal-steps.
    + */
    +public enum TraversalStepType {
    +    /**
    +     * Indicates that the expression is not part of a graph traversal.
    +     */
    +    NONE,
    +
    +    /**
    +     * Indicates that the expression is a
    +     * {@link
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource}.

    +     * This is not technically a graph traversal step.  This is the
expression the traversal is started from ("g").
    +     */
    +    SOURCE,
    +
    +    /**
    +     * A Start step adds vertices or edges to the traversal.  These
include "V", "E", and "inject".
    +     */
    +    START,
    +
    +    /**
    +     * An End step causes the traversal to be executed.  This includes
steps such as "toList", "toSet", and "fill"
    +     */
    +    END,
    +
    +    /**
    +     * Map steps map the current traverser value to exactly one new
value.  These
    +     * steps include "map" and "select".  Here, we make a further
distinction
    +     * based on the type of expression that things are being mapped
to.
    +     * <p>
    +     * MAP_TO_ELEMENT indicates that the traverser value is being
mapped
    +     * to either a Vertex or an Edge.
    +     */
    +    MAP_TO_ELEMENT,
    +    /**
    +     * Map steps map the current traverser value to exactly one new
value.  These
    +     * steps include "map" and "select".  Here, we make a further
distinction
    +     * based on the type of expression that things are being mapped
to.
    +     * <p>
    +     * MAP_TO_VALUE indicates that the traverser value is being mapped
    +     * to something that is not a Vertex or an Edge.
    +     */
    +    MAP_TO_VALUE,
    +
    +    /**
    +     * FlatMap steps map the current value of the traverser to an
iterator of objects that
    +     * are streamed to the next step.  These are steps like "in,
"out", "inE", and
    +     * so forth which map the current value of the traverser from some
vertex or edge
    +     * to some other set of vertices or edges that is derived from the
original set based
    +     * on the structure of the graph.  This also includes "values",
which maps a vertex or
    +     * edge to the set of values for a given property. Here, we make a
further distinction
    +     * based on the type of expression that things are being mapped
to.
    +     * <p>
    +     *  FLAT_MAP_TO_ELEMENTS indicates that the traverser value is
being mapped
    +     * to something that is a Vertex or an Edge (in, out, outE fall in
this category).
    +     */
    +    FLAT_MAP_TO_ELEMENTS,
    +
    +    /**
    +     * FlatMap steps map the current value of the traverser to an
iterator of objects that
    +     * are streamed to the next step.  These are steps like "in,
"out", "inE", and
    +     * so forth which map the current value of the traverser from some
vertex or edge
    +     * to some other set of vertices or edges that is derived from the
original set based
    +     * on the structure of the graph.  This also includes "values",
which maps a vertex or
    +     * edge to the set of values for a given property. Here, we make a
further distinction
    +     * based on the type of expression that things are being mapped
to.
    +     * <p>
    +     *  FLAT_MAP_TO_VALUES indicates that the traverser value is being
mapped
    +     * to something that not is a Vertex or an Edge (values falls in
this category).
    +     */
    +    FLAT_MAP_TO_VALUES,
    +
    +    /**
    +     * Filter steps filter things out of the traversal.  These include
"has", "where",
    +     * "and", "or", and "filter".
    +     */
    +    FILTER,
    +
    +    /**
    +     * Side effect steps do not affect the traverser value, but do
something
    +     * that affects the state of the traverser.  These include things
such as
    +     * "enablePath()", "as", and "by".
    +     */
    +    SIDE_EFFECT,
    +
    +    /**
    +     * Branch steps split the traverser, for example, "repeat",
"branch", "choose", and "union".
    +     */
    +    BRANCH,
    +
    +    /**
    +     * Barrier steps in Gremlin force everything before them to be
executed
    +     * before moving on to the steps after them.  We also use this to
indicate
    +     * steps that need to do some aggregation or processing that
requires the
    +     * full query result to be present in order for the step to work
correctly.
    +     * This includes "range", "group", and "order", and "cap"
    +     */
    +    BARRIER,
    +}


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/TypeCoersionExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/TypeCoersionExpression.java
b/common/src/main/java/org/apache/atlas/groovy/TypeCoersionExpression.java
    index 4a61052..956dafa 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/TypeCoersionExpression.java
    +++
b/common/src/main/java/org/apache/atlas/groovy/TypeCoersionExpression.java
    @@ -18,6 +18,9 @@

     package org.apache.atlas.groovy;

    +import java.util.Collections;
    +import java.util.List;
    +
     /**
      * Groovy expression that represents a type coersion (e.g obj as Set).
      */
    @@ -28,17 +31,29 @@ public class TypeCoersionExpression extends
AbstractGroovyExpression {

         public TypeCoersionExpression(GroovyExpression expr, String
className) {
             this.expr = expr;
    -        this.className  =className;
    +        this.className  = className;
         }

         @Override
         public void generateGroovy(GroovyGenerationContext context) {

    -        context.append("(");
    +        context.append("((");
             expr.generateGroovy(context);
             context.append(")");
             context.append(" as ");
             context.append(className);
    +        context.append(")");
    +    }
    +
    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.singletonList(expr);
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 1;
    +        return new TypeCoersionExpression(newChildren.get(0),
className);
         }

     }

    http://gi
t-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/common/src/main/java/org/apache/atlas/groovy/VariableAssignmentExpression.java

    ----------------------------------------------------------------------
    diff --git
a/common/src/main/java/org/apache/atlas/groovy/VariableAssignmentExpression.java

b/common/src/main/java/org/apache/atlas/groovy/VariableAssignmentExpression.java

    index 7e018f1..1aa7443 100644
    ---
a/common/src/main/java/org/apache/atlas/groovy/VariableAssignmentExpression.java

    +++
b/common/src/main/java/org/apache/atlas/groovy/VariableAssignmentExpression.java

    @@ -18,6 +18,9 @@

     package org.apache.atlas.groovy;

    +import java.util.Collections;
    +import java.util.List;
    +
     /**
      * Groovy statement that assigns a value to a variable.
      */
    @@ -50,9 +53,20 @@ public class VariableAssignmentExpression extends
AbstractGroovyExpression {
                 context.append(" ");
             }
             context.append(name);
    -        context.append(" = ");
    +        context.append("=");
             value.generateGroovy(context);

         }

    +    @Override
    +    public List<GroovyExpression> getChildren() {
    +        return Collections.singletonList(value);
    +    }
    +
    +    @Override
    +    public GroovyExpression copy(List<GroovyExpression> newChildren) {
    +        assert newChildren.size() == 1;
    +        return new VariableAssignmentExpression(name, newChildren.get
(0));
    +    }
    +
     }


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/distro/src/conf/atlas-application.properties

    ----------------------------------------------------------------------
    diff --git a/distro/src/conf/atlas-application.properties
b/distro/src/conf/atlas-application.properties
    index d9e2f6e..3e71a26 100755
    --- a/distro/src/conf/atlas-application.properties
    +++ b/distro/src/conf/atlas-application.properties
    @@ -29,6 +29,13 @@ atlas.graph.storage.hbase.table=apache_atlas_titan

     ${titan.storage.properties}

    +# Gremlin Query Optimizer
    +#
    +# Enables rewriting gremlin queries to maximize performance. This flag
is provided as
    +# a possible way to work around any defects that are found in the
optimizer until they
    +# are resolved.
    +#atlas.query.gremlinOptimizerEnabled=true
    +
     # Delete handler
     #
     # This allows the default behavior of doing "soft" deletes to be
changed.


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/graphdb/titan0/pom.xml

    ----------------------------------------------------------------------
    diff --git a/graphdb/titan0/pom.xml b/graphdb/titan0/pom.xml
    index 58a5cb8..9d88a72 100644
    --- a/graphdb/titan0/pom.xml
    +++ b/graphdb/titan0/pom.xml
    @@ -34,6 +34,7 @@
         <properties>
             <tinkerpop.version>2.6.0</tinkerpop.version>
             <titan.version>0.5.4</titan.version>
    +	<guava.version>14.0</guava.version>
         </properties>

         <dependencies>
    @@ -53,6 +54,13 @@
             </dependency>

             <dependency>
    +            <groupId>com.google.guava</groupId>
    +            <artifactId>guava</artifactId>
    +            <version>${guava.version}</version>
    +        </dependency>
    +
    +
    +        <dependency>
                 <groupId>com.google.inject</groupId>
                 <artifactId>guice</artifactId>
                 <scope>provided</scope>


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/intg/pom.xml

    ----------------------------------------------------------------------
    diff --git a/intg/pom.xml b/intg/pom.xml
    index 52b5ef5..a5fab71 100644
    --- a/intg/pom.xml
    +++ b/intg/pom.xml
    @@ -60,7 +60,6 @@
             <dependency>
                 <groupId>com.google.guava</groupId>
                 <artifactId>guava</artifactId>
    -            <version>${guava.version}</version>
             </dependency>

             <dependency>


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/pom.xml

    ----------------------------------------------------------------------
    diff --git a/pom.xml b/pom.xml
    index a985792..834ecae 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -459,7 +459,7 @@

<spring.security.version>3.1.3.RELEASE</spring.security.version>

<spring-ldap-core.version>1.3.1.RELEASE</spring-ldap-core.version>
             <javax.servlet.version>3.1.0</javax.servlet.version>
    -        <guava.version>18.0</guava.version>
    +        <guava.version>19.0</guava.version>

             <!-- Needed for hooks -->
             <aopalliance.version>1.0</aopalliance.version>
    @@ -633,6 +633,12 @@

         <dependencyManagement>
             <dependencies>
    +
    +            <dependency>
    +                <groupId>com.google.guava</groupId>
    +                <artifactId>guava</artifactId>
    +                <version>${guava.version}</version>
    +            </dependency>
                 <!-- AOP dependencies. -->
                 <dependency>
                     <groupId>org.aspectj</groupId>


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/release-log.txt

    ----------------------------------------------------------------------
    diff --git a/release-log.txt b/release-log.txt
    index fa22e6d..b0fc288 100644
    --- a/release-log.txt
    +++ b/release-log.txt
    @@ -9,8 +9,9 @@ ATLAS-1060 Add composite indexes for exact match
performance improvements for al
     ATLAS-1127 Modify creation and modification timestamps to Date instead
of Long(sumasai)

     ALL CHANGES:
    -ATLAS-1513: updated AtlasEntityType with methods to get foreign-key
references; added helper methods in AtlasAttribute (mneethiraj via
kevalbhatt)
    -ATLAS-1502: added configuration to restrict entity-types editable via
UI (Kalyanikashikar via mneethiraj)
    +ATLAS-1369 Optimize Gremlin queries generated by DSL translator
(jnhagelb)
    +ATLAS-1513 updated AtlasEntityType with methods to get foreign-key
references; added helper methods in AtlasAttribute (mneethiraj via
kevalbhatt)
    +ATLAS-1502 added configuration to restrict entity-types editable via
UI (Kalyanikashikar via mneethiraj)
     ATLAS-1507 fixed incorrect relationship specified in hive-model
     ATLAS-1506 updated AtlasObjectId to support unqiueAttributes to
identity the object
     ATLAS-1378 Use .gitignore so git does not see binary files as changed
(david_radley via dkantor)


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/repository/src/main/java/org/apache/atlas/discovery/DataSetLineageService.java

    ----------------------------------------------------------------------
    diff --git
a/repository/src/main/java/org/apache/atlas/discovery/DataSetLineageService.java

b/repository/src/main/java/org/apache/atlas/discovery/DataSetLineageService.java

    index 4db4773..8fb9ddd 100644
    ---
a/repository/src/main/java/org/apache/atlas/discovery/DataSetLineageService.java

    +++
b/repository/src/main/java/org/apache/atlas/discovery/DataSetLineageService.java

    @@ -25,6 +25,7 @@ import org.apache.atlas.AtlasException;
     import org.apache.atlas.GraphTransaction;
     import
org.apache.atlas.discovery.graph.DefaultGraphPersistenceStrategy;
     import org.apache.atlas.discovery.graph.GraphBackedDiscoveryService;
    +import org.apache.atlas.query.GremlinQueryResult;
     import org.apache.atlas.query.InputLineageClosureQuery;
     import org.apache.atlas.query.OutputLineageClosureQuery;
     import org.apache.atlas.query.QueryParams;
    @@ -139,7 +140,8 @@ public class DataSetLineageService implements
LineageService {
                     guid, HIVE_PROCESS_TYPE_NAME,
                     HIVE_PROCESS_INPUT_ATTRIBUTE_NAME,
HIVE_PROCESS_OUTPUT_ATTRIBUTE_NAME, Option.empty(),
                     SELECT_ATTRIBUTES, true, graphPersistenceStrategy,
graph);
    -        return inputsQuery.graph(null).toInstanceJson();
    +        GremlinQueryResult result = inputsQuery.evaluate();
    +        return inputsQuery.graph(result).toInstanceJson();
         }

         @Override
    @@ -156,7 +158,8 @@ public class DataSetLineageService implements
LineageService {
                     new OutputLineageClosureQuery
(AtlasClient.DATA_SET_SUPER_TYPE, SELECT_INSTANCE_GUID, guid,
HIVE_PROCESS_TYPE_NAME,
                             HIVE_PROCESS_INPUT_ATTRIBUTE_NAME,
HIVE_PROCESS_OUTPUT_ATTRIBUTE_NAME, Option.empty(),
                             SELECT_ATTRIBUTES, true,
graphPersistenceStrategy, graph);
    -        return outputsQuery.graph(null).toInstanceJson();
    +        GremlinQueryResult result = outputsQuery.evaluate();
    +        return outputsQuery.graph(result).toInstanceJson();
         }

         /**


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa74c73d/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java

    ----------------------------------------------------------------------
    diff --git
a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java

b/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java

    index 1858739..798d909 100644
    ---
a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java

    +++
b/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java

    @@ -18,7 +18,12 @@

     package org.apache.atlas.gremlin;

    +import java.util.ArrayList;
    +import java.util.Collections;
    +import java.util.List;
    +
     import org.apache.atlas.AtlasException;
    +import org.apache.atlas.groovy.AbstractFunctionExpression;
     import org.apache.atlas.groovy.CastExpression;
     import org.apache.atlas.groovy.ClosureExpression;
     import org.apache.atlas.groovy.ComparisonExpression;
    @@ -34,13 +39,11 @@ import org.apache.atlas.groovy.LogicalExpression;
     import org.apache.atlas.groovy.LogicalExpression.LogicalOperator;
     import org.apache.atlas.groovy.RangeExpression;
     import org.apache.atlas.groovy.TernaryOperatorExpression;
    +import org.apache.atlas.groovy.TraversalStepType;
     import org.apache.atlas.query.GraphPersistenceStrategies;
     import org.apache.atlas.query.TypeUtils.FieldInfo;
     import org.apache.atlas.typesystem.types.IDataType;

    -import java.util.ArrayList;
    -import java.util.List;
    -

     /**
      * Generates gremlin query expressions using Gremlin 2 syntax.
    @@ -54,12 +57,11 @@ public class Gremlin2ExpressionFactory extends
GremlinExpressionFactory {
         private static final String PATH_FIELD = "path";
         private static final String ENABLE_PATH_METHOD = "enablePath";
         private static final String BACK_METHOD = "back";
    -    private static final String VERTEX_LIST_CLASS = "List<Vertex>";
    -    private static final String VERTEX_ARRAY_CLASS = "Vertex[]";
         private static final String LAST_METHOD = "last";
    +
         @Override
         public GroovyExpression generateLogicalExpression(GroovyExpression
parent, String operator, List<GroovyExpression> operands) {
    -        return new FunctionCallExpression(parent, operator, operands);
    +        return new FunctionCallExpression(TraversalStepType.FILTER,
parent, operator, operands);
         }


    @@ -72,7 +74,7 @@ public class Gremlin2ExpressionFactory extends
GremlinExpressionFactory {
                 return parent;
             }
             else {
    -            return new FunctionCallExpression(parent, BACK_METHOD, new
LiteralExpression(alias));
    +            return new FunctionCallExpression
(TraversalStepType.MAP_TO_ELEMENT, parent, BACK_METHOD, new
LiteralExpression(alias));
             }
         }

    @@ -100,23 +102,23 @@ public class Gremlin2ExpressionFactory extends
GremlinExpressionFactory {
                 whileFunction = new ClosureExpression(new
TernaryOperatorExpression(pathContainsExpr, LiteralExpression.FALSE,
LiteralExpression.TRUE));
             }
             GroovyExpression emitFunction = new ClosureExpression
(emitExpr);
    -        GroovyExpression loopCall = new FunctionCallExpression
(loopExpr, LOOP_METHOD, new LiteralExpression(alias), whileFunction,
emitFunction);
    +        GroovyExpression loopCall = new FunctionCallExpression
(TraversalStepType.BRANCH, loopExpr, LOOP_METHOD, new LiteralExpression
(alias), whileFunction, emitFunction);

    -        return new FunctionCallExpression(loopCall,
ENABLE_PATH_METHOD);
    +        return new FunctionCallExpression
(TraversalStepType.SIDE_EFFECT, loopCall, ENABLE_PATH_METHOD);
         }

         @Override
         public GroovyExpression typeTestExpression
(GraphPersistenceStrategies s, String typeName, GroovyExpression itRef) {

    -        GroovyExpression typeAttrExpr = new FieldExpression(itRef,
s.typeAttributeName());
             GroovyExpression superTypeAttrExpr = new FieldExpression
(itRef, s.superTypeAttributeName());
             GroovyExpression typeNameExpr = new LiteralExpression
(typeName);
    -
    -        GroovyExpression typeMatchesExpr = new ComparisonExpression
(typeAttrExpr, ComparisonOperator.EQUALS, typeNameExpr);
             GroovyExpression isSuperTypeExpr = new FunctionCallExpression
(superTypeAttrExpr, CONTAINS, typeNameExpr);
             GroovyExpression superTypeMatchesExpr = new
TernaryOperatorExpression(superTypeAttrExpr, isSuperTypeExpr,
LiteralExpression.FALSE);

    +        GroovyExpression typeAttrExpr = new FieldExpression(itRef,
s.typeAttributeName());
    +        GroovyExpression typeMatchesExpr = new ComparisonExpression
(typeAttrExpr, ComparisonOperator.EQUALS, typeNameExpr);
             return new LogicalExpression(typeMatchesExpr,
LogicalOperator.OR, superTypeMatchesExpr);
    +
         }

         @Override
    @@ -129,7 +131,7 @@ public class Gremlin2ExpressionFactory extends
GremlinExpressionFactory {
             for(GroovyExpression expr : srcExprs) {
                 selectArgs.add(new ClosureExpression(expr));
             }
    -        return new FunctionCallExpression(parent, SELECT_METHOD,
selectArgs);
    +        return new FunctionCallExpression
(TraversalStepType.MAP_TO_VALUE, parent, SELECT_METHOD, selectArgs);
         }

         @Override
    @@ -142,7 +144,7 @@ public class Gremlin2ExpressionFactory extends
GremlinExpressionFactory {
                 GroovyExpression requiredValue, FieldInfo fInfo) throws
AtlasException {
             GroovyExpression op = gremlin2CompOp(symbol);
             GroovyExpression propertyNameExpr = new LiteralExpression
(propertyName);
    -        return new FunctionCallExpression(parent, HAS_METHOD,
propertyNameExpr, op, requiredValue);
    +        return new FunctionCallExpression(TraversalStepType.FILTER,
parent, HAS_METHOD, propertyNameExpr, op, requiredValue);
         }

         private GroovyExpression gremlin2CompOp(String op) throws
AtlasException {
    @@ -173,13 +175,52 @@ public class Gremlin2ExpressionFactory extends
GremlinExpressionFactory {
         }

         @Override
    -    protected GroovyExpression initialExpression
(GraphPersistenceStrategies s, GroovyExpression varExpr) {
    -        return new FunctionCallExpression(varExpr, "_");
    +    protected GroovyExpression initialExpression(GroovyExpression
varExpr, GraphPersistenceStrategies s) {
    +        return generateSeededTraversalExpresssion(false, varExpr);
    +    }
    +
    +    @Override
    +    public GroovyExpression generateSeededTraversalExpresssion(boolean
isMap, GroovyExpression varExpr) {
    +        return new FunctionCallExpression(TraversalStepType.START,
varExpr, "_");
         }

         @Override
    -    public GroovyExpression generateLimitExpression(GroovyExpression
parent, int offset, int totalRows) {
    -        return new RangeExpression(parent, offset, totalRows);
    +    public GroovyExpression generateRangeExpression(GroovyExpression
parent, int startIndex, int endIndex) {
    +        //treat as barrier step, since limits need to be applied
globally (even though it
    +        //is technically a filter step)
    +        return new RangeExpression(TraversalStepType.BARRIER, parent,
startIndex, endIndex);
    +    }
    +
    +    @Override
    +    public boolean isRangeExpression(GroovyExpression expr) {
    +
    +        return (expr instanceof RangeExpression);
    +    }
    +
    +    @Override
    +    public int[] getRangeParameters(AbstractFunctionExpression expr) {
    +
    +        if (isRangeExpression(expr)) {
    +            RangeExpression rangeExpression = (RangeExpression) expr;
    +            return new int[] {rangeExpression.getStartIndex(),
rangeExpression.getEndIndex()};
    +        }
    +        else {
    +            return null;
    +        }
    +    }
    +
    +    @Override
    +    public void setRangeParameters(GroovyExpression expr, int
startIndex, int endIndex) {
    +
    +        if (isRangeExpression(expr)) {
    +            RangeExpression rangeExpression = (RangeExpression) expr;
    +            rangeExpression.setStartIndex(startIndex);
    +            rangeExpression.setEndIndex(endIndex);
    +        }
    +        else {
    +            throw new IllegalArgumentException(expr.getClass().getName
() + " is not a valid range expression - must be an instance of " +
RangeExpression.class.getName());
    +        }
    +
         }

         @Override
    @@ -195,7 +236,7 @@ public class Gremlin2ExpressionFactory extends
GremlinExpressionFactory {

         @Override
         public GroovyExpression generateOrderByExpression(GroovyExpression
parent, List<GroovyExpression> translatedOrderBy, boolean isAscending) {
    -        GroovyExpression itExpr = getItVariable();
    +
             GroovyExpression aPropertyExpr = translatedOrderBy.get(0);
             GroovyExpression bPropertyExpr = translatedOrderBy.get(1);

    @@ -212,27 +253,28 @@ public class Gremlin2ExpressionFactory extends
GremlinExpressionFactory {
             else {
                 comparisonFunction = new ComparisonOperatorExpression
(bCondition,  aCondition);
             }
    -        return new FunctionCallExpression(parent, ORDER_METHOD, new
ClosureExpression(comparisonFunction));
    +        return new FunctionCallExpression(TraversalStepType.BARRIER,
parent, ORDER_METHOD, new ClosureExpression(comparisonFunction));
         }

    +
         @Override
         public GroovyExpression getAnonymousTraversalExpression() {
    -        return new FunctionCallExpression("_");
    +        return new FunctionCallExpression(TraversalStepType.START,
"_");
         }

    +
    +
         @Override
         public GroovyExpression generateGroupByExpression(GroovyExpression
parent, GroovyExpression groupByExpression,
    -            GroovyExpression aggregationFunction) {
    -
    +                                                      GroovyExpression
aggregationFunction) {
                 GroovyExpression groupByClosureExpr = new
ClosureExpression(groupByExpression);
                 GroovyExpression itClosure = new ClosureExpression
(getItVariable());
    -            GroovyExpression result = new FunctionCallExpression
(parent, "groupBy", groupByClosureExpr, itClosure);
    -            result = new FunctionCallExpression(result, "cap");
    -            result = new FunctionCallExpression(result, "next");
    +            GroovyExpression result = new FunctionCallExpression
(TraversalStepType.BARRIER, parent, "groupBy", groupByClosureExpr,
itClosure);
    +            result = new FunctionCallExpression
(TraversalStepType.SIDE_EFFECT, result, "cap");
    +            result = new FunctionCallExpression(TraversalStepType.END,
result, "next");
                 result = new FunctionCallExpression(result, "values");
                 result = new FunctionCallExpression(result, "toList");

    -            GroovyExpression mapValuesClosure = new ClosureExpression
(getItVariable());
                 GroovyExpression aggregrationFunctionClosure = new
ClosureExpression(aggregationFunction);
                 result = new FunctionCallExpression(result, "collect",
aggregrationFunctionClosure);
                 return result;
    @@ -251,8 +293,49 @@ public class Gremlin2ExpressionFactory extends
GremlinExpressionFactory {
         //assumes cast already performed
         @Override
         public GroovyExpression generateCountExpression(GroovyExpression
itExpr) {
    -        GroovyExpression collectionExpr = new CastExpression
(itExpr,"Collection");
             return new FunctionCallExpression(itExpr, "size");
         }
    +
    +    @Override
    +    public String getTraversalExpressionClass() {
    +        return "GremlinPipeline";
    +    }
    +
    +
    +    @Override
    +    public boolean isSelectGeneratesMap(int aliasCount) {
    +        //in Gremlin 2 select always generates a map
    +        return true;
    +    }
    +
    +    @Override
    +    public GroovyExpression generateMapExpression(GroovyExpression
parent, ClosureExpression closureExpression) {
    +        return new FunctionCallExpression
(TraversalStepType.MAP_TO_ELEMENT, parent, "transform", closureExpression);
    +    }
    +
    +    @Override
    +    public GroovyExpression generateGetSelectedValueExpression
(LiteralExpression key,
    +            GroovyExpression rowMap) {
    +        rowMap = new CastExpression(rowMap, "Row");
    +        GroovyExpression getExpr = new FunctionCallExpression(rowMap,
"getColumn", key);
    +        return getExpr;
    +    }
    +
    +    @Override
    +    public GroovyExpression getCurrentTraverserObject(GroovyExpression
traverser) {
    +        return traverser;
    +    }
    +
    +    public List<String> getAliasesRequiredByExpression
(GroovyExpression expr) {
    +        if(!(expr instanceof FunctionCallExpression)) {
    +            return Collections.emptyList();
    +        }
    +        FunctionCallExpression fc = (FunctionCallExpression)expr;
    +        if(! fc.getFunctionName().equals(LOOP_METHOD)) {
    +            return Collections.emptyList();
    +        }
    +       LiteralExpression aliasName =
(LiteralExpression)fc.getArguments().get(0);
    +       return Collections.singletonList(aliasName.getValue().toString
());
    +    }
     }







Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message