You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2015/06/10 18:23:25 UTC

incubator-tinkerpop git commit: WhereStep now has a static method to convert all nested predicates into TraversalP. gremlin-applications.asciidoc has Sugar sections being autogenerated. Added more WhereTests.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/master 773f7039b -> 8c3ecf5ac


WhereStep now has a static method to convert all nested predicates into TraversalP. gremlin-applications.asciidoc has Sugar sections being autogenerated. Added more WhereTests.


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

Branch: refs/heads/master
Commit: 8c3ecf5ac5284af20857658b7dc07dbfbefc8945
Parents: 773f703
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Wed Jun 10 10:23:18 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Wed Jun 10 10:23:18 2015 -0600

----------------------------------------------------------------------
 docs/src/gremlin-applications.asciidoc          | 172 ++++---------------
 .../traversal/step/filter/WhereStep.java        |  71 +++++---
 .../gremlin/process/traversal/util/ScopeP.java  |   2 +-
 .../step/filter/GroovyWhereTest.groovy          |   5 +
 .../traversal/step/filter/WhereTest.java        |  24 +++
 5 files changed, 104 insertions(+), 170 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8c3ecf5a/docs/src/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/gremlin-applications.asciidoc b/docs/src/gremlin-applications.asciidoc
index 0dcd18e..e01d615 100644
--- a/docs/src/gremlin-applications.asciidoc
+++ b/docs/src/gremlin-applications.asciidoc
@@ -945,7 +945,7 @@ NOTE: The Server Plugin is enabled in the Gremlin Console by default.
 Sugar Plugin
 ~~~~~~~~~~~~
 
-image:gremlin-sugar.png[width=120,float=left] In previous versions of Gremlin-Groovy, there were numerous link:http://en.wikipedia.org/wiki/Syntactic_sugar[syntactic sugars] that users could rely on to make their traversals more succinct. Unfortunately, many of these conventions made use of link:http://docs.oracle.com/javase/tutorial/reflect/[Java reflection] and thus, were not performant. In TinkerPop3, these conveniences have been removed in support of the standard Gremlin-Groovy syntax being both inline with Gremlin-Java8 syntax as well as always being the most performant representation. However, for those users that would like to use the previous syntactic sugars (as well as new ones), there is `SugarGremlinPlugin`.
+image:gremlin-sugar.png[width=120,float=left] In previous versions of Gremlin-Groovy, there were numerous link:http://en.wikipedia.org/wiki/Syntactic_sugar[syntactic sugars] that users could rely on to make their traversals more succinct. Unfortunately, many of these conventions made use of link:http://docs.oracle.com/javase/tutorial/reflect/[Java reflection] and thus, were not performant. In TinkerPop3, these conveniences have been removed in support of the standard Gremlin-Groovy syntax being both inline with Gremlin-Java8 syntax as well as always being the most performant representation. However, for those users that would like to use the previous syntactic sugars (as well as new ones), there is `SugarGremlinPlugin` (a.k.a Gremlin-Groovy-Sugar).
 
 IMPORTANT: It is important that the sugar plugin is loaded in a Gremlin Console session prior to any manipulations of the respective TinkerPop3 objects as Groovy will cache unavailable methods and properties.
 
@@ -955,36 +955,18 @@ gremlin> :plugin use tinkerpop.sugar
 ==>tinkerpop.sugar activated
 ----
 
-TIP: When using Sugar in a Groovy class file, add `static { SugarLoader.load() }` to the head of the file. `SugarLoader.load()` will automatically call `GremlinLoader.load()`.
+TIP: When using Sugar in a Groovy class file, add `static { SugarLoader.load() }` to the head of the file. Note that `SugarLoader.load()` will automatically call `GremlinLoader.load()`.
 
 Graph Traversal Methods
 ^^^^^^^^^^^^^^^^^^^^^^^
 
 If a `GraphTraversal` property is unknown and there is a corresponding method with said name off of `GraphTraversal` then the property is assumed to be a method call. This enables the user to omit `( )` from the method name. However, if the property does not reference a `GraphTraversal` method, then it is assumed to be a call to `values(property)`.
 
-[source,groovy]
+[gremlin-groovy,modern]
 ----
-gremlin> g.V ////<1>
-==>v[1]
-==>v[2]
-==>v[3]
-==>v[4]
-==>v[5]
-==>v[6]
-gremlin> g.V.name ////<2>
-==>marko
-==>vadas
-==>lop
-==>josh
-==>ripple
-==>peter
-gremlin> g.V.outE.weight ////<3>
-==>0.4
-==>0.5
-==>1.0
-==>1.0
-==>0.4
-==>0.2
+g.V <1>
+g.V.name <2>
+g.V.outE.weight <3>
 ----
 
 <1> There is no need for the parentheses in `g.V()`.
@@ -996,15 +978,11 @@ Range Queries
 
 The `[x]` and `[x..y]` range operators in Groovy translate to `RangeStep` calls.
 
-[source,groovy]
+[gremlin-groovy,modern]
 ----
-gremlin> g.V[0..2]
-==>v[1]
-==>v[2]
-gremlin> g.V[0..<2]
-==>v[1]
-gremlin> g.V[2]
-==>v[3]
+g.V[0..2]
+g.V[0..<2]
+g.V[2]
 ----
 
 Logical Operators
@@ -1012,20 +990,13 @@ Logical Operators
 
 The `&` and `|` operator are overloaded in `SugarGremlinPlugin`. When used, they introduce the `AndStep` and `OrStep` markers into the traversal. See <<and-step,`and()`>> and <<or-step,`or()`>> for more information.
 
-[source,groovy]
+[gremlin-groovy,modern]
 ----
-gremlin> g.V.has(outE('knows') & outE('created')).name ////<1>
-==>marko
-gremlin> t = g.V.has(outE('knows') | inE('created')).name; null ////<2>
-==>null
-gremlin> t.toString()
-==>[GraphStep(vertex), HasTraversalStep([VertexStep(OUT,[knows],edge), OrMarker, VertexStep(IN,[created],edge)]), PropertiesStep([name],value)]
-gremlin> t
-==>marko
-==>lop
-==>ripple
-gremlin> t.toString()
-==>[TinkerGraphStep(vertex), HasTraversalStep([OrStep([[VertexStep(OUT,[knows],edge)], [VertexStep(IN,[created],edge)]])]), PropertiesStep([name],value)]
+g.V.where(outE('knows') & outE('created')).name <1>
+t = g.V.where(outE('knows') | inE('created')).name; null <2>
+t.toString()
+t
+t.toString()
 ----
 
 <1> Introducing the `AndStep` with the `&` operator.
@@ -1036,22 +1007,10 @@ Traverser Methods
 
 It is rare that a user will ever interact with a `Traverser` directly. However, if they do, some method redirects exist to make it easy.
 
-[source,groovy]
+[gremlin-groovy,modern]
 ----
-gremlin> g.V().map{it.get().value('name')}  // conventional
-==>marko
-==>vadas
-==>lop
-==>josh
-==>ripple
-==>peter
-gremlin> g.V.map{it.name}  // sugar
-==>marko
-==>vadas
-==>lop
-==>josh
-==>ripple
-==>peter
+g.V().map{it.get().value('name')}  // conventional
+g.V.map{it.name}  // sugar
 ----
 
 [[utilities-plugin]]
@@ -1070,97 +1029,24 @@ The link:https://code.google.com/p/gperfutils/[GPerfUtils] library provides a nu
 
 Benchmarking allows execution time comparisons of different pieces of code. While such a feature is generally useful, in the context of Gremlin, benchmarking can help compare traversal performance times to determine the optimal approach.  Profiling helps determine the parts of a program which are taking the most execution time, yielding low-level insight into the code being examined. 
 
-[source,groovy]
+[gremlin-groovy,modern]
 ----
-gremlin> :plugin use tinkerpop.sugar // activate sugar plugin for use in benchmark
-==>tinkerpop.sugar activated
-gremlin> benchmark{ 
-gremlin>   'sugar' {g.V(1).name.next()}
-gremlin>   'nosugar' {g.V(1).values('name').next()}}.prettyPrint()
-Environment
-===========
-* Groovy: 2.3.6
-* JVM: Java HotSpot(TM) 64-Bit Server VM (25.5-b02, Oracle Corporation)
-    * JRE: 1.8.0_05
-    * Total Memory: 161 MB
-    * Maximum Memory: 1774.5 MB
-* OS: Linux (3.13.0-32-generic, amd64)
-
-Options
-=======
-* Warm Up: Auto (- 60 sec)
-* CPU Time Measurement: On
-
-         user  system   cpu  real
-
-sugar    4135       0  4135  4143
-nosugar  1223       0  1223  1226
-==>null
-gremlin> profile { g.V().iterate() }.prettyPrint()
-Flat:
-
- %    cumulative   self            self     total    self    total   self    total                                                                              
-time   seconds    seconds  calls  ms/call  ms/call  min ms  min ms  max ms  max ms  name                                                                        
-61.8        0.02     0.02      1    22.60    22.60   22.60   22.60   22.60   22.60  org.apache.tinkerpop.gremlin.tinkergraph.process.graph.TinkerGraphTraversal.iterate
-23.5        0.03     0.00      1     8.62     8.62    8.62    8.62    8.62    8.62  org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph.V                   
-13.4        0.03     0.00      1     4.93    36.57    4.93   36.57    4.93   36.57  groovysh_evaluate$_run_closure1.doCall                                      
- 1.0        0.03     0.00      1     0.38     0.40    0.38    0.40    0.38    0.40  org.apache.tinkerpop.gremlin.groovy.loaders.GremlinLoader.isStep                   
- 0.0        0.03     0.00      1     0.01     0.01    0.01    0.01    0.01    0.01  java.util.HashSet.contains                                                  
-
-Call graph:
-
-index  % time  self  children  calls  name                                                                                
-               0.00      0.03    1/1      <spontaneous>                                                                   
-[1]     100.0  0.00      0.03      1  groovysh_evaluate$_run_closure1.doCall [1]                                          
-               0.02      0.00    1/1      org.apache.tinkerpop.gremlin.tinkergraph.process.graph.TinkerGraphTraversal.iterate [2]
-               0.00      0.00    1/1      org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph.V [3]                   
-               0.00      0.00    1/1      org.apache.tinkerpop.gremlin.groovy.loaders.GremlinLoader.isStep [4]                   
---------------------------------------------------------------------------------------------------------------------------
-               0.02      0.00    1/1      groovysh_evaluate$_run_closure1.doCall [1]                                      
-[2]      61.8  0.02      0.00      1  org.apache.tinkerpop.gremlin.tinkergraph.process.graph.TinkerGraphTraversal.iterate [2]    
---------------------------------------------------------------------------------------------------------------------------
-               0.00      0.00    1/1      groovysh_evaluate$_run_closure1.doCall [1]                                      
-[3]      23.5  0.00      0.00      1  org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph.V [3]                       
---------------------------------------------------------------------------------------------------------------------------
-               0.00      0.00    1/1      groovysh_evaluate$_run_closure1.doCall [1]                                      
-[4]       1.1  0.00      0.00      1  org.apache.tinkerpop.gremlin.groovy.loaders.GremlinLoader.isStep [4]                       
-               0.00      0.00    1/1      java.util.HashSet.contains [5]                                                  
---------------------------------------------------------------------------------------------------------------------------
-               0.00      0.00    1/1      org.apache.tinkerpop.gremlin.groovy.loaders.GremlinLoader.isStep [4]                   
-[5]       0.0  0.00      0.00      1  java.util.HashSet.contains [5]                                                      
---------------------------------------------------------------------------------------------------------------------------
-==>null
+:plugin use tinkerpop.sugar <1>
+benchmark{
+ 'sugar' {g.V(1).name.next()}
+ 'nosugar' {g.V(1).values('name').next()}
+}.prettyPrint()
 ----
 
+<1> Activate sugar plugin for use in benchmark
+
 [[describe-graph]]
 Describe Graph
 ^^^^^^^^^^^^^^
 
 A good implementation of the Gremlin APIs will validate their features against the xref:validating-with-gremlin-test[Gremlin test suite].  To learn more about a specific implementation's compliance with the test suite, use the `describeGraph` function.  The following shows the output for `HadoopGraph`:
 
-[source,groovy]
+[gremlin-groovy,modern]
 ----
-gremlin> describeGraph(HadoopGraph)
-==>
-IMPLEMENTATION - org.apache.tinkerpop.gremlin.hadoop.structure.HadoopGraph
-TINKERPOP TEST SUITE
-- Compliant with (4 of 8 suites)
-> org.apache.tinkerpop.gremlin.process.ProcessStandardSuite
-> org.apache.tinkerpop.gremlin.process.ProcessComputerSuite
-> org.apache.tinkerpop.gremlin.process.GroovyProcessStandardSuite
-> org.apache.tinkerpop.gremlin.process.GroovyProcessComputerSuite
-- Opts out of 12 individual tests
-> org.apache.tinkerpop.gremlin.process.graph.step.map.MatchTest$StandardTest#g_V_matchXa_hasXname_GarciaX__a_0writtenBy_b__a_0sungBy_bX
-    "Hadoop-Gremlin is OLAP-oriented and for OLTP operations, linear-scan joins are required. This particular tests takes many minutes to execute."
-...
-> org.apache.tinkerpop.gremlin.process.graph.step.map.MatchTest$JavaMatchTest#g_V_matchXa_inXsungByX_b__a_inXsungByX_c__b_outXwrittenByX_d__c_outXwrittenByX_e__d_hasXname_George_HarisonX__e_hasXname_Bob_MarleyXX
-    "Hadoop-Gremlin is OLAP-oriented and for OLTP operations, linear-scan joins are required. This particular tests takes many minutes to execute."
-
-- NOTE -
-The describeGraph() function shows information about a Graph implementation.
-It uses information found in Java Annotations on the implementation itself to
-determine this output and does not assess the actual code of the test cases of
-the implementation itself.  Compliant implementations will faithfully and
-honestly supply these Annotations to provide the most accurate depiction of
-their support.
+describeGraph(HadoopGraph)
 ----

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8c3ecf5a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
index 9f033b8..fd4de2c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
@@ -29,11 +29,15 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.SelectOneStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StartStep;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.AndP;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ConjunctionP;
+import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
 import org.apache.tinkerpop.gremlin.process.traversal.util.ScopeP;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalP;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
@@ -50,32 +54,23 @@ public final class WhereStep<S> extends FilterStep<S> implements TraversalParent
     public WhereStep(final Traversal.Admin traversal, final Scope scope, final Optional<String> startKey, final P<?> predicate) {
         super(traversal);
         this.scope = scope;
-        this.predicate = (P) predicate;
-        if (this.predicate.getTraversals().isEmpty()) {                              // a standard P
-            final Traversal.Admin<?, ?> whereTraversal = new DefaultGraphTraversal<>();
-            // START STEP
-            startKey.ifPresent(key -> whereTraversal.addStep(new SelectOneStep<>(whereTraversal, scope, startKey.get())));
-            // END STEP
-            whereTraversal.addStep(new IsStep<>(whereTraversal, new ScopeP<>(predicate)));
-            this.predicate = new TraversalP(whereTraversal, false);
-        } else {                                                                     // a TraversalP, AndP, or OrP
-            for (final Traversal.Admin<?, ?> whereTraversal : this.predicate.getTraversals()) {
-                //// START STEP
-                final Step<?, ?> startStep = whereTraversal.getStartStep();
-                if (startStep instanceof StartStep && !startStep.getLabels().isEmpty()) {
-                    if (startStep.getLabels().size() > 1)
-                        throw new IllegalArgumentException("The start step of a where()-traversal predicate can only have one label: " + startStep);
-                    TraversalHelper.replaceStep(whereTraversal.getStartStep(), new SelectOneStep<>(whereTraversal, scope, startStep.getLabels().iterator().next()), whereTraversal);
-                }
-                //// END STEP
-                final Step<?, ?> endStep = whereTraversal.getEndStep();
-                if (!endStep.getLabels().isEmpty()) {
-                    if (endStep.getLabels().size() > 1)
-                        throw new IllegalArgumentException("The end step of a where()-traversal predicate can only have one label: " + endStep);
-                    final String label = endStep.getLabels().iterator().next();
-                    endStep.removeLabel(label);
-                    whereTraversal.addStep(new IsStep<>(whereTraversal, new ScopeP<>(P.eq(label))));
-                }
+        this.predicate = WhereStep.convertToTraversalP(startKey, predicate);
+        for (final Traversal.Admin<?, ?> whereTraversal : this.predicate.getTraversals()) {
+            //// START STEP
+            final Step<?, ?> startStep = whereTraversal.getStartStep();
+            if (startStep instanceof StartStep && !startStep.getLabels().isEmpty()) {
+                if (startStep.getLabels().size() > 1)
+                    throw new IllegalArgumentException("The start step of a where()-traversal predicate can only have one label: " + startStep);
+                TraversalHelper.replaceStep(whereTraversal.getStartStep(), new SelectOneStep<>(whereTraversal, scope, startStep.getLabels().iterator().next()), whereTraversal);
+            }
+            //// END STEP
+            final Step<?, ?> endStep = whereTraversal.getEndStep();
+            if (!endStep.getLabels().isEmpty()) {
+                if (endStep.getLabels().size() > 1)
+                    throw new IllegalArgumentException("The end step of a where()-traversal predicate can only have one label: " + endStep);
+                final String label = endStep.getLabels().iterator().next();
+                endStep.removeLabel(label);
+                whereTraversal.addStep(new IsStep<>(whereTraversal, new ScopeP<>(P.eq(label))));
             }
         }
         this.predicate.getTraversals().forEach(this::integrateChild);
@@ -158,4 +153,28 @@ public final class WhereStep<S> extends FilterStep<S> implements TraversalParent
     public Scope recommendNextScope() {
         return this.scope;
     }
+
+    private static P convertToTraversalP(final Optional<String> startKey, final P<?> predicate) {
+        if (predicate instanceof TraversalP)
+            return predicate;
+        else if (predicate instanceof ConjunctionP) {
+            final List<P<?>> conjunctionPredicates = ((ConjunctionP) predicate).getPredicates();
+            final P<?>[] ps = new P[conjunctionPredicates.size()];
+            for (int i = 0; i < conjunctionPredicates.size(); i++) {
+                ps[i] = convertToTraversalP(startKey, conjunctionPredicates.get(i));
+            }
+            return predicate instanceof AndP ? new AndP(ps[0], Arrays.copyOfRange(ps, 1, ps.length)) : new OrP(ps[0], Arrays.copyOfRange(ps, 1, ps.length));
+        } else {
+            final Traversal.Admin<?, ?> whereTraversal = new DefaultGraphTraversal<>();
+            // START STEP
+            if (startKey.isPresent()) {
+                final StartStep<?> startStep = new StartStep<>(whereTraversal);
+                startStep.addLabel(startKey.get());
+                whereTraversal.addStep(startStep);
+            }
+            // END STEP
+            whereTraversal.addStep(new IsStep<>(whereTraversal, new ScopeP<>(predicate)));
+            return new TraversalP(whereTraversal, false);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8c3ecf5a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ScopeP.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ScopeP.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ScopeP.java
index f22456a..33d03b3 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ScopeP.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/ScopeP.java
@@ -39,7 +39,7 @@ public final class ScopeP<V> extends P<V> {
 
     public ScopeP(final P<?> predicate) {
         super((BiPredicate) predicate.getBiPredicate(), (V) EMPTY_OBJECT);
-        this.key = predicate.getValue() instanceof Collection ? ((Collection<String>) predicate.getValue()).iterator().next() : predicate.getValue().toString();   // HACK: for within("x") as it sees that as an array
+        this.key = predicate.getValue() instanceof Collection ? ((Collection<String>) predicate.getValue()).iterator().next() : (String) predicate.getValue();   // HACK: for within("x") as it sees that as an array
     }
 
     public void bind(final Scoping scopingStep, final Traverser.Admin<?> traverser) {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8c3ecf5a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyWhereTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyWhereTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyWhereTest.groovy
index 490c3d0..6214fea 100644
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyWhereTest.groovy
+++ b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyWhereTest.groovy
@@ -111,6 +111,11 @@ public abstract class GroovyWhereTest {
             TraversalScriptHelper.compute("g.V.as('a').out.as('b').where(and(__.as('a').out('knows').as('b'),or(__.as('b').out('created').has('name','ripple'),__.as('b').in('knows').count.is(not(eq(0)))))).select.by('name')", g)
         }
 
+        @Override
+        public Traversal<Vertex, Map<String, String>> get_g_V_asXaX_outXcreatedX_asXbX_in_asXcX_whereXa__eqXcX_andXasXaX_outXknowsXXX_select_byXnameX() {
+            TraversalScriptHelper.compute("g.V.as('a').out('created').as('b').in.as('c').where('a',eq('c').and(__.as('a').out('knows'))).select.by('name')", g)
+        }
+
         /*@Override
         public Traversal<Vertex, String> get_g_V_asXaX_outXknowsX_asXbX_whereXasXa__bX_outXcreatedX_hasXname__rippleX_name() {
             TraversalScriptHelper.compute("g.V.as('a').out('knows').as('b').where(__.as('a', 'b').out('created').has('name', 'ripple')).name", g)

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8c3ecf5a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTest.java
index 8212a27..9ee7023 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTest.java
@@ -83,6 +83,8 @@ public abstract class WhereTest extends AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex,Map<String,String>> get_g_V_asXaX_out_asXbX_whereXandXasXaX_outXknowsX_asXbX__orXasXbX_outXcreatedX_hasXname_rippleX__asXbX_inXknowsX_count_isXnotXeqX0XXXXX_select_byXnameX();
 
+    public abstract Traversal<Vertex,Map<String,String>> get_g_V_asXaX_outXcreatedX_asXbX_in_asXcX_whereXa__eqXcX_andXasXaX_outXknowsXXX_select_byXnameX();
+
     // multi-labels
 
     //public abstract Traversal<Vertex, String> get_g_V_asXaX_outXknowsX_asXbX_whereXasXa__bX_outXcreatedX_hasXname__rippleX_name();
@@ -278,6 +280,23 @@ public abstract class WhereTest extends AbstractGremlinProcessTest {
         assertEquals(2,counter);
     }
 
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_asXaX_outXcreatedX_asXbX_in_asXcX_whereXa__eqXcX_andXasXaX_outXknowsXXX_select_byXnameX() {
+        Traversal<Vertex,Map<String,String>> traversal = get_g_V_asXaX_outXcreatedX_asXbX_in_asXcX_whereXa__eqXcX_andXasXaX_outXknowsXXX_select_byXnameX();
+        printTraversalForm(traversal);
+        int counter = 0;
+        while(traversal.hasNext()) {
+            final Map<String,String> map = traversal.next();
+            assertEquals(3,map.size());
+            assertEquals("marko",map.get("a"));
+            assertEquals("lop",map.get("b"));
+            assertEquals("marko", map.get("c"));
+            counter++;
+        }
+        assertEquals(1,counter);
+    }
+
 
     // multi-labels
    /* @Test
@@ -365,6 +384,11 @@ public abstract class WhereTest extends AbstractGremlinProcessTest {
               return g.V().as("a").out().as("b").where(and(as("a").out("knows").as("b"),or(as("b").out("created").has("name","ripple"),as("b").in("knows").count().is(not(eq(0)))))).<String>select().by("name");
         }
 
+        @Override
+        public Traversal<Vertex,Map<String,String>> get_g_V_asXaX_outXcreatedX_asXbX_in_asXcX_whereXa__eqXcX_andXasXaX_outXknowsXXX_select_byXnameX() {
+            return g.V().as("a").out("created").as("b").in().as("c").where("a",eq("c").and(__.as("a").out("knows"))).<String>select().by("name");
+        }
+
         // multi-labels
 
        /* @Override