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

colegreer pushed a commit to branch 3.7-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/3.7-dev by this push:
     new c8ab132512 [TINKERPOP-3080] AggregateGlobalStep acceps all pre-defined 
Operators (#2616)
c8ab132512 is described below

commit c8ab132512d0148931a006143db7842d3ff7052c
Author: Norio Akagi <[email protected]>
AuthorDate: Tue Aug 27 17:03:45 2024 -0700

    [TINKERPOP-3080] AggregateGlobalStep acceps all pre-defined Operators 
(#2616)
---
 CHANGELOG.asciidoc                                 |   1 +
 .../grammar/TraversalSourceSelfMethodVisitor.java  |  11 +-
 .../gremlin/process/traversal/Operator.java        |   4 +-
 .../step/sideEffect/AggregateGlobalStep.java       |  19 +-
 .../step/sideEffect/AggregateLocalStep.java        |  15 +-
 .../verification/ComputerVerificationStrategy.java |  24 +-
 .../TraversalSourceSelfMethodVisitorTest.java      |   2 +
 .../gremlin/process/traversal/OperatorTest.java    |   1 +
 gremlin-language/src/main/antlr4/Gremlin.g4        |   1 +
 .../test/features/sideEffect/Aggregate.feature     | 462 +++++++++++++++++----
 10 files changed, 440 insertions(+), 100 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 77968d6d81..f20ba908f8 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -37,6 +37,7 @@ This release also includes changes from <<release-3-6-8, 
3.6.8>>.
 * Fixed an issue where missing necessary parameters for logging, resulting in 
'%!x(MISSING)' output in `gremlin-go`.
 * Added getter method to `ConcatStep`, `ConjoinStep`, `SplitGlobalStep` and 
`SplitLocalStep` for their private fields.
 * Gremlin Server docker containers shutdown gracefully when receiving a 
SIGTERM.
+* TINKERPOP-3080 Support to specify Operator as a reducer in withSideEffect 
when parsing with the grammar
 
 [[release-3-7-2]]
 === TinkerPop 3.7.2 (April 8, 2024)
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalSourceSelfMethodVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalSourceSelfMethodVisitor.java
index 1df2b54afb..d968074729 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalSourceSelfMethodVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalSourceSelfMethodVisitor.java
@@ -85,8 +85,15 @@ public class TraversalSourceSelfMethodVisitor extends 
DefaultGremlinBaseVisitor<
      */
     @Override
     public GraphTraversalSource 
visitTraversalSourceSelfMethod_withSideEffect(final 
GremlinParser.TraversalSourceSelfMethod_withSideEffectContext ctx) {
-        return 
source.withSideEffect(antlr.argumentVisitor.parseString(ctx.stringArgument()),
-                
antlr.argumentVisitor.visitGenericLiteralArgument(ctx.genericLiteralArgument()));
+        if (ctx.getChildCount() < 8) {
+            // with 4 children withSideEffect() was called without a reducer 
specified.
+            return 
source.withSideEffect(antlr.argumentVisitor.parseString(ctx.stringArgument()),
+                    
antlr.argumentVisitor.visitGenericLiteralArgument(ctx.genericLiteralArgument()));
+        } else {
+            return 
source.withSideEffect(antlr.argumentVisitor.parseString(ctx.stringArgument()),
+                    
antlr.argumentVisitor.visitGenericLiteralArgument(ctx.genericLiteralArgument()),
+                    (BinaryOperator) 
antlr.argumentVisitor.visitTraversalBiFunctionArgument(ctx.traversalBiFunctionArgument()));
+        }
     }
 
     @Override
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..af9267b4a9 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
@@ -185,7 +185,7 @@ public enum Operator implements BinaryOperator<Object> {
             }
 
             if (a instanceof Map && b instanceof Map)
-                ((Map<?,?>) a).putAll((Map) b);
+                ((Map<?, ?>) a).putAll((Map) b);
             else if (a instanceof Collection && a instanceof Collection)
                 ((Collection<?>) a).addAll((Collection) b);
             else
@@ -204,5 +204,5 @@ public enum Operator implements BinaryOperator<Object> {
         public Object apply(final Object a, final Object b) {
             return (long) a + (long) b;
         }
-    }
+    };
 }
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AggregateGlobalStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AggregateGlobalStep.java
index c8fa203a3c..868b4e2260 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AggregateGlobalStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AggregateGlobalStep.java
@@ -20,6 +20,7 @@ package 
org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Operator;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalSideEffects;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
 import org.apache.tinkerpop.gremlin.process.traversal.step.LocalBarrier;
@@ -31,10 +32,8 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequire
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
 import 
org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementException;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.util.CloseableIterator;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.function.BulkSetSupplier;
-
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -122,8 +121,17 @@ public final class AggregateGlobalStep<S> extends 
AbstractStep<S, S> implements
 
     @Override
     public void processAllStarts() {
+        final TraversalSideEffects sideEffects = 
this.getTraversal().getSideEffects();
+
+        // addAll and assign operator collect solutions as a BulkSet. And 
addAll merges them with an existing
+        // sideEffect value which is expected to be Collection. assign 
replaces the existing value with the new BulkSet.
+        // Therefore, they need a different treatment how they gather inputs.
+        final boolean bulkReducingOperator = 
sideEffects.getReducer(sideEffectKey) == Operator.addAll ||
+                sideEffects.getReducer(sideEffectKey) == Operator.assign;
+
         if (this.starts.hasNext()) {
             final BulkSet<Object> bulkSet = new BulkSet<>();
+
             while (this.starts.hasNext()) {
                 final Traverser.Admin<S> traverser = this.starts.next();
                 TraversalUtil.produce(traverser, 
aggregateTraversal).ifProductive(p -> bulkSet.add(p, traverser.bulk()));
@@ -133,7 +141,12 @@ public final class AggregateGlobalStep<S> extends 
AbstractStep<S, S> implements
                 // when barrier is reloaded, the traversers should be at the 
next step
                 this.barrier.add(traverser);
             }
-            this.getTraversal().getSideEffects().add(this.sideEffectKey, 
bulkSet);
+
+            if (bulkReducingOperator) {
+                sideEffects.add(this.sideEffectKey, bulkSet);
+            } else {
+                bulkSet.forEach(p -> sideEffects.add(sideEffectKey, p));
+            }
         }
     }
 
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AggregateLocalStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AggregateLocalStep.java
index 7331caf23c..89970f55e0 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AggregateLocalStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AggregateLocalStep.java
@@ -20,6 +20,7 @@ package 
org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Operator;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalSideEffects;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
 import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
@@ -52,9 +53,21 @@ public final class AggregateLocalStep<S> extends 
SideEffectStep<S> implements Si
 
     @Override
     protected void sideEffect(final Traverser.Admin<S> traverser) {
+        final TraversalSideEffects sideEffects = 
this.getTraversal().getSideEffects();
+        // addAll and assign operator collect solutions as a BulkSet. And 
addAll merges them with an existing
+        // sideEffect value which is expected to be Collection. assign 
replaces the existing value with the new BulkSet.
+        // Therefore, they need a different treatment how they gather inputs.
+        final boolean isOperatorForBulkSet = 
sideEffects.getReducer(sideEffectKey) == Operator.addAll ||
+                sideEffects.getReducer(sideEffectKey) == Operator.assign;
+
         final BulkSet<Object> bulkSet = new BulkSet<>();
         TraversalUtil.produce(traverser, this.storeTraversal).ifProductive(p 
-> bulkSet.add(p, traverser.bulk()));
-        this.getTraversal().getSideEffects().add(this.sideEffectKey, bulkSet);
+
+        if (isOperatorForBulkSet) {
+            sideEffects.add(this.sideEffectKey, bulkSet);
+        } else {
+            bulkSet.forEach(p -> sideEffects.add(sideEffectKey, p));
+        }
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
index 890fade281..1c8eeebb57 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
@@ -21,16 +21,13 @@ package 
org.apache.tinkerpop.gremlin.process.traversal.strategy.verification;
 import 
org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.ComputerResultStep;
 import 
org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.TraversalVertexProgramStep;
 import 
org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.VertexProgramStep;
-import org.apache.tinkerpop.gremlin.process.traversal.Step;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.*;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Mutating;
 import org.apache.tinkerpop.gremlin.process.traversal.step.PathProcessor;
+import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ElementStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
-import 
org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IoStep;
-import 
org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SubgraphStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.*;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.ProfileStep;
 import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
@@ -40,6 +37,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.function.BinaryOperator;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -51,6 +49,13 @@ public final class ComputerVerificationStrategy extends 
AbstractTraversalStrateg
             InjectStep.class, Mutating.class, SubgraphStep.class, 
ComputerResultStep.class, IoStep.class, ElementStep.class
     ));
 
+    // Some operators output an indeterministic result when executed in 
GraphComputer.
+    // For now, we disable such operators. Operator.assign can have the same 
issue, however it is
+    // used in GraphComputer's code internally, so we don't disable it here.
+    private static final Set<Operator> UNSUPPORTED_OPERATORS = new 
HashSet<>(Arrays.asList(
+            Operator.minus, Operator.div
+    ));
+
     private ComputerVerificationStrategy() {
     }
 
@@ -80,6 +85,13 @@ public final class ComputerVerificationStrategy extends 
AbstractTraversalStrateg
 
             if (UNSUPPORTED_STEPS.stream().filter(c -> 
c.isAssignableFrom(step.getClass())).findFirst().isPresent())
                 throw new VerificationException("The following step is 
currently not supported on GraphComputer: " + step, traversal);
+
+            if (step instanceof SideEffectCapable) {
+                final BinaryOperator<?> sideEffectOperator = 
traversal.getSideEffects().getReducer(((SideEffectCapable<?, ?>) 
step).getSideEffectKey());
+                if (UNSUPPORTED_OPERATORS.stream().filter(o -> o == 
sideEffectOperator).findFirst().isPresent()) {
+                    throw new VerificationException("The following step has an 
SideEffect operator " + sideEffectOperator + " which is currently not supported 
on GraphComputer: " + step, traversal);
+                }
+            }
         }
 
         Step<?, ?> nextParentStep = traversal.getParent().asStep();
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalSourceSelfMethodVisitorTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalSourceSelfMethodVisitorTest.java
index 6c555c6c99..41eb40a533 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalSourceSelfMethodVisitorTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalSourceSelfMethodVisitorTest.java
@@ -57,6 +57,7 @@ public class TraversalSourceSelfMethodVisitorTest {
                 {"withSack('hello')", g.withSack("hello")},
                 {"withSack('hello', addAll)", g.withSack("hello", 
Operator.addAll)},
                 {"withSideEffect('hello', 12)", g.withSideEffect("hello", 12)},
+                {"withSideEffect('hello', 12, sum)", g.withSideEffect("hello", 
12, Operator.sum)},
                 {"withStrategies(ReadOnlyStrategy)", 
g.withStrategies(ReadOnlyStrategy.instance())},
                 {"withStrategies(new EdgeLabelVerificationStrategy(logWarning: 
true, throwException: true))", 
g.withStrategies(EdgeLabelVerificationStrategy.build().logWarning(true).throwException(true).create())},
                 {"withStrategies(ReadOnlyStrategy, new 
EdgeLabelVerificationStrategy(logWarning: true, throwException: true))", 
g.withStrategies(ReadOnlyStrategy.instance(), 
EdgeLabelVerificationStrategy.build().logWarning(true).throwException(true).create())},
@@ -65,6 +66,7 @@ public class TraversalSourceSelfMethodVisitorTest {
                 {"with('requestId')", g.with("requestId")},
                 {"withSideEffect('hello', ['one':1])", 
g.withSideEffect("hello", map)},
                 {"withSideEffect('hello', ['one' : 1])", 
g.withSideEffect("hello", map)},
+                {"withSideEffect('hello', ['one' : 1], Operator.addAll)", 
g.withSideEffect("hello", map, Operator.addAll)},
                 {"withSideEffect('hello', ['one':1, 'two':2])", 
g.withSideEffect("hello", new HashMap<String, Integer>() {{
                     put("one", 1);
                     put("two", 2);
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/OperatorTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/OperatorTest.java
index ce433c6c40..089dbf4bad 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/OperatorTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/OperatorTest.java
@@ -301,4 +301,5 @@ public class OperatorTest {
             return Integer.compare(n, anotherCustomNumber.n);
         }
     }
+
 }
diff --git a/gremlin-language/src/main/antlr4/Gremlin.g4 
b/gremlin-language/src/main/antlr4/Gremlin.g4
index 95b93e9e84..7268797beb 100644
--- a/gremlin-language/src/main/antlr4/Gremlin.g4
+++ b/gremlin-language/src/main/antlr4/Gremlin.g4
@@ -81,6 +81,7 @@ traversalSourceSelfMethod_withSack
 
 traversalSourceSelfMethod_withSideEffect
     : 'withSideEffect' LPAREN stringArgument COMMA genericLiteralArgument 
RPAREN
+    | 'withSideEffect' LPAREN stringArgument COMMA genericLiteralArgument 
COMMA traversalBiFunctionArgument RPAREN
     ;
 
 traversalSourceSelfMethod_withStrategies
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Aggregate.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Aggregate.feature
index 994e3cbd8f..f71282e50a 100644
--- 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Aggregate.feature
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Aggregate.feature
@@ -144,145 +144,435 @@ Feature: Step - aggregate()
   Scenario: g_V_aggregateXlocal_a_nameX_out_capXaX
     Given the modern graph
     And the traversal of
-      """
-      g.V().aggregate(Scope.local,"a").by("name").out().cap("a")
-      """
+    """
+    g.V().aggregate(Scope.local,"a").by("name").out().cap("a")
+    """
     When iterated next
     Then the result should be unordered
-      | result |
-      | marko |
-      | vadas |
-      | lop |
-      | josh |
-      | ripple |
-      | peter  |
+    | result |
+    | marko |
+    | vadas |
+    | lop |
+    | josh |
+    | ripple |
+    | peter  |
 
   Scenario: 
g_VX1X_aggregateXlocal_aX_byXnameX_out_aggregateXlocal_aX_byXnameX_name_capXaX
     Given the modern graph
     And using the parameter vid1 defined as "v[marko].id"
     And the traversal of
-      """
-      
g.V(vid1).aggregate(Scope.local,"a").by("name").out().aggregate(Scope.local,"a").by("name").values("name").cap("a")
-      """
+    """
+    
g.V(vid1).aggregate(Scope.local,"a").by("name").out().aggregate(Scope.local,"a").by("name").values("name").cap("a")
+    """
     When iterated next
     Then the result should be unordered
-      | result |
-      | marko |
-      | vadas |
-      | lop |
-      | josh |
+    | result |
+    | marko |
+    | vadas |
+    | lop |
+    | josh |
 
   Scenario: g_withSideEffectXa_setX_V_both_name_aggregateXlocal_aX_capXaX
     Given the modern graph
     And using the parameter xx1 defined as "s[]"
     And the traversal of
-      """
-      g.withSideEffect("a", 
xx1).V().both().values("name").aggregate(Scope.local,"a").cap("a")
-      """
+    """
+    g.withSideEffect("a", 
xx1).V().both().values("name").aggregate(Scope.local,"a").cap("a")
+    """
     When iterated next
     Then the result should be unordered
-      | result |
-      | marko |
-      | vadas |
-      | lop |
-      | josh |
-      | ripple |
-      | peter  |
+    | result |
+    | marko |
+    | vadas |
+    | lop |
+    | josh |
+    | ripple |
+    | peter  |
 
   Scenario: 
g_V_aggregateXlocal_aX_byXoutEXcreatedX_countX_out_out_aggregateXlocal_aX_byXinEXcreatedX_weight_sumX
     Given the modern graph
     And the traversal of
-      """
-      g.V().aggregate(Scope.local,"a").
-             by(__.outE("created").count()).
-        out().out().aggregate(Scope.local,"a").
-                      by(__.inE("created").values("weight").sum()).
-        cap("a")
-      """
+    """
+    g.V().aggregate(Scope.local,"a").
+    by(__.outE("created").count()).
+    out().out().aggregate(Scope.local,"a").
+    by(__.inE("created").values("weight").sum()).
+    cap("a")
+    """
     When iterated next
     Then the result should be unordered
-      | result |
-      | d[1].l |
-      | d[1].l |
-      | d[0].l |
-      | d[0].l |
-      | d[0].l |
-      | d[2].l |
-      | d[1.0].d |
-      | d[1.0].d |
+    | result |
+    | d[1].l |
+    | d[1].l |
+    | d[0].l |
+    | d[0].l |
+    | d[0].l |
+    | d[2].l |
+    | d[1.0].d |
+    | d[1.0].d |
 
   Scenario: g_V_aggregateXxX_byXvaluesXageX_isXgtX29XXX_capXxX
     Given the modern graph
     And the traversal of
-      """
-      g.V().aggregate("x").by(__.values("age").is(P.gt(29))).cap("x")
-      """
+    """
+    g.V().aggregate("x").by(__.values("age").is(P.gt(29))).cap("x")
+    """
     When iterated next
     Then the result should be unordered
-      | result |
-      | d[32].i |
-      | d[35].i |
+    | result |
+    | d[32].i |
+    | d[35].i |
 
   @WithProductiveByStrategy
   Scenario: 
g_withStrategiesXProductiveByStrategyX_V_aggregateXxX_byXvaluesXageX_isXgtX29XXX_capXxX
     Given the modern graph
     And the traversal of
-      """
-      
g.withStrategies(ProductiveByStrategy).V().aggregate("x").by(__.values("age").is(P.gt(29))).cap("x")
-      """
+    """
+    
g.withStrategies(ProductiveByStrategy).V().aggregate("x").by(__.values("age").is(P.gt(29))).cap("x")
+    """
     When iterated next
     Then the result should be unordered
-      | result |
-      | d[32].i |
-      | d[35].i |
-      | null |
-      | null |
-      | null |
-      | null |
+    | result |
+    | d[32].i |
+    | d[35].i |
+    | null |
+    | null |
+    | null |
+    | null |
 
   @GraphComputerVerificationStarGraphExceeded
   Scenario: g_V_aggregateXxX_byXout_order_byXnameXX_capXxX
     Given the modern graph
     And the traversal of
-      """
-      g.V().aggregate("x").by(__.out().order().by("name")).cap("x")
-      """
+    """
+    g.V().aggregate("x").by(__.out().order().by("name")).cap("x")
+    """
     When iterated next
     Then the result should be unordered
-      | result |
-      | v[josh] |
-      | v[lop] |
-      | v[lop] |
+    | result |
+    | v[josh] |
+    | v[lop] |
+    | v[lop] |
 
   @GraphComputerVerificationReferenceOnly @WithProductiveByStrategy
   Scenario: 
g_withStrategiesXProductiveByStrategyX_V_aggregateXxX_byXout_order_byXnameXX_capXxX
     Given the modern graph
     And the traversal of
-      """
-      
g.withStrategies(ProductiveByStrategy).V().aggregate("x").by(__.out().order().by("name")).cap("x")
-      """
+    """
+    
g.withStrategies(ProductiveByStrategy).V().aggregate("x").by(__.out().order().by("name")).cap("x")
+    """
     When iterated next
     Then the result should be unordered
-      | result |
-      | v[josh] |
-      | v[lop] |
-      | v[lop] |
-      | null |
-      | null |
-      | null |
+    | result |
+    | v[josh] |
+    | v[lop] |
+    | v[lop] |
+    | null |
+    | null |
+    | null |
 
   Scenario: 
g_V_aggregateXaX_hasXperson_age_gteX30XXX_capXaX_unfold_valuesXnameX
     Given the modern graph
     And the traversal of
-      """
-      g.V().aggregate("a").has("person","age", 
P.gte(30)).cap("a").unfold().values("name")
-      """
+    """
+    g.V().aggregate("a").has("person","age", 
P.gte(30)).cap("a").unfold().values("name")
+    """
+    When iterated to list
+    Then the result should be unordered
+    | result |
+    | marko |
+    | josh |
+    | peter |
+    | lop |
+    | vadas |
+    | ripple |
+
+  Scenario: g_withSideEffectXa_1_sumX_V_aggregateXaX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 1, 
Operator.sum).V().aggregate("a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+    | result   |
+    | d[124].i |
+
+  Scenario: g_withSideEffectXa_1_sumX_V_aggregateXlocal_aX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 1, Operator.sum).V().aggregate(Scope.local, 
"a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result   |
+      | d[124].i |
+
+  @GraphComputerVerificationStrategyNotSupported
+  Scenario: g_withSideEffectXa_123_minusX_V_aggregateXaX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 123, 
Operator.minus).V().aggregate("a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+    | result |
+    | d[0].i |
+
+  @GraphComputerVerificationStrategyNotSupported
+  Scenario: g_withSideEffectXa_123_minusX_V_aggregateXlocal_aX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 123, Operator.minus).V().aggregate(Scope.local, 
"a").by("age").cap("a")
+    """
     When iterated to list
     Then the result should be unordered
       | result |
-      | marko |
-      | josh |
-      | peter |
-      | lop |
-      | vadas |
-      | ripple |
\ No newline at end of file
+      | d[0].i |
+
+  Scenario: g_withSideEffectXa_2_multX_V_aggregateXaX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 2, 
Operator.mult).V().aggregate("a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+    | result |
+    | d[1753920].i |
+
+  Scenario: g_withSideEffectXa_2_multX_V_aggregateXlocal_aX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 2, Operator.mult).V().aggregate(Scope.local, 
"a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1753920].i |
+
+  @GraphComputerVerificationStrategyNotSupported
+  Scenario: g_withSideEffectXa_876960_divX_V_aggregateXaX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 876960, 
Operator.div).V().aggregate("a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+    | result |
+    | d[1].i |
+
+  @GraphComputerVerificationStrategyNotSupported
+  Scenario: g_withSideEffectXa_876960_divX_V_aggregateXlocal_aX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 876960, Operator.div).V().aggregate(Scope.local, 
"a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+
+  Scenario: g_withSideEffectXa_1_minX_V_aggregateXaX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 1, 
Operator.min).V().aggregate("a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+    | result |
+    | d[1].i |
+
+  Scenario: g_withSideEffectXa_1_minX_V_aggregateXlocal_aX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 1, Operator.min).V().aggregate(Scope.local, 
"a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+
+  Scenario: g_withSideEffectXa_100_minX_V_aggregateXaX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 100, 
Operator.min).V().aggregate("a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+    | result |
+    | d[27].i |
+
+  Scenario: g_withSideEffectXa_100_minX_V_aggregateXlocal_aX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 100, Operator.min).V().aggregate(Scope.local, 
"a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[27].i |
+
+  Scenario: g_withSideEffectXa_1_maxX_V_aggregateXaX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 1, 
Operator.max).V().aggregate("a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+    | result |
+    | d[35].i |
+
+  Scenario: g_withSideEffectXa_1_maxX_V_aggregateXlocal_aX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 1, Operator.max).V().aggregate(Scope.local, 
"a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[35].i |
+
+  Scenario: g_withSideEffectXa_100_maxX_V_aggregateXaX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 100, 
Operator.max).V().aggregate("a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+    | result |
+    | d[100].i |
+
+  Scenario: g_withSideEffectXa_100_maxX_V_aggregateXlocal_aX_byXageX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", 100, Operator.max).V().aggregate(Scope.local, 
"a").by("age").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[100].i |
+
+  Scenario: g_withSideEffectXa_true_andX_V_constantXfalseX_aggregateXaX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", true, 
Operator.and).V().constant(false).aggregate("a").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | false |
+
+  Scenario: 
g_withSideEffectXa_true_andX_V_constantXfalseX_aggregateXlocal_aX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", true, 
Operator.and).V().constant(false).aggregate(Scope.local, "a").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | false |
+
+  Scenario: g_withSideEffectXa_true_orX_V_constantXfalseX_aggregateXaX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", true, 
Operator.or).V().constant(false).aggregate("a").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | true |
+
+  Scenario: 
g_withSideEffectXa_true_orX_V_constantXfalseX_aggregateXlocal_aX_capXaX
+    Given the modern graph
+    And the traversal of
+    """
+    g.withSideEffect("a", true, 
Operator.or).V().constant(false).aggregate(Scope.local, "a").cap("a")
+    """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | true |
+
+  Scenario: g_withSideEffectXa_xx1_addAllX_V_aggregateXaX_byXageX_capXaX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[d[1].i,d[2].i,d[3].i]"
+    And the traversal of
+    """
+    g.withSideEffect("a", xx1, 
Operator.addAll).V().aggregate("a").by("age").cap("a")
+    """
+    When iterated next
+    Then the result should be unordered
+    | result |
+    | d[1].i |
+    | d[2].i |
+    | d[3].i |
+    | d[29].i |
+    | d[27].i |
+    | d[32].i |
+    | d[35].i |
+
+  Scenario: g_withSideEffectXa_xx1_addAllX_V_aggregateXlocal_aX_byXageX_capXaX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[d[1].i,d[2].i,d[3].i]"
+    And the traversal of
+    """
+    g.withSideEffect("a", xx1, Operator.addAll).V().aggregate(Scope.local, 
"a").by("age").cap("a")
+    """
+    When iterated next
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+      | d[2].i |
+      | d[3].i |
+      | d[29].i |
+      | d[27].i |
+      | d[32].i |
+      | d[35].i |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_withSideEffectXa_xx1_assignX_V_aggregateXaX_byXageX_capXaX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[d[1].i,d[2].i,d[3].i]"
+    And the traversal of
+    """
+    g.withSideEffect("a", xx1, 
Operator.assign).V().aggregate("a").by("age").cap("a")
+    """
+    When iterated next
+    Then the result should be unordered
+    | result |
+    | d[29].i |
+    | d[27].i |
+    | d[32].i |
+    | d[35].i |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: 
g_withSideEffectXa_xx1_assignX_V_order_byXageX_aggregateXlocal_aX_byXageX_capXaX
+    Given the modern graph
+    And using the parameter xx1 defined as "l[d[1].i,d[2].i,d[3].i]"
+    And the traversal of
+    # add order().by("age") to deterministically assign a vertex with the 
largest age value at the end
+    """
+    g.withSideEffect("a", xx1, 
Operator.assign).V().order().by("age").aggregate(Scope.local, 
"a").by("age").cap("a")
+    """
+    When iterated next
+    Then the result should be unordered
+      | result |
+      | d[35].i |

Reply via email to