This is an automated email from the ASF dual-hosted git repository.

xiazcy pushed a commit to branch steps-taking-traversal-poc
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 6aac8a0401193f40f476391002b75d8234c2e2f4
Author: Yang Xia <[email protected]>
AuthorDate: Wed May 27 13:56:25 2026 -0700

    update to implement where(P)
---
 .../traversal/step/filter/WherePredicateStep.java  |  33 ++++-
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs |   7 ++
 gremlin-go/driver/cucumber/gremlin.go              |   7 ++
 .../gremlin-javascript/test/cucumber/gremlin.js    |   7 ++
 .../src/main/python/tests/feature/gremlin.py       |   7 ++
 .../gremlin/language/translator/translations.json  | 136 +++++++++++++++++++++
 .../test/features/filter/WhereTraversal.feature    | 122 ++++++++++++++++++
 7 files changed, 317 insertions(+), 2 deletions(-)

diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
index 77c3f4abc9..ce47519ea7 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
@@ -63,12 +63,15 @@ public final class WherePredicateStep<S> extends 
FilterStep<S> implements Scopin
         this.predicate = (P) predicate;
         this.selectKeys = new ArrayList<>();
         this.configurePredicates(this.predicate);
+        // Integrate child traversals from the predicate so they participate 
in cloning/strategy application
+        P.integrateTraversals(this.predicate, this);
     }
 
     private void configurePredicates(final P<Object> predicate) {
         if (predicate instanceof ConnectiveP)
             ((ConnectiveP<Object>) 
predicate).getPredicates().forEach(this::configurePredicates);
-        else {
+        else if (!predicate.hasTraversal()) {
+            // Only configure scope keys for non-traversal predicates (string 
label references)
             final String selectKey = getSelectKey(predicate);
             this.selectKeys.add(selectKey);
             this.scopeKeys.add(selectKey);
@@ -112,6 +115,27 @@ public final class WherePredicateStep<S> extends 
FilterStep<S> implements Scopin
 
     @Override
     protected boolean filter(final Traverser.Admin<S> traverser) {
+        // If the predicate has a child traversal, resolve it and test 
directly against the
+        // current value (or startKey scope value). This bypasses the 
scope-label mechanism.
+        if (this.predicate.hasTraversal()) {
+            final Object leftValue;
+            if (null == this.startKey) {
+                final TraversalProduct product = 
TraversalUtil.produce(traverser, this.traversalRing.next());
+                this.traversalRing.reset();
+                if (!product.isProductive()) return false;
+                leftValue = product.get();
+            } else {
+                final TraversalProduct product = TraversalUtil.produce((S) 
this.getSafeScopeValue(Pop.last, this.startKey, traverser), 
this.traversalRing.next());
+                this.traversalRing.reset();
+                if (!product.isProductive()) return false;
+                leftValue = product.get();
+            }
+            this.predicate.resolve(traverser);
+            if (this.predicate.isResolvedEmpty()) return false;
+            return this.predicate.test(leftValue);
+        }
+
+        // Standard scope-label path for non-traversal predicates
         final TraversalProduct product = null == this.startKey ?
                 TraversalUtil.produce(traverser, this.traversalRing.next()) :
                 TraversalUtil.produce((S) this.getSafeScopeValue(Pop.last, 
this.startKey, traverser), this.traversalRing.next());
@@ -166,7 +190,12 @@ public final class WherePredicateStep<S> extends 
FilterStep<S> implements Scopin
 
     @Override
     public List<Traversal.Admin<S, ?>> getLocalChildren() {
-        return (List) this.traversalRing.getTraversals();
+        final List<Traversal.Admin<S, ?>> children = new ArrayList<>((List) 
this.traversalRing.getTraversals());
+        // Also expose predicate child traversals for strategy application and 
cloning
+        final List<Traversal.Admin<?, ?>> predicateTraversals = new 
ArrayList<>();
+        P.collectTraversals(this.predicate, predicateTraversals);
+        children.addAll((List) predicateTraversals);
+        return children;
     }
 
     @Override
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index d460dcadeb..e54133e1f0 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -773,6 +773,13 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"get_g_V_whereXage_isXgt_30XX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().Where(__.Values<object>("age").Is(P.Gt(30)))}}, 
                {"g_V_whereXlabel_isXsoftwareXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().Where(__.Label().Is("software"))}}, 
                {"g_V_whereXlabel_isXpersonXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.V().Where(__.Label().Is("person"))}}, 
+               {"g_V_valuesXageX_whereXgtXVXvid1X_valuesXageXXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Values<object>("age").Where(P.Gt(__.V(p["vid1"]).Values<object>("age")))}},
 
+               {"g_V_valuesXageX_whereXltXVXvid3X_valuesXageXXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Values<object>("age").Where(P.Lt(__.V(p["vid3"]).Values<object>("age")))}},
 
+               {"g_V_valuesXageX_whereXeqXVXvid1X_valuesXageXXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Values<object>("age").Where(P.Eq(__.V(p["vid1"]).Values<object>("age")))}},
 
+               
{"g_V_valuesXageX_whereXwithinXVXvid1X_outXknowsX_valuesXageXXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Values<object>("age").Where(P.Within(__.V(p["vid1"]).Out("knows").Values<object>("age")))}},
 
+               {"g_V_valuesXnameX_whereXneqXVXvid1X_valuesXnameXXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Values<object>("name").Where(P.Neq(__.V(p["vid1"]).Values<object>("name")))}},
 
+               {"g_V_valuesXageX_whereXeqXV9999_valuesXageXXX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Values<object>("age").Where(P.Eq(__.V(9999).Values<object>("age")))}}, 
+               {"g_V_whereXgtXVXvid1X_valuesXageXXX_byXageX_valuesXnameX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) 
=>g.V().Where(P.Gt(__.V(p["vid1"]).Values<object>("age"))).By("age").Values<object>("name")}},
 
                {"g_withStrategiesXAdjacentToIncidentStrategyX_V", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.WithStrategies(new AdjacentToIncidentStrategy()).V()}}, 
                {"g_withoutStrategiesXAdjacentToIncidentStrategyX_V", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.WithoutStrategies(typeof(AdjacentToIncidentStrategy)).V()}}, 
                {"g_withStrategiesXAdjacentToIncidentStrategyX_V_out_count", 
new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.WithStrategies(new 
AdjacentToIncidentStrategy()).V().Out().Count()}}, 
diff --git a/gremlin-go/driver/cucumber/gremlin.go 
b/gremlin-go/driver/cucumber/gremlin.go
index 60808e97d4..9003f7b3f8 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -743,6 +743,13 @@ var translationMap = map[string][]func(g 
*gremlingo.GraphTraversalSource, p map[
     "get_g_V_whereXage_isXgt_30XX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.V().Where(gremlingo.T__.Values("age").Is(gremlingo.P.Gt(30)))}}, 
     "g_V_whereXlabel_isXsoftwareXX": {func(g *gremlingo.GraphTraversalSource, 
p map[string]interface{}) *gremlingo.GraphTraversal {return 
g.V().Where(gremlingo.T__.Label().Is("software"))}}, 
     "g_V_whereXlabel_isXpersonXX": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.V().Where(gremlingo.T__.Label().Is("person"))}}, 
+    "g_V_valuesXageX_whereXgtXVXvid1X_valuesXageXXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("age").Where(gremlingo.P.Gt(gremlingo.T__.V(p["vid1"]).Values("age")))}},
 
+    "g_V_valuesXageX_whereXltXVXvid3X_valuesXageXXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("age").Where(gremlingo.P.Lt(gremlingo.T__.V(p["vid3"]).Values("age")))}},
 
+    "g_V_valuesXageX_whereXeqXVXvid1X_valuesXageXXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("age").Where(gremlingo.P.Eq(gremlingo.T__.V(p["vid1"]).Values("age")))}},
 
+    "g_V_valuesXageX_whereXwithinXVXvid1X_outXknowsX_valuesXageXXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("age").Where(gremlingo.P.Within(gremlingo.T__.V(p["vid1"]).Out("knows").Values("age")))}},
 
+    "g_V_valuesXnameX_whereXneqXVXvid1X_valuesXnameXXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("name").Where(gremlingo.P.Neq(gremlingo.T__.V(p["vid1"]).Values("name")))}},
 
+    "g_V_valuesXageX_whereXeqXV9999_valuesXageXXX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Values("age").Where(gremlingo.P.Eq(gremlingo.T__.V(9999).Values("age")))}},
 
+    "g_V_whereXgtXVXvid1X_valuesXageXXX_byXageX_valuesXnameX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.V().Where(gremlingo.P.Gt(gremlingo.T__.V(p["vid1"]).Values("age"))).By("age").Values("name")}},
 
     "g_withStrategiesXAdjacentToIncidentStrategyX_V": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.WithStrategies(gremlingo.AdjacentToIncidentStrategy()).V()}}, 
     "g_withoutStrategiesXAdjacentToIncidentStrategyX_V": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.WithoutStrategies(gremlingo.AdjacentToIncidentStrategy()).V()}}, 
     "g_withStrategiesXAdjacentToIncidentStrategyX_V_out_count": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.WithStrategies(gremlingo.AdjacentToIncidentStrategy()).V().Out().Count()}}, 
diff --git a/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js 
b/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js
index c2a1640ae4..1d705754b8 100644
--- a/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js
+++ b/gremlin-js/gremlin-javascript/test/cucumber/gremlin.js
@@ -774,6 +774,13 @@ const gremlins = {
     get_g_V_whereXage_isXgt_30XX: [function({g}) { return 
g.V().where(__.values("age").is(P.gt(30))) }], 
     g_V_whereXlabel_isXsoftwareXX: [function({g}) { return 
g.V().where(__.label().is("software")) }], 
     g_V_whereXlabel_isXpersonXX: [function({g}) { return 
g.V().where(__.label().is("person")) }], 
+    g_V_valuesXageX_whereXgtXVXvid1X_valuesXageXXX: [function({g, vid1}) { 
return g.V().values("age").where(P.gt(__.V(vid1).values("age"))) }], 
+    g_V_valuesXageX_whereXltXVXvid3X_valuesXageXXX: [function({g, vid3}) { 
return g.V().values("age").where(P.lt(__.V(vid3).values("age"))) }], 
+    g_V_valuesXageX_whereXeqXVXvid1X_valuesXageXXX: [function({g, vid1}) { 
return g.V().values("age").where(P.eq(__.V(vid1).values("age"))) }], 
+    g_V_valuesXageX_whereXwithinXVXvid1X_outXknowsX_valuesXageXXX: 
[function({g, vid1}) { return 
g.V().values("age").where(P.within(__.V(vid1).out("knows").values("age"))) }], 
+    g_V_valuesXnameX_whereXneqXVXvid1X_valuesXnameXXX: [function({g, vid1}) { 
return g.V().values("name").where(P.neq(__.V(vid1).values("name"))) }], 
+    g_V_valuesXageX_whereXeqXV9999_valuesXageXXX: [function({g}) { return 
g.V().values("age").where(P.eq(__.V(9999).values("age"))) }], 
+    g_V_whereXgtXVXvid1X_valuesXageXXX_byXageX_valuesXnameX: [function({g, 
vid1}) { return 
g.V().where(P.gt(__.V(vid1).values("age"))).by("age").values("name") }], 
     g_withStrategiesXAdjacentToIncidentStrategyX_V: [function({g}) { return 
g.withStrategies(new AdjacentToIncidentStrategy()).V() }], 
     g_withoutStrategiesXAdjacentToIncidentStrategyX_V: [function({g}) { return 
g.withoutStrategies(AdjacentToIncidentStrategy).V() }], 
     g_withStrategiesXAdjacentToIncidentStrategyX_V_out_count: [function({g}) { 
return g.withStrategies(new AdjacentToIncidentStrategy()).V().out().count() }], 
diff --git a/gremlin-python/src/main/python/tests/feature/gremlin.py 
b/gremlin-python/src/main/python/tests/feature/gremlin.py
index aa4358cfe7..5928aaedc4 100644
--- a/gremlin-python/src/main/python/tests/feature/gremlin.py
+++ b/gremlin-python/src/main/python/tests/feature/gremlin.py
@@ -748,6 +748,13 @@ world.gremlins = {
     'get_g_V_whereXage_isXgt_30XX': [(lambda 
g:g.V().where(__.values('age').is_(P.gt(30))))], 
     'g_V_whereXlabel_isXsoftwareXX': [(lambda 
g:g.V().where(__.label().is_('software')))], 
     'g_V_whereXlabel_isXpersonXX': [(lambda 
g:g.V().where(__.label().is_('person')))], 
+    'g_V_valuesXageX_whereXgtXVXvid1X_valuesXageXXX': [(lambda g, 
vid1=None:g.V().values('age').where(P.gt(__.V(vid1).values('age'))))], 
+    'g_V_valuesXageX_whereXltXVXvid3X_valuesXageXXX': [(lambda g, 
vid3=None:g.V().values('age').where(P.lt(__.V(vid3).values('age'))))], 
+    'g_V_valuesXageX_whereXeqXVXvid1X_valuesXageXXX': [(lambda g, 
vid1=None:g.V().values('age').where(P.eq(__.V(vid1).values('age'))))], 
+    'g_V_valuesXageX_whereXwithinXVXvid1X_outXknowsX_valuesXageXXX': [(lambda 
g, 
vid1=None:g.V().values('age').where(P.within(__.V(vid1).out('knows').values('age'))))],
 
+    'g_V_valuesXnameX_whereXneqXVXvid1X_valuesXnameXXX': [(lambda g, 
vid1=None:g.V().values('name').where(P.neq(__.V(vid1).values('name'))))], 
+    'g_V_valuesXageX_whereXeqXV9999_valuesXageXXX': [(lambda 
g:g.V().values('age').where(P.eq(__.V(9999).values('age'))))], 
+    'g_V_whereXgtXVXvid1X_valuesXageXXX_byXageX_valuesXnameX': [(lambda g, 
vid1=None:g.V().where(P.gt(__.V(vid1).values('age'))).by('age').values('name'))],
 
     'g_withStrategiesXAdjacentToIncidentStrategyX_V': [(lambda 
g:g.with_strategies(AdjacentToIncidentStrategy()).V())], 
     'g_withoutStrategiesXAdjacentToIncidentStrategyX_V': [(lambda 
g:g.without_strategies(AdjacentToIncidentStrategy).V())], 
     'g_withStrategiesXAdjacentToIncidentStrategyX_V_out_count': [(lambda 
g:g.with_strategies(AdjacentToIncidentStrategy()).V().out().count())], 
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
index 99148d3a53..1340ec569c 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
@@ -6516,6 +6516,23 @@
             }
         ]
     },
+    {
+        "scenario": "g_V_propertyXaddVXtempX_projectXkX_byXnameXX_rejected",
+        "traversals": [
+            {
+                "original": 
"g.V().property(__.addV(\"temp\").project(\"k\").by(\"name\"))",
+                "language": 
"g.V().property(__.addV(\"temp\").project(\"k\").by(\"name\"))",
+                "canonical": 
"g.V().property(__.addV(\"temp\").project(\"k\").by(\"name\"))",
+                "anonymized": 
"g.V().property(__.addV(string0).project(string1).by(string2))",
+                "dotnet": "g.V().Property((ITraversal) __.AddV((string) 
\"temp\").Project<object>(\"k\").By(\"name\"))",
+                "go": 
"g.V().Property(gremlingo.T__.AddV(\"temp\").Project(\"k\").By(\"name\"))",
+                "groovy": 
"g.V().property(__.addV(\"temp\").project(\"k\").by(\"name\"))",
+                "java": 
"g.V().property(__.addV(\"temp\").project(\"k\").by(\"name\"))",
+                "javascript": 
"g.V().property(__.addV(\"temp\").project(\"k\").by(\"name\"))",
+                "python": 
"g.V().property(__.add_v('temp').project('k').by('name'))"
+            }
+        ]
+    },
     {
         "scenario": "g_V_hasXname_VXvid1X_valuesXnameXX_passes_verification",
         "traversals": [
@@ -13359,6 +13376,125 @@
             }
         ]
     },
+    {
+        "scenario": "g_V_valuesXageX_whereXgtXVXvid1X_valuesXageXXX",
+        "traversals": [
+            {
+                "original": 
"g.V().values(\"age\").where(P.gt(__.V(vid1).values(\"age\")))",
+                "language": 
"g.V().values(\"age\").where(P.gt(__.V(vid1).values(\"age\")))",
+                "canonical": 
"g.V().values(\"age\").where(P.gt(__.V(vid1).values(\"age\")))",
+                "anonymized": 
"g.V().values(string0).where(P.gt(__.V(vid1).values(string0)))",
+                "dotnet": 
"g.V().Values<object>(\"age\").Where(P.Gt(__.V(vid1).Values<object>(\"age\")))",
+                "go": 
"g.V().Values(\"age\").Where(gremlingo.P.Gt(gremlingo.T__.V(vid1).Values(\"age\")))",
+                "groovy": 
"g.V().values(\"age\").where(P.gt(__.V(vid1).values(\"age\")))",
+                "java": 
"g.V().values(\"age\").where(P.gt(__.V(vid1).values(\"age\")))",
+                "javascript": 
"g.V().values(\"age\").where(P.gt(__.V(vid1).values(\"age\")))",
+                "python": 
"g.V().values('age').where(P.gt(__.V(vid1).values('age')))"
+            }
+        ]
+    },
+    {
+        "scenario": "g_V_valuesXageX_whereXltXVXvid3X_valuesXageXXX",
+        "traversals": [
+            {
+                "original": 
"g.V().values(\"age\").where(P.lt(__.V(vid3).values(\"age\")))",
+                "language": 
"g.V().values(\"age\").where(P.lt(__.V(vid3).values(\"age\")))",
+                "canonical": 
"g.V().values(\"age\").where(P.lt(__.V(vid3).values(\"age\")))",
+                "anonymized": 
"g.V().values(string0).where(P.lt(__.V(vid3).values(string0)))",
+                "dotnet": 
"g.V().Values<object>(\"age\").Where(P.Lt(__.V(vid3).Values<object>(\"age\")))",
+                "go": 
"g.V().Values(\"age\").Where(gremlingo.P.Lt(gremlingo.T__.V(vid3).Values(\"age\")))",
+                "groovy": 
"g.V().values(\"age\").where(P.lt(__.V(vid3).values(\"age\")))",
+                "java": 
"g.V().values(\"age\").where(P.lt(__.V(vid3).values(\"age\")))",
+                "javascript": 
"g.V().values(\"age\").where(P.lt(__.V(vid3).values(\"age\")))",
+                "python": 
"g.V().values('age').where(P.lt(__.V(vid3).values('age')))"
+            }
+        ]
+    },
+    {
+        "scenario": "g_V_valuesXageX_whereXeqXVXvid1X_valuesXageXXX",
+        "traversals": [
+            {
+                "original": 
"g.V().values(\"age\").where(P.eq(__.V(vid1).values(\"age\")))",
+                "language": 
"g.V().values(\"age\").where(P.eq(__.V(vid1).values(\"age\")))",
+                "canonical": 
"g.V().values(\"age\").where(P.eq(__.V(vid1).values(\"age\")))",
+                "anonymized": 
"g.V().values(string0).where(P.eq(__.V(vid1).values(string0)))",
+                "dotnet": 
"g.V().Values<object>(\"age\").Where(P.Eq(__.V(vid1).Values<object>(\"age\")))",
+                "go": 
"g.V().Values(\"age\").Where(gremlingo.P.Eq(gremlingo.T__.V(vid1).Values(\"age\")))",
+                "groovy": 
"g.V().values(\"age\").where(P.eq(__.V(vid1).values(\"age\")))",
+                "java": 
"g.V().values(\"age\").where(P.eq(__.V(vid1).values(\"age\")))",
+                "javascript": 
"g.V().values(\"age\").where(P.eq(__.V(vid1).values(\"age\")))",
+                "python": 
"g.V().values('age').where(P.eq(__.V(vid1).values('age')))"
+            }
+        ]
+    },
+    {
+        "scenario": 
"g_V_valuesXageX_whereXwithinXVXvid1X_outXknowsX_valuesXageXXX",
+        "traversals": [
+            {
+                "original": 
"g.V().values(\"age\").where(P.within(__.V(vid1).out(\"knows\").values(\"age\")))",
+                "language": 
"g.V().values(\"age\").where(P.within(__.V(vid1).out(\"knows\").values(\"age\")))",
+                "canonical": 
"g.V().values(\"age\").where(P.within(__.V(vid1).out(\"knows\").values(\"age\")))",
+                "anonymized": 
"g.V().values(string0).where(P.within(__.V(vid1).out(string1).values(string0)))",
+                "dotnet": 
"g.V().Values<object>(\"age\").Where(P.Within(__.V(vid1).Out(\"knows\").Values<object>(\"age\")))",
+                "go": 
"g.V().Values(\"age\").Where(gremlingo.P.Within(gremlingo.T__.V(vid1).Out(\"knows\").Values(\"age\")))",
+                "groovy": 
"g.V().values(\"age\").where(P.within(__.V(vid1).out(\"knows\").values(\"age\")))",
+                "java": 
"g.V().values(\"age\").where(P.within(__.V(vid1).out(\"knows\").values(\"age\")))",
+                "javascript": 
"g.V().values(\"age\").where(P.within(__.V(vid1).out(\"knows\").values(\"age\")))",
+                "python": 
"g.V().values('age').where(P.within(__.V(vid1).out('knows').values('age')))"
+            }
+        ]
+    },
+    {
+        "scenario": "g_V_valuesXnameX_whereXneqXVXvid1X_valuesXnameXXX",
+        "traversals": [
+            {
+                "original": 
"g.V().values(\"name\").where(P.neq(__.V(vid1).values(\"name\")))",
+                "language": 
"g.V().values(\"name\").where(P.neq(__.V(vid1).values(\"name\")))",
+                "canonical": 
"g.V().values(\"name\").where(P.neq(__.V(vid1).values(\"name\")))",
+                "anonymized": 
"g.V().values(string0).where(P.neq(__.V(vid1).values(string0)))",
+                "dotnet": 
"g.V().Values<object>(\"name\").Where(P.Neq(__.V(vid1).Values<object>(\"name\")))",
+                "go": 
"g.V().Values(\"name\").Where(gremlingo.P.Neq(gremlingo.T__.V(vid1).Values(\"name\")))",
+                "groovy": 
"g.V().values(\"name\").where(P.neq(__.V(vid1).values(\"name\")))",
+                "java": 
"g.V().values(\"name\").where(P.neq(__.V(vid1).values(\"name\")))",
+                "javascript": 
"g.V().values(\"name\").where(P.neq(__.V(vid1).values(\"name\")))",
+                "python": 
"g.V().values('name').where(P.neq(__.V(vid1).values('name')))"
+            }
+        ]
+    },
+    {
+        "scenario": "g_V_valuesXageX_whereXeqXV9999_valuesXageXXX",
+        "traversals": [
+            {
+                "original": 
"g.V().values(\"age\").where(P.eq(__.V(9999).values(\"age\")))",
+                "language": 
"g.V().values(\"age\").where(P.eq(__.V(9999).values(\"age\")))",
+                "canonical": 
"g.V().values(\"age\").where(P.eq(__.V(9999).values(\"age\")))",
+                "anonymized": 
"g.V().values(string0).where(P.eq(__.V(number0).values(string0)))",
+                "dotnet": 
"g.V().Values<object>(\"age\").Where(P.Eq(__.V(9999).Values<object>(\"age\")))",
+                "go": 
"g.V().Values(\"age\").Where(gremlingo.P.Eq(gremlingo.T__.V(9999).Values(\"age\")))",
+                "groovy": 
"g.V().values(\"age\").where(P.eq(__.V(9999).values(\"age\")))",
+                "java": 
"g.V().values(\"age\").where(P.eq(__.V(9999).values(\"age\")))",
+                "javascript": 
"g.V().values(\"age\").where(P.eq(__.V(9999).values(\"age\")))",
+                "python": 
"g.V().values('age').where(P.eq(__.V(9999).values('age')))"
+            }
+        ]
+    },
+    {
+        "scenario": "g_V_whereXgtXVXvid1X_valuesXageXXX_byXageX_valuesXnameX",
+        "traversals": [
+            {
+                "original": 
"g.V().where(P.gt(__.V(vid1).values(\"age\"))).by(\"age\").values(\"name\")",
+                "language": 
"g.V().where(P.gt(__.V(vid1).values(\"age\"))).by(\"age\").values(\"name\")",
+                "canonical": 
"g.V().where(P.gt(__.V(vid1).values(\"age\"))).by(\"age\").values(\"name\")",
+                "anonymized": 
"g.V().where(P.gt(__.V(vid1).values(string0))).by(string0).values(string1)",
+                "dotnet": 
"g.V().Where(P.Gt(__.V(vid1).Values<object>(\"age\"))).By(\"age\").Values<object>(\"name\")",
+                "go": 
"g.V().Where(gremlingo.P.Gt(gremlingo.T__.V(vid1).Values(\"age\"))).By(\"age\").Values(\"name\")",
+                "groovy": 
"g.V().where(P.gt(__.V(vid1).values(\"age\"))).by(\"age\").values(\"name\")",
+                "java": 
"g.V().where(P.gt(__.V(vid1).values(\"age\"))).by(\"age\").values(\"name\")",
+                "javascript": 
"g.V().where(P.gt(__.V(vid1).values(\"age\"))).by(\"age\").values(\"name\")",
+                "python": 
"g.V().where(P.gt(__.V(vid1).values('age'))).by('age').values('name')"
+            }
+        ]
+    },
     {
         "scenario": "g_withStrategiesXAdjacentToIncidentStrategyX_V",
         "traversals": [
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/WhereTraversal.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/WhereTraversal.feature
new file mode 100644
index 0000000000..cf9628883a
--- /dev/null
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/WhereTraversal.feature
@@ -0,0 +1,122 @@
+# 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.
+
+@StepClassFilter @StepWhere
+Feature: Step - where(P) with traversal-bearing predicates
+
+  # where(P.gt(traversal)) — compare current traverser value against resolved 
traversal result
+  @GraphComputerVerificationMidVNotSupported
+  Scenario: g_V_valuesXageX_whereXgtXVXvid1X_valuesXageXXX
+    Given the modern graph
+    And using the parameter vid1 defined as "v[marko].id"
+    And the traversal of
+      """
+      g.V().values("age").where(P.gt(__.V(vid1).values("age")))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[32].i |
+      | d[35].i |
+
+  # where(P.lt(traversal)) — filter ages less than josh's age
+  @GraphComputerVerificationMidVNotSupported
+  Scenario: g_V_valuesXageX_whereXltXVXvid3X_valuesXageXXX
+    Given the modern graph
+    And using the parameter vid3 defined as "v[josh].id"
+    And the traversal of
+      """
+      g.V().values("age").where(P.lt(__.V(vid3).values("age")))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[29].i |
+      | d[27].i |
+
+  # where(P.eq(traversal)) — exact match against resolved value
+  @GraphComputerVerificationMidVNotSupported
+  Scenario: g_V_valuesXageX_whereXeqXVXvid1X_valuesXageXXX
+    Given the modern graph
+    And using the parameter vid1 defined as "v[marko].id"
+    And the traversal of
+      """
+      g.V().values("age").where(P.eq(__.V(vid1).values("age")))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[29].i |
+
+  # where(P.within(traversal)) — collection membership against resolved 
traversal results
+  @GraphComputerVerificationMidVNotSupported
+  Scenario: g_V_valuesXageX_whereXwithinXVXvid1X_outXknowsX_valuesXageXXX
+    Given the modern graph
+    And using the parameter vid1 defined as "v[marko].id"
+    And the traversal of
+      """
+      
g.V().values("age").where(P.within(__.V(vid1).out("knows").values("age")))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[27].i |
+      | d[32].i |
+
+  # where(P.neq(traversal)) — not equal to resolved value
+  @GraphComputerVerificationMidVNotSupported
+  Scenario: g_V_valuesXnameX_whereXneqXVXvid1X_valuesXnameXXX
+    Given the modern graph
+    And using the parameter vid1 defined as "v[marko].id"
+    And the traversal of
+      """
+      g.V().values("name").where(P.neq(__.V(vid1).values("name")))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | vadas |
+      | lop |
+      | josh |
+      | ripple |
+      | peter |
+
+  # Empty traversal result — filters out (no match)
+  @GraphComputerVerificationMidVNotSupported
+  Scenario: g_V_valuesXageX_whereXeqXV9999_valuesXageXXX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").where(P.eq(__.V(9999).values("age")))
+      """
+    When iterated to list
+    Then the result should be empty
+
+  # where(P.gt(traversal)) with by() modulator — compare property values
+  @GraphComputerVerificationMidVNotSupported
+  Scenario: g_V_whereXgtXVXvid1X_valuesXageXXX_byXageX_valuesXnameX
+    Given the modern graph
+    And using the parameter vid1 defined as "v[marko].id"
+    And the traversal of
+      """
+      g.V().where(P.gt(__.V(vid1).values("age"))).by("age").values("name")
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | josh |
+      | peter |

Reply via email to