You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2025/03/21 10:56:32 UTC

(tinkerpop) 04/04: TINKERPOP-3088 Retain lower common type for sum() global

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

spmallette pushed a commit to branch bp-time
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 2b0b2ebf9ce3e8ad2522817b78fe51876918d5e8
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Fri Oct 11 13:27:50 2024 -0400

    TINKERPOP-3088 Retain lower common type for sum() global
    
    The multiplication of the traverser value by the bulk was promoting the type to long so that even if the values were all int and fitting well within that space you'd still end up with a long value.
---
 CHANGELOG.asciidoc                                 |   1 +
 .../translator/DotNetTranslateVisitor.java         |   8 +-
 .../process/traversal/step/map/SumGlobalStep.java  |  11 +-
 .../tinkerpop/gremlin/util/NumberHelper.java       |  44 +++++++
 .../language/translator/GremlinTranslatorTest.java |   6 +-
 .../tinkerpop/gremlin/util/NumberHelperTest.java   |  96 +++++++++++++++
 gremlin-dotnet/build/generate.groovy               |   1 +
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs |  11 ++
 gremlin-go/driver/cucumber/gremlin.go              |  10 ++
 .../gremlin-javascript/test/cucumber/gremlin.js    |  10 ++
 gremlin-python/src/main/python/radish/gremlin.py   |  10 ++
 .../gremlin/server/GremlinServerIntegrateTest.java |   4 +-
 .../tinkerpop/gremlin/features/StepDefinition.java |  17 +--
 .../process/computer/GraphComputerTest.java        |  12 +-
 .../traversal/step/sideEffect/GroupTest.java       |   4 +-
 .../gremlin/test/features/map/Sum.feature          | 130 ++++++++++++++++++++-
 .../gremlin/test/features/sideEffect/Group.feature |   4 +-
 .../test/features/sideEffect/SideEffectCap.feature |   2 +-
 .../interceptor/SparkStarBarrierInterceptor.java   |   7 +-
 .../optimization/SparkInterceptorStrategyTest.java |   4 +-
 .../gremlin/spark/structure/io/InputRDDTest.java   |   2 +-
 21 files changed, 352 insertions(+), 42 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 926c9dd66c..c444bbd2f1 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -30,6 +30,7 @@ This release also includes changes from <<release-3-7-XXX, 3.7.XXX>>.
 * Added `with()` on `AnonymousTraversalSource` to cover both embedded and remote creation options.
 * Added support for `Set` in GraphSON and GraphBinary serialization for `gremlin-javascript`, where it previously just converted to array.
 * Added `Set` syntax in `gremlin-language`.
+* Changed `sum()` to retain the type common to the stream rather than always promoting to `long` given the need for it to multiple by the `long` bulk value for the traverser.
 * Removed the deprecated `withGraph()` option from `AnonymousTraversalSource`.
 * Modified the `split()` step to split a string into a list of its characters if the given separator is an empty string.
 * Added `withoutStrategies()` syntax to the Gremlin ANTLR grammar.
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java
index 2701819624..0e552bb560 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java
@@ -104,14 +104,18 @@ public class DotNetTranslateVisitor extends AbstractTranslateVisitor {
                 sb.append(integerLiteral, 0, lastCharIndex);
                 break;
             case 'i':
-            case 'n':
-                // parse I/i as integer. no BigInteger so just remove the N/n
+                // parse I/i as integer.
                 sb.append(integerLiteral, 0, lastCharIndex);
                 break;
             case 'l':
                 // parse L/l as long
                 sb.append(integerLiteral);
                 break;
+            case 'n':
+                sb.append("new BigInteger(");
+                sb.append(integerLiteral, 0, lastCharIndex);
+                sb.append(")");
+                break;
             default:
                 // everything else just goes as specified
                 sb.append(integerLiteral);
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SumGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SumGlobalStep.java
index 21a61878ca..a85c1c751f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SumGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SumGlobalStep.java
@@ -23,12 +23,14 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
-import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.EnumSet;
 import java.util.Set;
 import java.util.function.BinaryOperator;
 
+import static org.apache.tinkerpop.gremlin.util.NumberHelper.coerceTo;
 import static org.apache.tinkerpop.gremlin.util.NumberHelper.mul;
 
 /**
@@ -68,7 +70,12 @@ public final class SumGlobalStep<S extends Number> extends ReducingBarrierStep<S
 
     @Override
     public S projectTraverser(final Traverser.Admin<S> traverser) {
-        return (S) mul(traverser.get(), traverser.bulk());
+        final S value = traverser.get();
+        final long bulk = traverser.bulk();
+
+        // force the bulk to the type of the value so that mul doesn't arbitrarily widen the type of the Number
+        final Class<? extends Number> clazz = null == value ? Long.class : value.getClass();
+        return (S) mul(value, coerceTo(bulk, clazz));
     }
 
     @Override
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/NumberHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/NumberHelper.java
index 2d1e6154ad..1010abd499 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/NumberHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/NumberHelper.java
@@ -573,6 +573,50 @@ public final class NumberHelper {
         return getHelper(clazz).cmp.apply(a, b);
     }
 
+    /**
+     * Coerces the given number to the specified numeric type if it can fit into it.
+     * Otherwise, retains the original type.
+     *
+     * @param a the number to be coerced
+     * @param clazz the target numeric type class
+     * @return the coerced number in the specified type or the original type if it cannot fit
+     * @throws IllegalArgumentException if the specified numeric type is unsupported
+     */
+    public static Number coerceTo(final Number a, final Class<? extends Number> clazz) {
+        if (a.getClass().equals(clazz)) {
+            return a;
+        } else if (clazz.equals(Integer.class)) {
+            if (a.longValue() >= Integer.MIN_VALUE && a.longValue() <= Integer.MAX_VALUE) {
+                return a.intValue();
+            }
+        } else if (clazz.equals(Long.class)) {
+            return a.longValue();
+        } else if (clazz.equals(Float.class)) {
+            if (a.doubleValue() >= -Float.MAX_VALUE && a.doubleValue() <= Float.MAX_VALUE) {
+                return a.floatValue();
+            }
+        } else if (clazz.equals(Double.class)) {
+            return a.doubleValue();
+        } else if (clazz.equals(Byte.class)) {
+            if (a.longValue() >= Byte.MIN_VALUE && a.longValue() <= Byte.MAX_VALUE) {
+                return a.byteValue();
+            }
+        } else if (clazz.equals(Short.class)) {
+            if (a.longValue() >= Short.MIN_VALUE && a.longValue() <= Short.MAX_VALUE) {
+                return a.shortValue();
+            }
+        } else if (clazz.equals(BigInteger.class)) {
+            return NumberHelper.bigIntegerValue(a);
+        } else if (clazz.equals(BigDecimal.class)) {
+            return NumberHelper.bigDecimalValue(a);
+        } else {
+            throw new IllegalArgumentException("Unsupported numeric type: " + clazz);
+        }
+
+        // return as-is since it didn't fit the type we wanted to coerce to
+        return a;
+    }
+
     private static NumberHelper getHelper(final Class<? extends Number> clazz) {
         if (clazz.equals(Byte.class)) {
             return BYTE_NUMBER_HELPER;
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/translator/GremlinTranslatorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/translator/GremlinTranslatorTest.java
index 558df4dc13..4558634508 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/translator/GremlinTranslatorTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/translator/GremlinTranslatorTest.java
@@ -442,7 +442,7 @@ public class GremlinTranslatorTest {
                     {"g.with('x', 1n)",
                             null,
                             "g.with(string0, biginteger0)",
-                            "g.With(\"x\", 1)",
+                            "g.With(\"x\", new BigInteger(1))",
                             "g.With(\"x\", 1)",
                             "g.with('x', 1g)",
                             "g.with(\"x\", new BigInteger(\"1\"))",
@@ -451,7 +451,7 @@ public class GremlinTranslatorTest {
                     {"g.with('x', 1N)",
                             "g.with('x', 1n)",
                             "g.with(string0, biginteger0)",
-                            "g.With(\"x\", 1)",
+                            "g.With(\"x\", new BigInteger(1))",
                             "g.With(\"x\", 1)",
                             "g.with('x', 1g)",
                             "g.with(\"x\", new BigInteger(\"1\"))",
@@ -460,7 +460,7 @@ public class GremlinTranslatorTest {
                     {"g.with('x', -1n)",
                             null,
                             "g.with(string0, biginteger0)",
-                            "g.With(\"x\", -1)",
+                            "g.With(\"x\", new BigInteger(-1))",
                             "g.With(\"x\", -1)",
                             "g.with('x', -1g)",
                             "g.with(\"x\", new BigInteger(\"-1\"))",
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/NumberHelperTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/NumberHelperTest.java
index d8aed24bea..0c36889239 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/NumberHelperTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/util/NumberHelperTest.java
@@ -479,4 +479,100 @@ public class NumberHelperTest {
             }
         }
     }
+
+    @Test
+    public void shouldCoerceToReturnSameInstanceForSameClass() {
+        final Integer value = 42;
+        assertEquals(value, NumberHelper.coerceTo(value, Integer.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToByte() {
+        final Integer value = 42;
+        assertEquals(Byte.valueOf((byte) 42), NumberHelper.coerceTo(value, Byte.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToShort() {
+        final Integer value = 42;
+        assertEquals(Short.valueOf((short) 42), NumberHelper.coerceTo(value, Short.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToLong() {
+        final Integer value = 42;
+        assertEquals(Long.valueOf(42L), NumberHelper.coerceTo(value, Long.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToFloat() {
+        final Integer value = 42;
+        assertEquals(Float.valueOf(42.0f), NumberHelper.coerceTo(value, Float.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToDouble() {
+        final Integer value = 42;
+        assertEquals(Double.valueOf(42.0), NumberHelper.coerceTo(value, Double.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToBigInteger() {
+        final Integer value = 42;
+        assertEquals(BigInteger.valueOf(42), NumberHelper.coerceTo(value, BigInteger.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToBigDecimal() {
+        final Integer value = 42;
+        assertEquals(BigDecimal.valueOf(42), NumberHelper.coerceTo(value, BigDecimal.class));
+    }
+
+    @Test
+    public void shouldCoerceToRetainOriginalTypeIfCannotFitInByte() {
+        final Integer value = 128;
+        assertEquals(value, NumberHelper.coerceTo(value, Byte.class));
+    }
+
+    @Test
+    public void shouldCoerceToRetainOriginalTypeIfCannotFitInShort() {
+        final Integer value = 32768;
+        assertEquals(value, NumberHelper.coerceTo(value, Short.class));
+    }
+
+    @Test
+    public void shouldCoerceToRetainOriginalTypeIfCannotFitInInteger() {
+        final Long value = 2147483648L;
+        assertEquals(value, NumberHelper.coerceTo(value, Integer.class));
+    }
+
+    @Test
+    public void shouldCoerceToRetainOriginalTypeIfCannotFitInFloat() {
+        final Double value = Double.MAX_VALUE;
+        assertEquals(value, NumberHelper.coerceTo(value, Float.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToByteIfCanFit() {
+        final Integer value = 42;
+        assertEquals(Byte.valueOf((byte) 42), NumberHelper.coerceTo(value, Byte.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToShortIfCanFit() {
+        final Integer value = 42;
+        assertEquals(Short.valueOf((short) 42), NumberHelper.coerceTo(value, Short.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToIntegerIfCanFit() {
+        final Long value = 42L;
+        assertEquals(Integer.valueOf(42), NumberHelper.coerceTo(value, Integer.class));
+    }
+
+    @Test
+    public void shouldCoerceToConvertToFloatIfCanFit() {
+        final Double value = 42.0;
+        assertEquals(Float.valueOf(42.0f), NumberHelper.coerceTo(value, Float.class));
+    }
 }
diff --git a/gremlin-dotnet/build/generate.groovy b/gremlin-dotnet/build/generate.groovy
index 9936823093..0c2464d804 100644
--- a/gremlin-dotnet/build/generate.groovy
+++ b/gremlin-dotnet/build/generate.groovy
@@ -59,6 +59,7 @@ radishGremlinFile.withWriter('UTF-8') { Writer writer ->
     writer.writeLine("#nullable disable\n")
 
     writer.writeLine('using System;\n' +
+                     'using System.Numerics;\n' +
                      'using System.Collections.Generic;\n' +
                      'using Gremlin.Net.Structure;\n' +
                      'using Gremlin.Net.Process.Traversal;\n' +
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 4e83c7c0e4..9c1f3d4c8b 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -30,6 +30,7 @@
 #nullable disable
 
 using System;
+using System.Numerics;
 using System.Collections.Generic;
 using Gremlin.Net.Structure;
 using Gremlin.Net.Process.Traversal;
@@ -1241,6 +1242,16 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_injectXlistXnull_10_5_nullXX_sumXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(p["xx1"]).Sum<object>(Scope.Local)}}, 
                {"g_VX1X_valuesXageX_sumXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).Values<object>("age").Sum<object>(Scope.Local)}}, 
                {"g_V_localXunionXvaluesXageX_outE_valuesXweightXX_foldX_sumXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Local<object>(__.Union<object>(__.Values<object>("age"), __.OutE().Values<object>("weight")).Fold()).Sum<object>(Scope.Local)}}, 
+               {"g_V_age_injectX1000nX_sum", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Inject(new BigInteger(1000)).Sum<object>()}}, 
+               {"g_injectX1b_2b_3bX_sum", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>((byte) 1, (byte) 2, (byte) 3).Sum<object>()}}, 
+               {"g_injectX1b_2b_3sX_sum", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>((byte) 1, (byte) 2, (short) 3).Sum<object>()}}, 
+               {"g_injectX1b_26b_3iX_sum", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>((byte) 1, (byte) 2, 3).Sum<object>()}}, 
+               {"g_injectX1f_26f_3fX_sum", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(1f, 2f, 3f).Sum<object>()}}, 
+               {"g_V_age_injectX1000nX_fold_sumXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Inject(new BigInteger(1000)).Fold().Sum<object>(Scope.Local)}}, 
+               {"g_injectX1b_2b_3bX_fold_sumXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>((byte) 1, (byte) 2, (byte) 3).Fold().Sum<object>(Scope.Local)}}, 
+               {"g_injectX1b_2b_3sX_fold_sumXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>((byte) 1, (byte) 2, (short) 3).Fold().Sum<object>(Scope.Local)}}, 
+               {"g_injectX1b_26b_3iX_fold_sumXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>((byte) 1, (byte) 2, 3).Fold().Sum<object>(Scope.Local)}}, 
+               {"g_injectX1f_26f_3fX_fold_sumXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(1f, 2f, 3f).Fold().Sum<object>(Scope.Local)}}, 
                {"g_injectXfeature_test_nullX_toLower", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>("FEATURE", "tESt", null).ToLower()}}, 
                {"g_injectXfeature_test_nullX_toLowerXlocalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(p["xx1"]).ToLower<object>(Scope.Local)}}, 
                {"g_injectXListXa_bXX_toLower", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(p["xx1"]).ToLower()}}, 
diff --git a/gremlin-go/driver/cucumber/gremlin.go b/gremlin-go/driver/cucumber/gremlin.go
index 554c03c8e7..d485199dbe 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -1212,6 +1212,16 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
     "g_injectXlistXnull_10_5_nullXX_sumXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Sum(gremlingo.Scope.Local)}}, 
     "g_VX1X_valuesXageX_sumXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).Values("age").Sum(gremlingo.Scope.Local)}}, 
     "g_V_localXunionXvaluesXageX_outE_valuesXweightXX_foldX_sumXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Local(gremlingo.T__.Union(gremlingo.T__.Values("age"), gremlingo.T__.OutE().Values("weight")).Fold()).Sum(gremlingo.Scope.Local)}}, 
+    "g_V_age_injectX1000nX_sum": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Inject(1000).Sum()}}, 
+    "g_injectX1b_2b_3bX_sum": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(1, 2, 3).Sum()}}, 
+    "g_injectX1b_2b_3sX_sum": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(1, 2, 3).Sum()}}, 
+    "g_injectX1b_26b_3iX_sum": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(1, 2, 3).Sum()}}, 
+    "g_injectX1f_26f_3fX_sum": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(1, 2, 3).Sum()}}, 
+    "g_V_age_injectX1000nX_fold_sumXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Inject(1000).Fold().Sum(gremlingo.Scope.Local)}}, 
+    "g_injectX1b_2b_3bX_fold_sumXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(1, 2, 3).Fold().Sum(gremlingo.Scope.Local)}}, 
+    "g_injectX1b_2b_3sX_fold_sumXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(1, 2, 3).Fold().Sum(gremlingo.Scope.Local)}}, 
+    "g_injectX1b_26b_3iX_fold_sumXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(1, 2, 3).Fold().Sum(gremlingo.Scope.Local)}}, 
+    "g_injectX1f_26f_3fX_fold_sumXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(1, 2, 3).Fold().Sum(gremlingo.Scope.Local)}}, 
     "g_injectXfeature_test_nullX_toLower": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("FEATURE", "tESt", nil).ToLower()}}, 
     "g_injectXfeature_test_nullX_toLowerXlocalX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).ToLower(gremlingo.Scope.Local)}}, 
     "g_injectXListXa_bXX_toLower": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).ToLower()}}, 
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
index 2abdef9cfd..773738a261 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
@@ -1233,6 +1233,16 @@ const gremlins = {
     g_injectXlistXnull_10_5_nullXX_sumXlocalX: [function({g, xx1}) { return g.inject(xx1).sum(Scope.local) }], 
     g_VX1X_valuesXageX_sumXlocalX: [function({g, vid1}) { return g.V(vid1).values("age").sum(Scope.local) }], 
     g_V_localXunionXvaluesXageX_outE_valuesXweightXX_foldX_sumXlocalX: [function({g}) { return g.V().local(__.union(__.values("age"), __.outE().values("weight")).fold()).sum(Scope.local) }], 
+    g_V_age_injectX1000nX_sum: [function({g}) { return g.V().values("age").inject(1000).sum() }], 
+    g_injectX1b_2b_3bX_sum: [function({g}) { return g.inject(1, 2, 3).sum() }], 
+    g_injectX1b_2b_3sX_sum: [function({g}) { return g.inject(1, 2, 3).sum() }], 
+    g_injectX1b_26b_3iX_sum: [function({g}) { return g.inject(1, 2, 3).sum() }], 
+    g_injectX1f_26f_3fX_sum: [function({g}) { return g.inject(1, 2, 3).sum() }], 
+    g_V_age_injectX1000nX_fold_sumXlocalX: [function({g}) { return g.V().values("age").inject(1000).fold().sum(Scope.local) }], 
+    g_injectX1b_2b_3bX_fold_sumXlocalX: [function({g}) { return g.inject(1, 2, 3).fold().sum(Scope.local) }], 
+    g_injectX1b_2b_3sX_fold_sumXlocalX: [function({g}) { return g.inject(1, 2, 3).fold().sum(Scope.local) }], 
+    g_injectX1b_26b_3iX_fold_sumXlocalX: [function({g}) { return g.inject(1, 2, 3).fold().sum(Scope.local) }], 
+    g_injectX1f_26f_3fX_fold_sumXlocalX: [function({g}) { return g.inject(1, 2, 3).fold().sum(Scope.local) }], 
     g_injectXfeature_test_nullX_toLower: [function({g}) { return g.inject("FEATURE", "tESt", null).toLower() }], 
     g_injectXfeature_test_nullX_toLowerXlocalX: [function({g, xx1}) { return g.inject(xx1).toLower(Scope.local) }], 
     g_injectXListXa_bXX_toLower: [function({g, xx1}) { return g.inject(xx1).toLower() }], 
diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py
index b02b3773b4..4cce40358b 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -1215,6 +1215,16 @@ world.gremlins = {
     'g_injectXlistXnull_10_5_nullXX_sumXlocalX': [(lambda g, xx1=None:g.inject(xx1).sum_(Scope.local))], 
     'g_VX1X_valuesXageX_sumXlocalX': [(lambda g, vid1=None:g.V(vid1).values('age').sum_(Scope.local))], 
     'g_V_localXunionXvaluesXageX_outE_valuesXweightXX_foldX_sumXlocalX': [(lambda g:g.V().local(__.union(__.values('age'), __.out_e().values('weight')).fold()).sum_(Scope.local))], 
+    'g_V_age_injectX1000nX_sum': [(lambda g:g.V().values('age').inject(1000).sum_())], 
+    'g_injectX1b_2b_3bX_sum': [(lambda g:g.inject(1, 2, 3).sum_())], 
+    'g_injectX1b_2b_3sX_sum': [(lambda g:g.inject(1, 2, 3).sum_())], 
+    'g_injectX1b_26b_3iX_sum': [(lambda g:g.inject(1, 2, 3).sum_())], 
+    'g_injectX1f_26f_3fX_sum': [(lambda g:g.inject(1, 2, 3).sum_())], 
+    'g_V_age_injectX1000nX_fold_sumXlocalX': [(lambda g:g.V().values('age').inject(1000).fold().sum_(Scope.local))], 
+    'g_injectX1b_2b_3bX_fold_sumXlocalX': [(lambda g:g.inject(1, 2, 3).fold().sum_(Scope.local))], 
+    'g_injectX1b_2b_3sX_fold_sumXlocalX': [(lambda g:g.inject(1, 2, 3).fold().sum_(Scope.local))], 
+    'g_injectX1b_26b_3iX_fold_sumXlocalX': [(lambda g:g.inject(1, 2, 3).fold().sum_(Scope.local))], 
+    'g_injectX1f_26f_3fX_fold_sumXlocalX': [(lambda g:g.inject(1, 2, 3).fold().sum_(Scope.local))], 
     'g_injectXfeature_test_nullX_toLower': [(lambda g:g.inject('FEATURE', 'tESt', None).to_lower())], 
     'g_injectXfeature_test_nullX_toLowerXlocalX': [(lambda g, xx1=None:g.inject(xx1).to_lower(Scope.local))], 
     'g_injectXListXa_bXX_toLower': [(lambda g, xx1=None:g.inject(xx1).to_lower())], 
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index d644a9534d..05569f406d 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -1162,7 +1162,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
         final GraphTraversalSource g = traversal().withRemote(conf);
         g.addV("person").property("age", 20).iterate();
         g.addV("person").property("age", 10).iterate();
-        assertEquals(50L, g.V().hasLabel("person").map(Lambda.function("it.get().value('age') + 10")).sum().next());
+        assertEquals(50, g.V().hasLabel("person").map(Lambda.function("it.get().value('age') + 10")).sum().next());
         g.close();
     }
 
@@ -1171,7 +1171,7 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
         final GraphTraversalSource g = traversal().withRemote(conf);
         g.addV("person").property("age", 20).promise(Traversal::iterate).join();
         g.addV("person").property("age", 10).promise(Traversal::iterate).join();
-        assertEquals(50L, g.V().hasLabel("person").map(Lambda.function("it.get().value('age') + 10")).sum().promise(t -> t.next()).join());
+        assertEquals(50, g.V().hasLabel("person").map(Lambda.function("it.get().value('age') + 10")).sum().promise(t -> t.next()).join());
         g.addV("person").property("age", 20).promise(Traversal::iterate).join();
 
         final Traversal<Vertex,Integer> traversal = g.V().hasLabel("person").has("age", 20).values("age");
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
index 5d5b83bfad..13c6debeac 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
@@ -381,13 +381,6 @@ public final class StepDefinition {
         assertEquals(count.longValue(), ((GraphTraversal) parseGremlin(applyParameters(gremlin))).count().next());
     }
 
-    @Then("debug the graph should return {int} for count of {string}")
-    public void debugTheGraphShouldReturnForCountOf(final Integer count, final String gremlin) {
-        assertThatNoErrorWasThrown();
-
-        assertEquals(count.longValue(), ((GraphTraversal) parseGremlin(applyParameters(gremlin))).count().next());
-    }
-
     @Then("the result should be empty")
     public void theResultShouldBeEmpty() {
         assertThatNoErrorWasThrown();
@@ -598,7 +591,7 @@ public final class StepDefinition {
      * TinkerPop version of Hamcrest's {code containsInAnyOrder} that can use our custom assertions for {@link Path} and {@link Double}.
      */
     @SafeVarargs
-    public static <T> org.hamcrest.Matcher<Iterable<? extends T>> containsInAnyOrder(T... items) {
+    public static <T> org.hamcrest.Matcher<Iterable<? extends T>> containsInAnyOrder(final T... items) {
         return new IsIterableContainingInAnyOrder(getMatchers(items));
     }
 
@@ -606,25 +599,25 @@ public final class StepDefinition {
      * TinkerPop version of Hamcrest's {code contains} that can use our custom assertions for {@link Path} and {@link Double}.
      */
     @SafeVarargs
-    public static <T> org.hamcrest.Matcher<Iterable<? extends T>> contains(T... items) {
+    public static <T> org.hamcrest.Matcher<Iterable<? extends T>> contains(final T... items) {
         return new IsIterableContainingInOrder(getMatchers(items));
     }
 
     /**
      * TinkerPop version of Hamcrest's {code in} that can use our custom assertions for {@link Path}.
      */
-    public static <T> org.hamcrest.Matcher<T> in(Collection<T> collection) {
+    public static <T> org.hamcrest.Matcher<T> in(final Collection<T> collection) {
         return new IsInMatcher(collection);
     }
 
     /**
      * TinkerPop version of Hamcrest's {code in} that can use our custom assertions for {@link Path}.
      */
-    public static <T> org.hamcrest.Matcher<T> in(T[] elements) {
+    public static <T> org.hamcrest.Matcher<T> in(final T[] elements) {
         return new IsInMatcher(elements);
     }
 
-    private static <T> List<org.hamcrest.Matcher<? super T>> getMatchers(T[] items) {
+    private static <T> List<org.hamcrest.Matcher<? super T>> getMatchers(final T[] items) {
         final List<org.hamcrest.Matcher<? super T>> matchers = new ArrayList<>();
 
         for (int ix = 0; ix < items.length; ix++) {
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java
index d489a434d1..2648c66717 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java
@@ -1391,7 +1391,7 @@ public class GraphComputerTest extends AbstractGremlinProcessTest {
             assertEquals(Long.valueOf(0l), result.graph().traversal().E().count().next());
             assertEquals(Long.valueOf(18l), result.graph().traversal().V().values().count().next());
             assertEquals(Long.valueOf(0l), result.graph().traversal().E().values().count().next());
-            assertEquals(28l, result.graph().traversal().V().values("money").sum().next());
+            assertEquals(28, result.graph().traversal().V().values("money").sum().next());
             ///
             assertEquals(Long.valueOf(6l), graph.traversal().V().count().next());
             assertEquals(Long.valueOf(6l), graph.traversal().E().count().next());
@@ -1411,7 +1411,7 @@ public class GraphComputerTest extends AbstractGremlinProcessTest {
             assertEquals(Long.valueOf(6l), result.graph().traversal().E().count().next());
             assertEquals(Long.valueOf(18l), result.graph().traversal().V().values().count().next());
             assertEquals(Long.valueOf(6l), result.graph().traversal().E().values().count().next());
-            assertEquals(28l, result.graph().traversal().V().values("money").sum().next());
+            assertEquals(28, result.graph().traversal().V().values("money").sum().next());
             ///
             assertEquals(Long.valueOf(6l), graph.traversal().V().count().next());
             assertEquals(Long.valueOf(6l), graph.traversal().E().count().next());
@@ -1451,13 +1451,13 @@ public class GraphComputerTest extends AbstractGremlinProcessTest {
             assertEquals(Long.valueOf(6l), result.graph().traversal().E().count().next());
             assertEquals(Long.valueOf(18l), result.graph().traversal().V().values().count().next());
             assertEquals(Long.valueOf(6l), result.graph().traversal().E().values().count().next());
-            assertEquals(28l, result.graph().traversal().V().values("money").sum().next());
+            assertEquals(28, result.graph().traversal().V().values("money").sum().next());
             ///
             assertEquals(Long.valueOf(6l), graph.traversal().V().count().next());
             assertEquals(Long.valueOf(6l), graph.traversal().E().count().next());
             assertEquals(Long.valueOf(18l), graph.traversal().V().values().count().next());
             assertEquals(Long.valueOf(6l), graph.traversal().E().values().count().next());
-            assertEquals(28l, graph.traversal().V().values("money").sum().next());
+            assertEquals(28, graph.traversal().V().values("money").sum().next());
         }
     }
 
@@ -1471,13 +1471,13 @@ public class GraphComputerTest extends AbstractGremlinProcessTest {
             assertEquals(Long.valueOf(6l), result.graph().traversal().E().count().next());
             assertEquals(Long.valueOf(18l), result.graph().traversal().V().values().count().next());
             assertEquals(Long.valueOf(6l), result.graph().traversal().E().values().count().next());
-            assertEquals(28l, result.graph().traversal().V().values("money").sum().next());
+            assertEquals(28, result.graph().traversal().V().values("money").sum().next());
             ///
             assertEquals(Long.valueOf(6l), graph.traversal().V().count().next());
             assertEquals(Long.valueOf(6l), graph.traversal().E().count().next());
             assertEquals(Long.valueOf(18l), graph.traversal().V().values().count().next());
             assertEquals(Long.valueOf(6l), graph.traversal().E().values().count().next());
-            assertEquals(28l, graph.traversal().V().values("money").sum().next());
+            assertEquals(28, graph.traversal().V().values("money").sum().next());
         }
     }
 
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupTest.java
index 897f2d2a67..277267a07c 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupTest.java
@@ -518,8 +518,8 @@ public abstract class GroupTest extends AbstractGremlinProcessTest {
         assertEquals(2, map.size());
         assertTrue(map.containsKey("ripple"));
         assertTrue(map.containsKey("lop"));
-        assertEquals(32L, map.get("ripple"));
-        assertEquals(96L, map.get("lop"));
+        assertEquals(32, map.get("ripple"));
+        assertEquals(96, map.get("lop"));
         assertFalse(traversal.hasNext());
     }
 
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Sum.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Sum.feature
index c5a475f292..0776345c3e 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Sum.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Sum.feature
@@ -27,7 +27,7 @@ Feature: Step - sum()
     When iterated to list
     Then the result should be unordered
       | result |
-      | d[123].l |
+      | d[123].i |
 
   Scenario: g_V_foo_sum
     Given the modern graph
@@ -104,7 +104,7 @@ Feature: Step - sum()
     When iterated to list
     Then the result should be unordered
       | result |
-      | d[123].l |
+      | d[123].i |
 
   # null values are ignored in sum() which is similar to sum aggregation works in SQL
   @WithProductiveByStrategy
@@ -117,7 +117,7 @@ Feature: Step - sum()
     When iterated to list
     Then the result should be unordered
       | result |
-      | d[123].l |
+      | d[123].i |
 
   Scenario: g_V_aggregateXaX_byXfooX_sumXlocalX
     Given the modern graph
@@ -176,7 +176,7 @@ Feature: Step - sum()
     When iterated to list
     Then the result should be unordered
       | result |
-      | d[15].l |
+      | d[15].i |
 
   @GraphComputerVerificationInjectionNotSupported
   Scenario: g_injectXlistXnull_10_5_nullXX_sumXlocalX
@@ -216,4 +216,124 @@ Feature: Step - sum()
       | d[30.9].d |
       | d[27].i |
       | d[33.4].d |
-      | d[35.2].d |
\ No newline at end of file
+      | d[35.2].d |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_V_age_injectX1000nX_sum
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").inject(1000n).sum()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1123].n |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1b_2b_3bX_sum
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(1b,2b,3b).sum()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[6].b |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1b_2b_3sX_sum
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(1b,2b,3s).sum()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[6].s |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1b_26b_3iX_sum
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(1b,2b,3i).sum()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[6].i |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1f_26f_3fX_sum
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(1f,2f,3f).sum()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[6].f |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_V_age_injectX1000nX_fold_sumXlocalX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values("age").inject(1000n).fold().sum(local)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1123].n |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1b_2b_3bX_fold_sumXlocalX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(1b,2b,3b).fold().sum(local)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[6].b |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1b_2b_3sX_fold_sumXlocalX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(1b,2b,3s).fold().sum(local)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[6].s |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1b_26b_3iX_fold_sumXlocalX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(1b,2b,3i).fold().sum(local)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[6].i |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1f_26f_3fX_fold_sumXlocalX
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(1f,2f,3f).fold().sum(local)
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[6].f |
\ No newline at end of file
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Group.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Group.feature
index a149db6344..a10f6d3fa6 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Group.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/Group.feature
@@ -171,7 +171,7 @@ Feature: Step - group()
     When iterated to list
     Then the result should be unordered
       | result |
-      | m[{"cover":{"followedBy":"d[777982].l"}, "":{"followedBy":"d[179350].l"}, "original":{"followedBy":"d[2185613].l"}}] |
+      | m[{"cover":{"followedBy":"d[777982].i"}, "":{"followedBy":"d[179350].i"}, "original":{"followedBy":"d[2185613].i"}}] |
 
   Scenario: g_V_group_byXlabelX_byXbothE_groupXaX_byXlabelX_byXweight_sumX_weight_sumX
     Given the modern graph
@@ -212,7 +212,7 @@ Feature: Step - group()
     When iterated to list
     Then the result should be unordered
       | result |
-      | m[{"ripple":"d[32].l", "lop":"d[96].l"}] |
+      | m[{"ripple":"d[32].i", "lop":"d[96].i"}] |
 
 
   Scenario: g_V_group_byXlabelX_byXlabel_countX
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/SideEffectCap.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/SideEffectCap.feature
index 3418f07925..ad702c06cc 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/SideEffectCap.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/sideEffect/SideEffectCap.feature
@@ -128,7 +128,7 @@ Feature: Step - cap()
     When iterated to list
     Then the result should be unordered
       | result |
-      | m[{"ripple":"d[32].l", "lop":"d[96].l"}] |
+      | m[{"ripple":"d[32].i", "lop":"d[96].i"}] |
 
   @GraphComputerVerificationStarGraphExceeded
   Scenario: g_V_groupXmX_byXnameX_byXinXknowsX_nameX_capXmX
diff --git a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/process/computer/traversal/strategy/optimization/interceptor/SparkStarBarrierInterceptor.java b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/process/computer/traversal/strategy/optimization/interceptor/SparkStarBarrierInterceptor.java
index 850e95a18d..adf992e8a3 100644
--- a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/process/computer/traversal/strategy/optimization/interceptor/SparkStarBarrierInterceptor.java
+++ b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/process/computer/traversal/strategy/optimization/interceptor/SparkStarBarrierInterceptor.java
@@ -101,8 +101,11 @@ public final class SparkStarBarrierInterceptor implements SparkVertexProgramInte
             result = nextRDD.map(Traverser::bulk).fold(0L, (a, b) -> a + b);
         else if (endStep instanceof SumGlobalStep) {
             result = nextRDD.isEmpty() ? null : nextRDD
-                    .map(traverser -> NumberHelper.mul(traverser.bulk(), (Number) traverser.get()))
-                    .fold(0, NumberHelper::add);
+                    .map(traverser -> {
+                        final Number n = (Number) traverser.get();
+                        final Class<? extends Number> clazz = null == n ? Long.class : n.getClass();
+                        return NumberHelper.mul(n, NumberHelper.coerceTo(traverser.bulk(), clazz));
+                    }).fold(0, NumberHelper::add);
         } else if (endStep instanceof MeanGlobalStep) {
             result = nextRDD.isEmpty() ? null : nextRDD
                     .map(traverser -> new MeanGlobalStep.MeanNumber((Number) traverser.get(), traverser.bulk()))
diff --git a/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/process/computer/traversal/strategy/optimization/SparkInterceptorStrategyTest.java b/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/process/computer/traversal/strategy/optimization/SparkInterceptorStrategyTest.java
index c43cadd324..6cdaf81dfb 100644
--- a/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/process/computer/traversal/strategy/optimization/SparkInterceptorStrategyTest.java
+++ b/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/process/computer/traversal/strategy/optimization/SparkInterceptorStrategyTest.java
@@ -127,8 +127,8 @@ public class SparkInterceptorStrategyTest extends AbstractSparkTest {
         test(SparkStarBarrierInterceptor.class, 6l, g.V().as("a").count());
         test(SparkStarBarrierInterceptor.class, 1l, g.V().has("name", "marko").as("a").values("name").as("b").count());
         test(SparkStarBarrierInterceptor.class, 4l, g.V().has(T.label, P.not(P.within("robot", "android")).and(P.within("person", "software"))).hasLabel("person").has("age").out("created").count());
-        test(SparkStarBarrierInterceptor.class, 123l, g.V().has("age").values("age").sum());
-        test(SparkStarBarrierInterceptor.class, 67l, g.V().has("age").has("age", P.gt(30)).values("age").sum());
+        test(SparkStarBarrierInterceptor.class, 123, g.V().has("age").values("age").sum());
+        test(SparkStarBarrierInterceptor.class, 67, g.V().has("age").has("age", P.gt(30)).values("age").sum());
         test(SparkStarBarrierInterceptor.class, 27, g.V().hasLabel("person").values("age").min());
         test(SparkStarBarrierInterceptor.class, 35, g.V().hasLabel("person").values("age").max());
         test(SparkStarBarrierInterceptor.class, new HashMap<String, Long>() {{
diff --git a/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/io/InputRDDTest.java b/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/io/InputRDDTest.java
index 11c4f48571..b87b2ddd40 100644
--- a/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/io/InputRDDTest.java
+++ b/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/io/InputRDDTest.java
@@ -52,7 +52,7 @@ public class InputRDDTest extends AbstractSparkTest {
         configuration.setProperty(Constants.GREMLIN_HADOOP_JARS_IN_DISTRIBUTED_CACHE, false);
         ////////
         Graph graph = GraphFactory.open(configuration);
-        assertEquals(123l, graph.traversal().withComputer(SparkGraphComputer.class).V().values("age").sum().next());
+        assertEquals(123, graph.traversal().withComputer(SparkGraphComputer.class).V().values("age").sum().next());
         assertEquals(Long.valueOf(4l), graph.traversal().withComputer(SparkGraphComputer.class).V().count().next());
     }