This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch gvalue-3.7
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/gvalue-3.7 by this push:
new f70d0d5f26 Brought back some changes from gvalue branch bound to master
f70d0d5f26 is described below
commit f70d0d5f264160f03aa270983ce30fb5252f9070
Author: Stephen Mallette <[email protected]>
AuthorDate: Thu Aug 15 09:32:41 2024 -0400
Brought back some changes from gvalue branch bound to master
---
.../gremlin/process/traversal/Operator.java | 2 +-
.../tinkerpop/gremlin/process/traversal/P.java | 20 ++++++-
.../traversal/dsl/graph/GraphTraversal.java | 64 ++++++++++++++++++++++
.../traversal/dsl/graph/GraphTraversalSource.java | 43 +++++++++++++++
.../gremlin/process/traversal/step/GType.java | 18 +++++-
.../gremlin/process/traversal/step/GValue.java | 20 +++++--
.../traversal/step/sideEffect/InjectStep.java | 18 +++---
.../process/traversal/step/util/AbstractStep.java | 43 +++++++++++++++
.../process/traversal/step/util/HasContainer.java | 6 +-
.../strategy/decoration/SideEffectStrategy.java | 7 ++-
.../gremlin/process/traversal/step/GValueTest.java | 34 ++++++------
11 files changed, 236 insertions(+), 39 deletions(-)
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Operator.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Operator.java
index b4d3cb23a0..3100084294 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Operator.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Operator.java
@@ -186,7 +186,7 @@ public enum Operator implements BinaryOperator<Object> {
if (a instanceof Map && b instanceof Map)
((Map<?,?>) a).putAll((Map) b);
- else if (a instanceof Collection && a instanceof Collection)
+ else if (a instanceof Collection && b instanceof Collection)
((Collection<?>) a).addAll((Collection) b);
else
throw new IllegalArgumentException(String.format("Objects must
be both of Map or Collection: a=%s b=%s",
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java
index 56e1946368..622a3c3e3a 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java
@@ -25,7 +25,9 @@ import
org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
/**
* Predefined {@code Predicate} values that can be used to define filters to
{@code has()} and {@code where()}.
@@ -75,10 +77,22 @@ public class P<V> implements Predicate<V>, Serializable,
Cloneable {
@Override
public boolean test(final V testValue) {
- if (this.value instanceof GValue)
+ if (this.value instanceof GValue) {
return this.biPredicate.test(testValue, ((GValue<V>)
this.value).get());
- else
- return this.biPredicate.test(testValue, this.value);
+ } else {
+ // this might be a bunch of GValue that need to be resolved. zomg
+ if (this.value instanceof List) {
+ return this.biPredicate.test(testValue, (V) ((List)
this.value).stream().map(o -> {
+ if (o instanceof GValue) {
+ return ((GValue) o).get();
+ } else {
+ return o;
+ }
+ }).collect(Collectors.toList()));
+ } else {
+ return this.biPredicate.test(testValue, this.value);
+ }
+ }
}
@Override
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index 3d9cd3e088..c49eadaf7d 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -458,6 +458,30 @@ public interface GraphTraversal<S, E> extends Traversal<S,
E> {
return TraversalHelper.addHasContainer(this.asAdmin(), new
HasContainer(T.label.getAccessor(), labels.length == 1 ? P.eq(labels[0]) :
P.within(labels)));
}
+ /**
+ * This is a step modulator to a {@link TraversalOptionParent} like
{@code choose()} or {@code mergeV()} where the
+ * provided argument associated to the {@code token} is applied
according to the semantics of the step. Please see
+ * the documentation of such steps to understand the usage context.
+ *
+ * @param token the token that would trigger this option which
may be a {@link Pick}, {@link Merge},
+ * a {@link Traversal}, {@link Predicate}, or
object depending on the step being modulated.
+ * @param traversalOption the option as a traversal
+ * @return the traversal with the modulated step
+ * @see <a
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#choose-step"
target="_blank">Reference Documentation - Choose Step</a>
+ * @see <a
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergev-step"
target="_blank">Reference Documentation - MergeV Step</a>
+ * @see <a
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergee-step"
target="_blank">Reference Documentation - MergeE Step</a>
+ * @since 3.0.0-incubating
+ */
+ public default <M, E2> GraphTraversal<S, E> option(final GValue<M>
token, final Traversal<?, E2> traversalOption) {
+
this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.option, token,
traversalOption);
+
+ // handle null similar to how option() with Map handles it,
otherwise we get a NPE if this one gets used
+ final Traversal.Admin<E,E2> t = null == traversalOption ?
+ new ConstantTraversal<>(null) : (Traversal.Admin<E, E2>)
traversalOption.asAdmin();
+ ((TraversalOptionParent<M, E, E2>)
this.asAdmin().getEndStep()).addChildOption(token.get(), t);
+ return this;
+ }
+
/**
* This is a step modulator to a {@link TraversalOptionParent} like
{@code choose()} or {@code mergeV()} where the
* provided argument associated to the {@code token} is applied
according to the semantics of the step. Please see
@@ -501,6 +525,46 @@ public interface GraphTraversal<S, E> extends Traversal<S,
E> {
return this;
}
+ /**
+ * When used as a modifier to {@link #addE(String)} this method
specifies the traversal to use for selecting the
+ * incoming vertex of the newly added {@link Edge}.
+ *
+ * @param toVertex the vertex for selecting the incoming vertex
+ * @return the traversal with the modified {@link AddEdgeStep}
+ * @see <a
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step"
target="_blank">Reference Documentation - From Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, E> to(final GValue<Vertex> toVertex) {
+ final Step<?,?> prev = this.asAdmin().getEndStep();
+ if (!(prev instanceof FromToModulating))
+ throw new IllegalArgumentException(String.format(
+ "The to() step cannot follow %s",
prev.getClass().getSimpleName()));
+
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.to,
toVertex);
+ ((FromToModulating) prev).addTo(__.constant(toVertex).asAdmin());
+ return this;
+ }
+
+ /**
+ * When used as a modifier to {@link #addE(String)} this method
specifies the traversal to use for selecting the
+ * outgoing vertex of the newly added {@link Edge}.
+ *
+ * @param fromVertex the vertex for selecting the outgoing vertex
+ * @return the traversal with the modified {@link AddEdgeStep}
+ * @see <a
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step"
target="_blank">Reference Documentation - From Step</a>
+ * @since 4.0.0
+ */
+ public default GraphTraversal<S, E> from(final GValue<Vertex>
fromVertex) {
+ final Step<?,?> prev = this.asAdmin().getEndStep();
+ if (!(prev instanceof FromToModulating))
+ throw new IllegalArgumentException(String.format(
+ "The from() step cannot follow %s",
prev.getClass().getSimpleName()));
+
+ this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.from,
fromVertex);
+ ((FromToModulating)
prev).addFrom(__.constant(fromVertex).asAdmin());
+ return this;
+ }
+
@Override
public default <E2> GraphTraversal.Admin<S, E2> addStep(final Step<?,
E2> step) {
return (GraphTraversal.Admin<S, E2>)
Traversal.Admin.super.addStep((Step) step);
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
index dc15306fce..961ba8c59c 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
@@ -27,6 +27,7 @@ import
org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.UnionStep;
import
org.apache.tinkerpop.gremlin.process.traversal.step.map.AddEdgeStartStep;
import
org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStartStep;
@@ -68,6 +69,7 @@ public class GraphTraversalSource implements TraversalSource {
protected final Graph graph;
protected TraversalStrategies strategies;
protected Bytecode bytecode = new Bytecode();
+ protected Admin admin;
////////////////
@@ -100,6 +102,12 @@ public class GraphTraversalSource implements
TraversalSource {
this.strategies.addStrategies(new RemoteStrategy(connection));
}
+ public GraphTraversalSource.Admin asAdmin() {
+ if (null == this.admin)
+ this.admin = new Admin();
+ return this.admin;
+ }
+
@Override
public Optional<Class<?>> getAnonymousTraversalClass() {
return Optional.of(__.class);
@@ -624,4 +632,39 @@ public class GraphTraversalSource implements
TraversalSource {
return StringFactory.traversalSourceString(this);
}
+ /**
+ * This class masks spawn steps that are more reserved for advanced usage.
+ */
+ public class Admin {
+
+ /**
+ * Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert)
style operation for an {@link Vertex} using a
+ * {@code Map} as an argument. The {@code Map} represents search
criteria and will match each of the supplied
+ * key/value pairs where the keys may be {@code String} property
values or a value of {@link T}. If a match is not
+ * made it will use that search criteria to create the new {@link
Vertex}.
+ *
+ * @param searchCreate This {@code Map} can have a key of {@link T} or
a {@code String}.
+ * @since 4.0.0
+ */
+ public GraphTraversal<Vertex, Vertex> mergeV(final GValue<Map<Object,
Object>> searchCreate) {
+ final GraphTraversalSource clone =
GraphTraversalSource.this.clone();
+ clone.bytecode.addStep(GraphTraversal.Symbols.mergeV,
searchCreate);
+ final GraphTraversal.Admin<Vertex, Vertex> traversal = new
DefaultGraphTraversal<>(clone);
+ return traversal.addStep(new MergeVertexStep(traversal, true,
searchCreate));
+ }
+
+ /**
+ * Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert)
style operation for an {@link Edge} using a
+ * {@code Map} as an argument.
+ *
+ * @param searchCreate This {@code Map} can have a key of {@link T}
{@link Direction} or a {@code String}.
+ * @since 4.0.0
+ */
+ public GraphTraversal<Edge, Edge> mergeE(final GValue<Map<?, Object>>
searchCreate) {
+ final GraphTraversalSource clone =
GraphTraversalSource.this.clone();
+ clone.bytecode.addStep(GraphTraversal.Symbols.mergeE,
searchCreate);
+ final GraphTraversal.Admin<Edge, Edge> traversal = new
DefaultGraphTraversal<>(clone);
+ return traversal.addStep(new MergeEdgeStep(traversal, true,
searchCreate));
+ }
+ }
}
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GType.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GType.java
index 89a8b79098..23dd8be5f2 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GType.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GType.java
@@ -52,12 +52,26 @@ public enum GType {
GType() {}
/**
- * Returns true if the type is a number.
+ * Returns {@code true} if the type is a number.
*/
public boolean isNumeric() {
return this == INTEGER || this == DOUBLE || this == LONG || this ==
BIG_INTEGER || this == BIG_DECIMAL;
}
+ /**
+ * Returns {@code true} if the type is a collection.v
+ */
+ public boolean isCollection() {
+ return this == LIST || this == SET;
+ }
+
+ /**
+ * Returns {@code true} if the type is an element.
+ */
+ public boolean isElement() {
+ return this == VERTEX || this == EDGE;
+ }
+
/**
* Convert an object to a matching {@link GType} and if not matched return
{@link GType#UNKNOWN}.
*/
@@ -78,4 +92,4 @@ public enum GType {
else if (object instanceof BigDecimal) return BIG_DECIMAL;
else return UNKNOWN;
}
-}
+}
\ No newline at end of file
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValue.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValue.java
index 4de2ca1f8e..a7271c3ad9 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValue.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValue.java
@@ -66,8 +66,8 @@ public class GValue<V> implements Cloneable, Serializable {
/**
* Gets the name of the variable if it was defined as such and returns
empty if the value was a literal.
*/
- public Optional<String> getName() {
- return Optional.ofNullable(this.name);
+ public String getName() {
+ return this.name;
}
/**
@@ -79,6 +79,13 @@ public class GValue<V> implements Cloneable, Serializable {
return this.type;
}
+ /**
+ * Determines if the value held is of a {@code null} value.
+ */
+ public boolean isNull() {
+ return this.value == null;
+ }
+
/**
* Gets the value.
*/
@@ -96,7 +103,7 @@ public class GValue<V> implements Cloneable, Serializable {
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- GValue<?> gValue = (GValue<?>) o;
+ final GValue<?> gValue = (GValue<?>) o;
return Objects.equals(name, gValue.name) && type == gValue.type &&
Objects.equals(value, gValue.value);
}
@@ -123,6 +130,7 @@ public class GValue<V> implements Cloneable, Serializable {
public static <V> GValue<V> of(final String name, final V value) {
return new GValue<>(name, GType.getType(value), value);
}
+
/**
* Create a new {@code GValue} for a string value.
*/
@@ -238,14 +246,14 @@ public class GValue<V> implements Cloneable, Serializable
{
/**
* Create a new {@code GValue} for a list value.
*/
- public static GValue<List> ofList(final List value) {
+ public static <T> GValue<List<T>> ofList(final List<T> value) {
return new GValue<>(GType.LIST, value);
}
/**
* Create a new {@code GValue} for a list value with a specified name.
*/
- public static GValue<List> ofList(final String name, final List value) {
+ public static <T> GValue<List<T>> ofList(final String name, final List<T>
value) {
return new GValue<>(name, GType.LIST, value);
}
@@ -318,4 +326,4 @@ public class GValue<V> implements Cloneable, Serializable {
public static GValue<Property> ofProperty(final String name, final
Property value) {
return new GValue<>(name, GType.PROPERTY, value);
}
-}
+}
\ No newline at end of file
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectStep.java
index 0502f18541..e22bbaa382 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/InjectStep.java
@@ -19,6 +19,7 @@
package org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
import org.apache.tinkerpop.gremlin.util.iterator.ArrayIterator;
/**
@@ -26,29 +27,32 @@ import
org.apache.tinkerpop.gremlin.util.iterator.ArrayIterator;
*/
public final class InjectStep<S> extends StartStep<S> {
- private final S[] injections;
+ private final GValue<S>[] injections;
@SafeVarargs
public InjectStep(final Traversal.Admin traversal, final S... injections) {
super(traversal);
- this.injections = injections;
- this.start = new ArrayIterator<>(this.injections);
+ this.injections = convertToGValues(injections);
+ this.start = new ArrayIterator<>(resolveToValues(this.injections));
}
@Override
public InjectStep<S> clone() {
final InjectStep<S> clone = (InjectStep<S>) super.clone();
- clone.start = new ArrayIterator<>(clone.injections);
+ clone.start = new ArrayIterator<>(resolveToValues(clone.injections));
return clone;
}
@Override
public void reset() {
super.reset();
- this.start = new ArrayIterator<>(this.injections);
+ this.start = new ArrayIterator<>(resolveToValues(this.injections));
}
- public S[] getInjections() {
+ /**
+ * Get the injections of the step.
+ */
+ public GValue<S>[] getInjections() {
return this.injections;
}
-}
+}
\ No newline at end of file
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
index d4545ead5c..94c5866b14 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
@@ -21,6 +21,7 @@ package
org.apache.tinkerpop.gremlin.process.traversal.step.util;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
import
org.apache.tinkerpop.gremlin.process.traversal.traverser.util.EmptyTraverser;
import
org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
@@ -30,9 +31,11 @@ import
org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
+import java.util.stream.Stream;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -229,4 +232,44 @@ public abstract class AbstractStep<S, E> implements
Step<S, E> {
return traverser;
}
+ /**
+ * The elements in object array argument are examined to see if they are
{@link GValue} objects. If they are, they
+ * are preserved as is. If they are not then they are wrapped in a {@link
GValue} object.
+ */
+ protected static <T> GValue<T>[] convertToGValues(final Object[] args) {
+ return Stream.of(args).map(id -> {
+ if (id instanceof GValue)
+ return (GValue<?>) id;
+ else
+ return GValue.of(id);
+ }).toArray(GValue[]::new);
+ }
+
+ /**
+ * Converts {@link GValue} objects arguments to their values to prevent
them from leaking to the Graph API.
+ * Providers extending from this step should use this method to get actual
values to prevent any {@link GValue}
+ * objects from leaking to the Graph API.
+ */
+ protected Object[] resolveToValues(final List<GValue<?>> gvalues) {
+ // convert gvalues to array
+ final Object[] newIds = new Object[gvalues.size()];
+ int i = 0;
+ for (final GValue<?> gvalue : gvalues) {
+ newIds[i++] = gvalue.get();
+ }
+ return newIds;
+ }
+
+ /**
+ * Converts {@link GValue} objects argument array to their values to
prevent them from leaking to the Graph API.
+ * Providers extending from this step should use this method to get actual
values to prevent any {@link GValue}
+ * objects from leaking to the Graph API.
+ */
+ protected Object[] resolveToValues(final GValue<?>[] gvalues) {
+ final Object[] newIds = new Object[gvalues.length];
+ for (int i = 0; i < gvalues.length; i++) {
+ newIds[i] = gvalues[i].get();
+ }
+ return newIds;
+ }
}
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
index c20c68fde0..d62c366a4c 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
@@ -19,6 +19,8 @@
package org.apache.tinkerpop.gremlin.process.traversal.step.util;
import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GType;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
import org.apache.tinkerpop.gremlin.structure.Element;
import org.apache.tinkerpop.gremlin.structure.Property;
import org.apache.tinkerpop.gremlin.structure.T;
@@ -154,11 +156,11 @@ public class HasContainer implements Serializable,
Cloneable, Predicate<Element>
if (predicateValue instanceof Collection) {
final Collection collection = (Collection) predicateValue;
if (!collection.isEmpty()) {
- return ((Collection) predicateValue).stream().allMatch(c
-> null == c || c instanceof String);
+ return ((Collection) predicateValue).stream().allMatch(c
-> null == c || c instanceof String || (c instanceof GValue && ((GValue)
c).getType() == GType.STRING));
}
}
- return predicateValue instanceof String;
+ return predicateValue instanceof String || (predicateValue
instanceof GValue && ((GValue) predicateValue).getType() == GType.STRING);
}
return false;
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SideEffectStrategy.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SideEffectStrategy.java
index ce794b8b6a..9b309dba3f 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SideEffectStrategy.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SideEffectStrategy.java
@@ -22,6 +22,7 @@ package
org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
import
org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier;
@@ -60,7 +61,11 @@ public final class SideEffectStrategy extends
AbstractTraversalStrategy<Traversa
strategy = cloneStrategy;
traversalStrategies.addStrategies(strategy);
}
- strategy.sideEffects.add(new Triplet<>(key, value instanceof Supplier
? (Supplier) value : new ConstantSupplier<>(value), reducer));
+
+ // don't want the GValue to leak beyond strategy application or else
the Supplier will start producing it
+ // during execution
+ final ConstantSupplier initialValue = value instanceof GValue ? new
ConstantSupplier<>(((GValue) value).get()) : new ConstantSupplier<>(value);
+ strategy.sideEffects.add(new Triplet<>(key, value instanceof Supplier
? (Supplier) value : initialValue, reducer));
}
public boolean contains(final String sideEffectKey) {
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValueTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValueTest.java
index fcfac9b9d9..f4ae56dff8 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValueTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/GValueTest.java
@@ -54,7 +54,7 @@ public class GValueTest {
final GValue<Integer> gValue = GValue.of("varName", 123);
assertEquals(123, gValue.get().intValue());
assertEquals(GType.INTEGER, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -71,7 +71,7 @@ public class GValueTest {
final GValue<String> gValue = GValue.ofString("varName", "test");
assertEquals("test", gValue.get());
assertEquals(GType.STRING, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -88,7 +88,7 @@ public class GValueTest {
final GValue<Integer> gValue = GValue.ofInteger("varName", 123);
assertEquals(123, gValue.get().intValue());
assertEquals(GType.INTEGER, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -105,7 +105,7 @@ public class GValueTest {
final GValue<Boolean> gValue = GValue.ofBoolean("varName", true);
assertEquals(true, gValue.get());
assertEquals(GType.BOOLEAN, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -122,7 +122,7 @@ public class GValueTest {
final GValue<Double> gValue = GValue.ofDouble("varName", 123.45);
assertEquals(123.45, gValue.get(), 0.0);
assertEquals(GType.DOUBLE, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -139,7 +139,7 @@ public class GValueTest {
final GValue<BigInteger> gValue = GValue.ofBigInteger("varName",
BigInteger.ONE);
assertEquals(BigInteger.ONE, gValue.get());
assertEquals(GType.BIG_INTEGER, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -156,7 +156,7 @@ public class GValueTest {
final GValue<BigDecimal> gValue = GValue.ofBigDecimal("varName",
BigDecimal.ONE);
assertEquals(BigDecimal.ONE, gValue.get());
assertEquals(GType.BIG_DECIMAL, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -173,7 +173,7 @@ public class GValueTest {
final GValue<Long> gValue = GValue.ofLong("varName", 123L);
assertEquals(123L, gValue.get().longValue());
assertEquals(GType.LONG, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -196,14 +196,14 @@ public class GValueTest {
final GValue<Map> gValue = GValue.ofMap("varName", map);
assertEquals(map, gValue.get());
assertEquals(GType.MAP, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@Test
public void shouldCreateGValueFromList() {
final List<String> list = Arrays.asList("value1", "value2");
- final GValue<List> gValue = GValue.ofList(list);
+ final GValue<List<String>> gValue = GValue.ofList(list);
assertEquals(list, gValue.get());
assertEquals(GType.LIST, gValue.getType());
assertThat(gValue.isVariable(), is(false));
@@ -212,10 +212,10 @@ public class GValueTest {
@Test
public void shouldCreateGValueFromListWithName() {
final List<String> list = Arrays.asList("value1", "value2");
- final GValue<List> gValue = GValue.ofList("varName", list);
+ final GValue<List<String>> gValue = GValue.ofList("varName", list);
assertEquals(list, gValue.get());
assertEquals(GType.LIST, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -234,7 +234,7 @@ public class GValueTest {
final GValue<Set> gValue = GValue.ofSet("varName", set);
assertEquals(set, gValue.get());
assertEquals(GType.SET, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -253,7 +253,7 @@ public class GValueTest {
final GValue<Vertex> gValue = GValue.ofVertex("varName", vertex);
assertEquals(vertex, gValue.get());
assertEquals(GType.VERTEX, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -272,7 +272,7 @@ public class GValueTest {
final GValue<Edge> gValue = GValue.ofEdge("varName", edge);
assertEquals(edge, gValue.get());
assertEquals(GType.EDGE, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -291,7 +291,7 @@ public class GValueTest {
final GValue<Path> gValue = GValue.ofPath("varName", path);
assertEquals(path, gValue.get());
assertEquals(GType.PATH, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
@@ -310,7 +310,7 @@ public class GValueTest {
final GValue<Property> gValue = GValue.ofProperty("varName", property);
assertEquals(property, gValue.get());
assertEquals(GType.PROPERTY, gValue.getType());
- assertEquals("varName", gValue.getName().get());
+ assertEquals("varName", gValue.getName());
assertThat(gValue.isVariable(), is(true));
}
}
\ No newline at end of file