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, "[email protected]" <[email protected]> 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 <[email protected]>
Authored: Wed Feb 1 16:03:34 2017 -0500
Committer: Jeff Hagelberg <[email protected]>
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..<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://git-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());
+ }
}