This is an automated email from the ASF dual-hosted git repository. spmallette pushed a commit to branch GValueManager3.8-wip in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 789f67b33a410ca40642382d533339f733c00d2a Author: Stephen Mallette <[email protected]> AuthorDate: Fri Jun 13 11:37:23 2025 -0400 wip --- .../strategy/decoration/SubgraphStrategy.java | 3 + .../strategy/decoration/SubgraphStrategyTest.java | 100 +++++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java index 8c30cfa258..8e2d17debd 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java @@ -194,6 +194,9 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS new EdgeOtherVertexStep(traversal) : new EdgeVertexStep(traversal, step.getDirection().opposite()); + // move StepContract from out() to outE() for example + traversal.getGValueManager().copyRegistryState(step, (Step) someEStep); + TraversalHelper.replaceStep((Step<Vertex, Edge>) step, someEStep, traversal); TraversalHelper.insertAfterStep(someVStep, someEStep, traversal); TraversalHelper.copyLabels(step, someVStep, true); diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTest.java index 1d7ba5dc47..4726d76a1e 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTest.java @@ -27,6 +27,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTrav import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; +import org.apache.tinkerpop.gremlin.process.traversal.step.GValue; import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AndStep; import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep; import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStartStep; @@ -34,6 +35,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep; import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep; import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexStep; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.GValueManagerVerifier; import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.InlineFilterStrategy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.StandardVerificationStrategy; import org.apache.tinkerpop.gremlin.process.traversal.translator.GroovyTranslator; @@ -50,7 +52,9 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.has; @@ -213,5 +217,101 @@ public class SubgraphStrategyTest { } } + /** + * Tests that GValueManager is being used correctly in SubgraphStrategy + * to ensure that GValue state is properly maintained when steps are modified. + */ + @RunWith(Parameterized.class) + public static class GValueTest { + + @Parameterized.Parameter(value = 0) + public Traversal.Admin<?, ?> traversal; + + @Parameterized.Parameter(value = 1) + public SubgraphStrategy strategy; + + @Parameterized.Parameter(value = 2) + public Set<String> expectedVariables; + + @Parameterized.Parameters(name = "{0}") + public static Iterable<Object[]> generateTestParameters() { + // Create a default SubgraphStrategy + final SubgraphStrategy defaultStrategy = SubgraphStrategy.build() + .vertices(__.has("vertex")) + .edges(__.has("edge")) + .create(); + + return Arrays.asList(new Object[][]{ + // Basic vertex steps with GValue edge labels + { + __.V().hasLabel("person").out(GValue.of("x", "knows")).asAdmin(), + defaultStrategy, + new HashSet<>(Arrays.asList("x")) + }, + { + __.V().hasLabel("person").both(GValue.of("x", "created")).asAdmin(), + defaultStrategy, + new HashSet<>(Arrays.asList("x")) + }, + { + __.V().hasLabel("person").in(GValue.of("x", "created")).asAdmin(), + defaultStrategy, + new HashSet<>(Arrays.asList("x")) + }, + // Multiple GValue edge labels + { + __.V().hasLabel("person").out(GValue.of("x", "knows"), GValue.of("y", "created")).asAdmin(), + defaultStrategy, + new HashSet<>(Arrays.asList("x", "y")) + }, + // Edge steps with GValue + { + __.V().hasLabel("person").outE(GValue.of("x", "knows")).inV().asAdmin(), + defaultStrategy, + new HashSet<>(Arrays.asList("x")) + }, + { + __.V().hasLabel("person").inE(GValue.of("x", "created")).outV().asAdmin(), + defaultStrategy, + new HashSet<>(Arrays.asList("x")) + }, + { + __.V().hasLabel("person").bothE(GValue.of("x", "created")).otherV().asAdmin(), + defaultStrategy, + new HashSet<>(Arrays.asList("x")) + }, + // Filter steps with GValue + { + __.V().hasLabel(GValue.of("x", "person")).asAdmin(), + defaultStrategy, + new HashSet<>(Arrays.asList("x")) + }, + // Complex traversals with GValue + { + __.V().hasLabel("person").out(GValue.of("x", "knows")).out(GValue.of("y", "created")).asAdmin(), + defaultStrategy, + new HashSet<>(Arrays.asList("x", "y")) + }, + // Filter with GValue in predicate + { + __.V().has("age", GValue.of("x", P.gt(30))).asAdmin(), + SubgraphStrategy.build() + .vertices(__.has("vertex")) + .edges(__.has("edge")) + .create(), + new HashSet<>(Arrays.asList("x")) + } + }); + } + @Test + public void shouldMaintainGValueState() { + // Verify that expected variables exist before applying the strategy + GValueManagerVerifier.verify(traversal, strategy) + .beforeApplying() + .hasVariables(expectedVariables) + .afterApplying() + .variablesArePreserved(); + } + } }
