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 2021/11/05 14:02:34 UTC

[tinkerpop] branch TINKERPOP-2524 created (now c2b4f2f)

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

spmallette pushed a change to branch TINKERPOP-2524
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git.


      at c2b4f2f  TINKERPOP-2524 Supported more explicit numeric literals in grammar

This branch includes the following new commits:

     new c2b4f2f  TINKERPOP-2524 Supported more explicit numeric literals in grammar

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[tinkerpop] 01/01: TINKERPOP-2524 Supported more explicit numeric literals in grammar

Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit c2b4f2fc0a02e0022602978faf21bea205e56460
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Fri Nov 5 09:57:00 2021 -0400

    TINKERPOP-2524 Supported more explicit numeric literals in grammar
    
    Added byte, short, BigInteger, BigDecimal which basically just follows the pattern Java/Groovy have with a character suffix. While these literals have some specific use for Gremlin users they also have importance to the gherkin test suite where validating numeric semantics required a wider range of numeric types in the test definitions.
---
 CHANGELOG.asciidoc                                 |   1 +
 docs/src/dev/developer/for-committers.asciidoc     |   9 +-
 .../language/grammar/GenericLiteralVisitor.java    |  40 ++++--
 .../grammar/GeneralLiteralVisitorTest.java         | 133 +++++++++---------
 .../Gherkin/CommonSteps.cs                         |   8 +-
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs |   7 +
 .../test/cucumber/feature-steps.js                 |   2 +-
 .../gremlin-javascript/test/cucumber/gremlin.js    |   7 +
 gremlin-language/src/main/antlr4/Gremlin.g4        |   4 +-
 .../src/main/python/radish/feature_steps.py        |   2 +-
 gremlin-python/src/main/python/radish/gremlin.py   |   7 +
 .../server/handler/SaslAuthenticationHandler.java  |   3 +-
 gremlin-test/features/semantics/Equality.feature   | 156 ++++++++++++++++++++-
 .../tinkerpop/gremlin/features/StepDefinition.java |  11 +-
 14 files changed, 291 insertions(+), 99 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index af06a51..f2c6522 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -31,6 +31,7 @@ limitations under the License.
 * Removed `groovy` and `groovy-json` dependencies from `gremlin-driver` as well as related `JsonBuilder` serialization support.
 * Replaced log4j usage with logback where builds rely on and packaged distributions now contain the latter.
 * Prevented metrics computation unless the traversal is in a locked state.
+* Added syntax to Gremlin grammar to explicitly define `byte`, `short` and `BigInteger`.
 * Created a way to produce a corpus of Gremlin traversals via `FeatureReader` and `DocumentationReader` in `gremlin-language`.
 * Exposed Gherkin tests as part of the provider test suite.
 * Packaged Gherkin tests and data as standalone package as a convenience distribution.
diff --git a/docs/src/dev/developer/for-committers.asciidoc b/docs/src/dev/developer/for-committers.asciidoc
index 33465ee..c3c3453 100644
--- a/docs/src/dev/developer/for-committers.asciidoc
+++ b/docs/src/dev/developer/for-committers.asciidoc
@@ -357,11 +357,14 @@ they are required for the test.
 the type notation system so that it is possible to have maps containing arbitrary keys and values.
 * Numeric - *d[_xxx_]._y_* - The "xxx" should be replaced with a number. The suffix denoted by "y" should always be
 included to further qualify the type of numeric. The following options are available:
-** *d* - 32-bit Double
-** *f* - 32-bit Float
+** *b* - 8-bit byte
+** *s* - 16-bit Short
 ** *i* - 32-bit Integer
+** *f* - 32-bit Float
 ** *l* - 64-bit Long
-** *m* - Arbitrary-precision signed decimal numbers (i.e. BigDecimal in Java)
+** *d* - 64-bit Double
+** *m* - Arbitrary-precision signed decimal numbers (e.g. `BigDecimal` in Java)
+** *n* - Arbitrary-precision integers (e.g. `BigInteger` in Java)
 * Path - *p[_xxx_,_yyy_,_zzz_,...]* - A comma separated collection of values that make up the `Path` should be added to
 between the square brackets. These values respect the type system thus allowing for creation of `Path` of vertices,
 edges, maps, and any other available type.
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
index 1529392..1d93387 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/GenericLiteralVisitor.java
@@ -308,12 +308,25 @@ public class GenericLiteralVisitor extends GremlinBaseVisitor<Object> {
     @Override
     public Object visitIntegerLiteral(final GremlinParser.IntegerLiteralContext ctx) {
         String integerLiteral = ctx.getText().toLowerCase().replace("_", "");
-        // handle suffix: L/l
+        // handle suffixes for specific types
         final int lastCharIndex = integerLiteral.length() - 1;
-        if (integerLiteral.charAt(lastCharIndex) == 'l') {
-            integerLiteral = integerLiteral.substring(0, lastCharIndex);
-
-            return Long.decode(integerLiteral);
+        final char suffix = integerLiteral.charAt(lastCharIndex);
+        switch (suffix) {
+            case 'b':
+                integerLiteral = integerLiteral.substring(0, lastCharIndex);
+                return Byte.decode(integerLiteral);
+            case 's':
+                integerLiteral = integerLiteral.substring(0, lastCharIndex);
+                return Short.decode(integerLiteral);
+            case 'i':
+                integerLiteral = integerLiteral.substring(0, lastCharIndex);
+                return Integer.decode(integerLiteral);
+            case 'l':
+                integerLiteral = integerLiteral.substring(0, lastCharIndex);
+                return Long.decode(integerLiteral);
+            case 'n':
+                integerLiteral = integerLiteral.substring(0, lastCharIndex);
+                return new BigInteger(integerLiteral);
         }
 
         try {
@@ -363,18 +376,19 @@ public class GenericLiteralVisitor extends GremlinBaseVisitor<Object> {
         final String floatLiteral = ctx.getText().toLowerCase();
 
         // check suffix
-        final char lastCharacter = floatLiteral.charAt(floatLiteral.length() - 1);
-        if (Character.isDigit(lastCharacter)) {
-            // if there is no suffix, parse it as BigDecimal
-            return new BigDecimal(floatLiteral);
-        }
-
-        if (lastCharacter == 'f') {
+        final int lastCharIndex = floatLiteral.length() - 1;
+        final char lastCharacter = floatLiteral.charAt(lastCharIndex);
+        if (lastCharacter == 'm') {
+            // parse M/m or whatever which could be a parse exception
+            return new BigDecimal(floatLiteral.substring(0, lastCharIndex));
+        } else if (lastCharacter == 'f') {
             // parse F/f suffix as Float
             return new Float(ctx.getText());
-        } else {
+        } else if (lastCharacter == 'd'){
             // parse D/d suffix as Double
             return new Double(floatLiteral);
+        } else {
+            return new BigDecimal(floatLiteral);
         }
     }
 
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
index c8a350e..7791a08 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/GeneralLiteralVisitorTest.java
@@ -292,44 +292,54 @@ public class GeneralLiteralVisitorTest {
         public String script;
 
         @Parameterized.Parameter(value = 1)
-        public String expected;
+        public Object expected;
 
         @Parameterized.Parameters(name = "{0}")
         public static Iterable<Object[]> generateTestParameters() {
             return Arrays.asList(new Object[][]{
                     // decimal format
-                    {"1", "1"},
-                    {"-11", "-11"},
-                    {"0", "0"},
-                    {"1L", "1L"},
-                    {"-1l", "-1l"},
-                    {"1_2_3", "123"},
-                    {"-1_2_3L", "-123L"},
-                    {"9223372036854775807", "9223372036854775807"},
-                    {"-9223372036854775808", "-9223372036854775808"},
-                    {"9223372036854775807L", "9223372036854775807"},
-                    {"-9223372036854775808l", "-9223372036854775808"},
+                    {"1", 1},
+                    {"-11", -11},
+                    {"0", 0},
+                    {"1B", (byte) 1},
+                    {"-1b", (byte) -1},
+                    {"1S", (short) 1},
+                    {"-1s", (short) -1},
+                    {"1I", 1},
+                    {"-1i", -1},
+                    {"1L", 1L},
+                    {"-1l", -1L},
+                    {"1_2_3", 123},
+                    {"-1_2_3L", -123L},
+                    {"1N", new BigInteger("1")},
+                    {"-1n", new BigInteger("-1")},
+                    {"9223372036854775807", 9223372036854775807L},
+                    {"-9223372036854775808", -9223372036854775808L},
+                    {"9223372036854775807L", 9223372036854775807L},
+                    {"-9223372036854775808l", -9223372036854775808L},
+                    {"9999999999999999999999999999999999999999999999999N", new BigInteger("9999999999999999999999999999999999999999999999999")},
+                    {"9999999999999999999999999999999999999999999999999n", new BigInteger("9999999999999999999999999999999999999999999999999")},
                     // hex format
-                    {"0xA", "10"},
-                    {"-0xA", "-10"},
-                    {"0xaL", "10l"},
-                    {"-0xal", "-10l"},
-                    {"-0xA_0L", "-160l"},
-                    {"0x10", "16"},
-                    {"-0x10", "-16"},
-                    {"0x10", "16"},
-                    {"-0x10l", "-16l"},
-                    {"-0x1_0L", "-16l"},
+                    {"0xA", 10},
+                    {"-0xA", -10},
+                    {"0xaL", 10L},
+                    {"-0xal", -10L},
+                    {"-0xA_0L", -160L},
+                    {"0x10", 16},
+                    {"-0x10", -16},
+                    {"0x10", 16},
+                    {"-0x10l", -16L},
+                    {"-0x1_0L", -16L},
                     // oct format
-                    {"01", "1"},
-                    {"-01", "-1"},
-                    {"01L", "1l"},
-                    {"-01l", "-1l"},
-                    {"010", "8"},
-                    {"-010", "-8"},
-                    {"010L", "8l"},
-                    {"-010l", "-8l"},
-                    {"-01_0L", "-8l"},
+                    {"01", 1},
+                    {"-01", -1},
+                    {"01L", 1L},
+                    {"-01l", -1L},
+                    {"010", 8},
+                    {"-010", -8},
+                    {"010L", 8L},
+                    {"-010l", -8L},
+                    {"-01_0L", -8L},
             });
         }
 
@@ -340,19 +350,7 @@ public class GeneralLiteralVisitorTest {
             final GremlinParser.IntegerLiteralContext ctx = parser.integerLiteral();
 
             final Object actualValue = GenericLiteralVisitor.getInstance().visitIntegerLiteral(ctx);
-
-            // verify suffix L/l
-            if (expected.toUpperCase().charAt(expected.length() - 1) == 'L') {
-                assertEquals(Long.valueOf(expected.substring(0, expected.length() - 1)), actualValue);
-                return;
-            }
-
-            // based on value range verify the value is parsed in correct type
-            try {
-                assertEquals(Integer.valueOf(expected), actualValue);
-            } catch (NumberFormatException ignoredException) {
-                assertEquals(Long.valueOf(expected), actualValue);
-            }
+            assertEquals(expected, actualValue);
         }
     }
 
@@ -398,34 +396,33 @@ public class GeneralLiteralVisitorTest {
         public String script;
 
         @Parameterized.Parameter(value = 1)
-        public String expected;
-
-        @Parameterized.Parameter(value = 2)
-        public String type;
+        public Object expected;
 
         @Parameterized.Parameters()
         public static Iterable<Object[]> generateTestParameters() {
             return Arrays.asList(new Object[][]{
-                    {"1.1", "1.1", "java.math.BigDecimal"},
-                    {"-0.1", "-0.1", "java.math.BigDecimal"},
-                    {"1.0E+12", "1.0E12", "java.math.BigDecimal"},
-                    {"-0.1E-12", "-0.1E-12", "java.math.BigDecimal"},
-                    {"1E12", "1E12", "java.math.BigDecimal"},
+                    {"1.1m", new BigDecimal("1.1")},
+                    {"1.1M", new BigDecimal("1.1")},
+                    {"1.1", new BigDecimal("1.1")},
+                    {"-0.1", new BigDecimal("-0.1")},
+                    {"1.0E+12", new BigDecimal("1.0E12")},
+                    {"-0.1E-12", new BigDecimal("-0.1E-12")},
+                    {"1E12", new BigDecimal("1E12")},
                     // float
-                    {"1.1f", "1.1", "java.lang.Float"},
-                    {"-0.1F", "-0.1", "java.lang.Float"},
-                    {"1.0E+12f", "1.0E12", "java.lang.Float"},
-                    {"-0.1E-12F", "-0.1E-12", "java.lang.Float"},
-                    {"1E12f", "1E12", "java.lang.Float"},
-                    {"1F", "1", "java.lang.Float"},
+                    {"1.1f", 1.1F},
+                    {"-0.1F", -0.1F},
+                    {"1.0E+12f", 1.0E12F},
+                    {"-0.1E-12F", -0.1E-12F},
+                    {"1E12f", 1E12F},
+                    {"1F", 1F},
 
                     // double
-                    {"1.1d", "1.1", "java.lang.Double"},
-                    {"-0.1D", "-0.1", "java.lang.Double"},
-                    {"1.0E+12d", "1.0E12", "java.lang.Double"},
-                    {"-0.1E-12D", "-0.1E-12", "java.lang.Double"},
-                    {"1E12d", "1E12", "java.lang.Double"},
-                    {"1D", "1", "java.lang.Double"}
+                    {"1.1d", 1.1D},
+                    {"-0.1D", -0.1D},
+                    {"1.0E+12d", 1.0E12D},
+                    {"-0.1E-12D", -0.1E-12D},
+                    {"1E12d", 1E12D},
+                    {"1D", 1D}
             });
         }
 
@@ -435,11 +432,7 @@ public class GeneralLiteralVisitorTest {
             final GremlinParser parser = new GremlinParser(new CommonTokenStream(lexer));
             final GremlinParser.FloatLiteralContext ctx = parser.floatLiteral();
 
-            final Class<?> clazz = Class.forName(type);
-            final Constructor<?> ctor = clazz.getConstructor(String.class);
-            final Object expectedValue = ctor.newInstance(expected);
-
-            assertEquals(expectedValue, GenericLiteralVisitor.getInstance().visitFloatLiteral(ctx));
+            assertEquals(expected, GenericLiteralVisitor.getInstance().visitFloatLiteral(ctx));
         }
     }
 
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
index a2941eb..11e71c8 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
@@ -26,6 +26,7 @@ using System.Collections;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
+using System.Numerics;
 using System.Text.Json;
 using System.Text.RegularExpressions;
 using Gherkin.Ast;
@@ -54,7 +55,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
         private static readonly IDictionary<Regex, Func<string, string, object>> Parsers =
             new Dictionary<string, Func<string, string, object>>
             {
-                {@"d\[(.*)\]\.([ilfdm])", ToNumber},
+                {@"d\[(.*)\]\.([bsilfdmn])", ToNumber},
                 {@"D\[(.+)\]", ToDirection},
                 {@"v\[(.+)\]", ToVertex},
                 {@"v\[(.+)\]\.id", (x, graphName) => ToVertex(x, graphName).Id},
@@ -74,11 +75,14 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
         private static readonly IDictionary<char, Func<string, object>> NumericParsers =
             new Dictionary<char, Func<string, object>>
             {
+                { 'b', s => Convert.ToByte(s) },
+                { 's', s => Convert.ToInt16(s) },
                 { 'i', s => Convert.ToInt32(s) },
                 { 'l', s => Convert.ToInt64(s) },
                 { 'f', s => Convert.ToSingle(s, CultureInfo.InvariantCulture) },
                 { 'd', s => Convert.ToDouble(s, CultureInfo.InvariantCulture) },
-                { 'm', s => Convert.ToDecimal(s, CultureInfo.InvariantCulture) }
+                { 'm', s => Convert.ToDecimal(s, CultureInfo.InvariantCulture) },
+                { 'n', s => BigInteger.Parse(s) }
             };
 
         [Given("the (\\w+) graph")]
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 2c8d242..bb8565b 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -686,7 +686,14 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_V_hasLabelXpersonX_V_hasLabelXsoftwareX_name", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("person").V().HasLabel("software").Values<object>("name")}}, 
                {"g_V_hasLabelXloopsX_bothEXselfX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("loops").BothE("self")}}, 
                {"g_V_hasLabelXloopsX_bothXselfX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("loops").Both("self")}}, 
+               {"Primitives_Number_eqXbyteX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
+               {"Primitives_Number_eqXshortX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
                {"Primitives_Number_eqXintX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
+               {"Primitives_Number_eqXlongX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
+               {"Primitives_Number_eqXbigintX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
+               {"Primitives_Number_eqXfloatX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
+               {"Primitives_Number_eqXdoubleX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
+               {"Primitives_Number_eqXbigdecimalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
                {"g_V_valueXnameX_aggregateXxX_capXxX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Aggregate("x").Cap<object>("x")}}, 
                {"g_V_valueXnameX_aggregateXglobal_xX_capXxX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Aggregate(Scope.Global,"x").Cap<object>("x")}}, 
                {"g_V_aggregateXxX_byXnameX_capXxX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Aggregate("x").By("name").Cap<object>("x")}}, 
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
index 7a9c8ee..e9d39cf 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
@@ -42,7 +42,7 @@ const direction = traversalModule.direction;
 const mapAsObject = false;
 
 const parsers = [
-  [ 'd\\[(.*)\\]\\.[ilfdm]', toNumeric ],
+  [ 'd\\[(.*)\\]\\.[bsilfdmn]', toNumeric ],
   [ 'v\\[(.+)\\]', toVertex ],
   [ 'v\\[(.+)\\]\\.id', toVertexId ],
   [ 'v\\[(.+)\\]\\.sid', toVertexIdString ],
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 8507405..a780192 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
@@ -675,7 +675,14 @@ const gremlins = {
     g_V_hasLabelXpersonX_V_hasLabelXsoftwareX_name: [function({g}) { return g.V().hasLabel("person").V().hasLabel("software").values("name") }], 
     g_V_hasLabelXloopsX_bothEXselfX: [function({g}) { return g.V().hasLabel("loops").bothE("self") }], 
     g_V_hasLabelXloopsX_bothXselfX: [function({g}) { return g.V().hasLabel("loops").both("self") }], 
+    Primitives_Number_eqXbyteX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
+    Primitives_Number_eqXshortX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
     Primitives_Number_eqXintX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
+    Primitives_Number_eqXlongX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
+    Primitives_Number_eqXbigintX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
+    Primitives_Number_eqXfloatX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
+    Primitives_Number_eqXdoubleX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
+    Primitives_Number_eqXbigdecimalX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
     g_V_valueXnameX_aggregateXxX_capXxX: [function({g}) { return g.V().values("name").aggregate("x").cap("x") }], 
     g_V_valueXnameX_aggregateXglobal_xX_capXxX: [function({g}) { return g.V().values("name").aggregate(Scope.global,"x").cap("x") }], 
     g_V_aggregateXxX_byXnameX_capXxX: [function({g}) { return g.V().aggregate("x").by("name").cap("x") }], 
diff --git a/gremlin-language/src/main/antlr4/Gremlin.g4 b/gremlin-language/src/main/antlr4/Gremlin.g4
index 0844d67..e277baa 100644
--- a/gremlin-language/src/main/antlr4/Gremlin.g4
+++ b/gremlin-language/src/main/antlr4/Gremlin.g4
@@ -1362,7 +1362,7 @@ OctalIntegerLiteral
 
 fragment
 IntegerTypeSuffix
-	:	[lL]
+	:	[bBsSnNiIlL]
 	;
 
 fragment
@@ -1489,7 +1489,7 @@ Sign
 
 fragment
 FloatTypeSuffix
-	:	[fFdD]
+	:	[fFdDmM]
 	;
 
 // Boolean Literals
diff --git a/gremlin-python/src/main/python/radish/feature_steps.py b/gremlin-python/src/main/python/radish/feature_steps.py
index eb225bd..9fd8cf6 100644
--- a/gremlin-python/src/main/python/radish/feature_steps.py
+++ b/gremlin-python/src/main/python/radish/feature_steps.py
@@ -162,7 +162,7 @@ def _convert(val, ctx):
         return [] if val == "l[]" else list(map((lambda x: _convert(x, ctx)), val[2:-1].split(",")))
     elif isinstance(val, str) and re.match(r"^s\[.*\]$", val):           # parse set
         return set() if val == "s[]" else set(map((lambda x: _convert(x, ctx)), val[2:-1].split(",")))
-    elif isinstance(val, str) and re.match(r"^d\[.*\]\.[ilfdm]$", val):  # parse numeric
+    elif isinstance(val, str) and re.match(r"^d\[.*\]\.[bsilfdmn]$", val):  # parse numeric
         return float(val[2:-3]) if val[2:-3].__contains__(".") else long(val[2:-3])
     elif isinstance(val, str) and re.match(r"^v\[.*\]\.id$", val):       # parse vertex id
         return __find_cached_element(ctx, graph_name, val[2:-4], "v").id
diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py
index 5f9535a..0aa4c93 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -660,7 +660,14 @@ world.gremlins = {
     'g_V_hasLabelXpersonX_V_hasLabelXsoftwareX_name': [(lambda g:g.V().hasLabel('person').V().hasLabel('software').name)], 
     'g_V_hasLabelXloopsX_bothEXselfX': [(lambda g:g.V().hasLabel('loops').bothE('self'))], 
     'g_V_hasLabelXloopsX_bothXselfX': [(lambda g:g.V().hasLabel('loops').both('self'))], 
+    'Primitives_Number_eqXbyteX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
+    'Primitives_Number_eqXshortX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
     'Primitives_Number_eqXintX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
+    'Primitives_Number_eqXlongX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
+    'Primitives_Number_eqXbigintX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
+    'Primitives_Number_eqXfloatX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
+    'Primitives_Number_eqXdoubleX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
+    'Primitives_Number_eqXbigdecimalX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
     'g_V_valueXnameX_aggregateXxX_capXxX': [(lambda g:g.V().name.aggregate('x').cap('x'))], 
     'g_V_valueXnameX_aggregateXglobal_xX_capXxX': [(lambda g:g.V().name.aggregate(Scope.global_,'x').cap('x'))], 
     'g_V_aggregateXxX_byXnameX_capXxX': [(lambda g:g.V().aggregate('x').by('name').cap('x'))], 
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/SaslAuthenticationHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/SaslAuthenticationHandler.java
index 2adc97f..848be27 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/SaslAuthenticationHandler.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/SaslAuthenticationHandler.java
@@ -156,8 +156,7 @@ public class SaslAuthenticationHandler extends AbstractAuthenticationHandler {
                     ctx.writeAndFlush(error);
                 }
             }
-        }
-        else {
+        } else {
             logger.warn("{} only processes RequestMessage instances - received {} - channel closing",
                     this.getClass().getSimpleName(), msg.getClass());
             ctx.close();
diff --git a/gremlin-test/features/semantics/Equality.feature b/gremlin-test/features/semantics/Equality.feature
index cb57121..58a1439 100644
--- a/gremlin-test/features/semantics/Equality.feature
+++ b/gremlin-test/features/semantics/Equality.feature
@@ -18,11 +18,52 @@
 @StepClassSemantics
 Feature: Equality
 
-  # TODO: TINKERPOP-2524 to support all the number types (and others required for semantics checks)
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: Primitives_Number_eqXbyteX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[1].b,d[1].s,d[1].i,d[1].l,d[1].f,d[1].d,d[1000].i,d[1].m,d[1].n]"
+    And using the parameter xx2 defined as "d[1].b"
+    And the traversal of
+      """
+      g.inject(xx1).unfold().where(__.is(xx2))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+      | d[1].l |
+      | d[1].f |
+      | d[1].d |
+      | d[1].s |
+      | d[1].n |
+      | d[1].m |
+      | d[1].b |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: Primitives_Number_eqXshortX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[1].b,d[1].s,d[1].i,d[1].l,d[1].f,d[1].d,d[1000].i,d[1].m,d[1].n]"
+    And using the parameter xx2 defined as "d[1].s"
+    And the traversal of
+      """
+      g.inject(xx1).unfold().where(__.is(xx2))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+      | d[1].l |
+      | d[1].f |
+      | d[1].d |
+      | d[1].s |
+      | d[1].n |
+      | d[1].m |
+      | d[1].b |
+
   @GraphComputerVerificationInjectionNotSupported
   Scenario: Primitives_Number_eqXintX
     Given the empty graph
-    And using the parameter xx1 defined as "l[d[1].i,d[1].l,d[1].f,d[1].d,d[1000].i]"
+    And using the parameter xx1 defined as "l[d[1].b,d[1].s,d[1].i,d[1].l,d[1].f,d[1].d,d[1000].i,d[1].m,d[1].n]"
     And using the parameter xx2 defined as "d[1].i"
     And the traversal of
       """
@@ -34,4 +75,113 @@ Feature: Equality
       | d[1].i |
       | d[1].l |
       | d[1].f |
-      | d[1].d |
\ No newline at end of file
+      | d[1].d |
+      | d[1].s |
+      | d[1].n |
+      | d[1].m |
+      | d[1].b |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: Primitives_Number_eqXlongX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[1].b,d[1].s,d[1].i,d[1].l,d[1].f,d[1].d,d[1000].i,d[1].m,d[1].n]"
+    And using the parameter xx2 defined as "d[1].l"
+    And the traversal of
+      """
+      g.inject(xx1).unfold().where(__.is(xx2))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+      | d[1].l |
+      | d[1].f |
+      | d[1].d |
+      | d[1].s |
+      | d[1].n |
+      | d[1].m |
+      | d[1].b |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: Primitives_Number_eqXbigintX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[1].b,d[1].s,d[1].i,d[1].l,d[1].f,d[1].d,d[1000].i,d[1].m,d[1].n]"
+    And using the parameter xx2 defined as "d[1].n"
+    And the traversal of
+      """
+      g.inject(xx1).unfold().where(__.is(xx2))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+      | d[1].l |
+      | d[1].f |
+      | d[1].d |
+      | d[1].s |
+      | d[1].n |
+      | d[1].m |
+      | d[1].b |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: Primitives_Number_eqXfloatX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[1].b,d[1].s,d[1].i,d[1].l,d[1].f,d[1].d,d[1000].i,d[1].m,d[1].n]"
+    And using the parameter xx2 defined as "d[1].f"
+    And the traversal of
+      """
+      g.inject(xx1).unfold().where(__.is(xx2))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+      | d[1].l |
+      | d[1].f |
+      | d[1].d |
+      | d[1].s |
+      | d[1].n |
+      | d[1].m |
+      | d[1].b |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: Primitives_Number_eqXdoubleX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[1].b,d[1].s,d[1].i,d[1].l,d[1].f,d[1].d,d[1000].i,d[1].m,d[1].n]"
+    And using the parameter xx2 defined as "d[1].d"
+    And the traversal of
+      """
+      g.inject(xx1).unfold().where(__.is(xx2))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+      | d[1].l |
+      | d[1].f |
+      | d[1].d |
+      | d[1].s |
+      | d[1].n |
+      | d[1].m |
+      | d[1].b |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: Primitives_Number_eqXbigdecimalX
+    Given the empty graph
+    And using the parameter xx1 defined as "l[d[1].b,d[1].s,d[1].i,d[1].l,d[1].f,d[1].d,d[1000].i,d[1].m,d[1].n]"
+    And using the parameter xx2 defined as "d[1].m"
+    And the traversal of
+      """
+      g.inject(xx1).unfold().where(__.is(xx2))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | d[1].i |
+      | d[1].l |
+      | d[1].f |
+      | d[1].d |
+      | d[1].s |
+      | d[1].n |
+      | d[1].m |
+      | d[1].b |
\ No newline at end of file
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 410858c..6b644a0 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
@@ -56,6 +56,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -93,11 +94,14 @@ public final class StepDefinition {
             final String listItems = Stream.of(items).map(String::trim).map(x -> convertToString(x)).collect(Collectors.joining(","));
             return String.format("[%s]", listItems);
         }));
-        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.i"), s -> s));
+        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.b"), s -> s + "b"));
+        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.s"), s -> s + "s"));
+        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.i"), s -> s + "i"));
         add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.l"), s -> s + "l"));
         add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.f"), s -> s + "f"));
         add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.d"), s -> s + "d"));
-        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.m"), s -> String.format("new BigDecimal(%s)", s)));
+        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.m"), s -> s + "m"));
+        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.n"), s -> s + "n"));
 
         add(Pair.with(Pattern.compile("v\\[(.+)\\]\\.id"), s -> g.V().has("name", s).id().next().toString()));
         add(Pair.with(Pattern.compile("v\\[(.+)\\]\\.sid"), s -> g.V().has("name", s).id().next().toString()));
@@ -155,11 +159,14 @@ public final class StepDefinition {
             throw new AssumptionViolatedException("This test uses a Path as a parameter which is not supported by gremlin-language");
         }));
 
+        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.b"), Byte::parseByte));
+        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.s"), Short::parseShort));
         add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.i"), Integer::parseInt));
         add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.l"), Long::parseLong));
         add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.f"), Float::parseFloat));
         add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.d"), Double::parseDouble));
         add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.m"), BigDecimal::new));
+        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.n"), BigInteger::new));
 
         add(Pair.with(Pattern.compile("v\\[(.+)\\]\\.id"), s -> g.V().has("name", s).id().next()));
         add(Pair.with(Pattern.compile("v\\[(.+)\\]\\.sid"), s -> g.V().has("name", s).id().next().toString()));