You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by xi...@apache.org on 2025/12/22 21:45:00 UTC
(tinkerpop) 02/02: fix various gremlinlang and serializer bugs in go for http
This is an automated email from the ASF dual-hosted git repository.
xiazcy pushed a commit to branch go-http-converge-conn-lang
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 4393a5a3b8a488c9131b0c86b4a1d73159161c48
Author: Yang Xia <xi...@gmail.com>
AuthorDate: Mon Dec 22 13:44:32 2025 -0800
fix various gremlinlang and serializer bugs in go for http
---
.../language/translator/GremlinTranslatorTest.java | 12 +-
gremlin-go/driver/client.go | 47 +-
gremlin-go/driver/client_test.go | 14 +-
gremlin-go/driver/connection_test.go | 161 +----
gremlin-go/driver/cucumber/cucumberSteps_test.go | 3 -
gremlin-go/driver/cucumber/cucumberWorld.go | 62 +-
gremlin-go/driver/driverRemoteConnection.go | 37 +-
gremlin-go/driver/error_codes.go | 1 +
gremlin-go/driver/graphBinary.go | 14 +-
gremlin-go/driver/graphBinary_test.go | 23 +-
gremlin-go/driver/graphTraversal.go | 8 +-
gremlin-go/driver/graphTraversalSource.go | 6 +-
gremlin-go/driver/gremlinClient.go | 148 -----
gremlin-go/driver/gremlinlang.go | 178 +++--
gremlin-go/driver/gremlinlang_test.go | 45 +-
gremlin-go/driver/httpTransporter.go | 7 +-
gremlin-go/driver/logger.go | 1 -
gremlin-go/driver/serializer.go | 13 +-
gremlin-go/driver/strategies.go | 40 +-
gremlin-go/driver/translator.go | 365 -----------
gremlin-go/driver/translator_test.go | 717 ---------------------
gremlin-go/driver/traversal.go | 52 +-
gremlin-go/driver/traversal_test.go | 14 +-
gremlin-go/examples/go.mod | 4 +-
gremlin-go/examples/go.sum | 2 +
gremlin-go/go.mod | 16 +-
gremlin-go/go.sum | 33 +-
.../python/gremlin_python/process/traversal.py | 2 +-
28 files changed, 410 insertions(+), 1615 deletions(-)
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 d89dba51b4..f08355d1a2 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
@@ -699,23 +699,13 @@ public class GremlinTranslatorTest {
{"g.withStrategies(ReservedKeysVerificationStrategy(throwException: true, keys: [\"age\"])).addV(\"person\").property(\"age\", 29).property(\"name\", \"marko\")",
"g.withStrategies(ReservedKeysVerificationStrategy(throwException:true, keys:[\"age\"])).addV(\"person\").property(\"age\", 29).property(\"name\", \"marko\")",
"g.withStrategies(ReservedKeysVerificationStrategy(throwException:boolean0, keys:list0)).addV(string0).property(string1, number0).property(string2, string3)",
- "g.WithStrategies(new ReservedKeysVerificationStrategy(throwException: true, keys: new List<object> { \"age\" })).AddV(\"person\").Property(\"age\", 29).Property(\"name\", \"marko\")",
+ "g.WithStrategies(new ReservedKeysVerificationStrategy(throwException: true, keys: new List<object> { \"age\" })).AddV((string) \"person\").Property(\"age\", 29).Property(\"name\", \"marko\")",
"g.WithStrategies(gremlingo.ReservedKeysVerificationStrategy(gremlingo.ReservedKeysVerificationStrategyConfig{ThrowException: true, Keys: []string{\"age\"}})).AddV(\"person\").Property(\"age\", 29).Property(\"name\", \"marko\")",
"g.withStrategies(new ReservedKeysVerificationStrategy(throwException:true, keys:[\"age\"])).addV(\"person\").property(\"age\", 29).property(\"name\", \"marko\")",
"g.withStrategies(ReservedKeysVerificationStrategy.build().throwException(true).keys(new ArrayList<Object>() {{ add(\"age\"); }}).create()).addV(\"person\").property(\"age\", 29).property(\"name\", \"marko\")",
"g.withStrategies(new ReservedKeysVerificationStrategy({throwException: true, keys: [\"age\"]})).addV(\"person\").property(\"age\", 29).property(\"name\", \"marko\")",
"g.with_strategies(ReservedKeysVerificationStrategy(throw_exception=True, keys=['age'])).add_v('person').property('age', 29).property('name', 'marko')"
},
- {"g.withStrategies(OptionsStrategy(myVar: \"myValue\")).V()",
- "g.withStrategies(OptionsStrategy(myVar:\"myValue\")).V()",
- "g.withStrategies(OptionsStrategy(myVar:string0)).V()",
- "g.WithStrategies(new OptionsStrategy(myVar: \"myValue\")).V()",
- "g.WithStrategies(gremlingo.OptionsStrategy(map[string]interface{}{\"myVar\": \"myValue\"})).V()",
- "g.withStrategies(new OptionsStrategy(myVar:\"myValue\")).V()",
- "g.withStrategies(OptionsStrategy.build().myVar(\"myValue\").create()).V()",
- "g.withStrategies(new OptionsStrategy({myVar: \"myValue\"})).V()",
- "g.with_strategies(OptionsStrategy(my_var='myValue')).V()"
- },
{"g.withoutStrategies(ReadOnlyStrategy, PathRetractionStrategy, FilterRankingStrategy)",
null,
null,
diff --git a/gremlin-go/driver/client.go b/gremlin-go/driver/client.go
index 12b6c4e9c6..7ce9a8839a 100644
--- a/gremlin-go/driver/client.go
+++ b/gremlin-go/driver/client.go
@@ -21,6 +21,7 @@ package gremlingo
import (
"crypto/tls"
+ "reflect"
"runtime"
"time"
@@ -134,7 +135,7 @@ func (client *Client) SubmitWithOptions(traversalString string, requestOptions R
request := makeStringRequest(traversalString, client.traversalSource, requestOptions)
// TODO interceptors (ie. auth)
-
+
rs, err := client.httpProtocol.send(&request)
return rs, err
}
@@ -156,13 +157,47 @@ func (client *Client) submitGremlinLang(gremlinLang *GremlinLang) (ResultSet, er
client.logHandler.logf(Debug, submitStartedString, *gremlinLang)
// TODO placeholder
requestOptionsBuilder := new(RequestOptionsBuilder)
+ if len(gremlinLang.GetParameters()) > 0 {
+ requestOptionsBuilder.SetBindings(gremlinLang.GetParameters())
+ }
+ if len(gremlinLang.optionsStrategies) > 0 {
+ requestOptionsBuilder = applyOptionsConfig(requestOptionsBuilder, gremlinLang.optionsStrategies[0].configuration)
+ }
+
request := makeStringRequest(gremlinLang.GetGremlin(), client.traversalSource, requestOptionsBuilder.Create())
return client.httpProtocol.send(&request)
}
-// submitBytecode submits Bytecode to the server to execute and returns a ResultSet.
-func (client *Client) submitBytecode(bytecode *Bytecode) (ResultSet, error) {
- client.logHandler.logf(Debug, submitStartedBytecode, *bytecode)
- request := makeBytecodeRequest(bytecode, client.traversalSource)
- return client.httpProtocol.send(&request)
+func applyOptionsConfig(builder *RequestOptionsBuilder, config map[string]interface{}) *RequestOptionsBuilder {
+ builderValue := reflect.ValueOf(builder)
+
+ // Map configuration keys to setter method names
+ setterMap := map[string]string{
+ "requestId": "SetRequestId",
+ "evaluationTimeout": "SetEvaluationTimeout",
+ "batchSize": "SetBatchSize",
+ "userAgent": "SetUserAgent",
+ "bindings": "SetBindings",
+ "materializeProperties": "SetMaterializeProperties",
+ }
+
+ for key, value := range config {
+ if methodName, exists := setterMap[key]; exists {
+ method := builderValue.MethodByName(methodName)
+ if method.IsValid() {
+ args := []reflect.Value{reflect.ValueOf(value)}
+ method.Call(args)
+ }
+ }
+ }
+
+ return builder
}
+
+// submitBytecode submits Bytecode to the server to execute and returns a ResultSet.
+// TODO remove
+//func (client *Client) submitBytecode(bytecode *Bytecode) (ResultSet, error) {
+// client.logHandler.logf(Debug, submitStartedBytecode, *bytecode)
+// request := makeBytecodeRequest(bytecode, client.traversalSource)
+// return client.httpProtocol.send(&request)
+//}
diff --git a/gremlin-go/driver/client_test.go b/gremlin-go/driver/client_test.go
index 6068f89ecc..9e223dd193 100644
--- a/gremlin-go/driver/client_test.go
+++ b/gremlin-go/driver/client_test.go
@@ -62,7 +62,7 @@ func TestClient(t *testing.T) {
})
assert.NoError(t, err)
assert.NotNil(t, client)
- resultSet, err := client.Submit("2+2")
+ resultSet, err := client.Submit("g.inject(2)")
assert.NoError(t, err)
assert.NotNil(t, resultSet)
@@ -104,9 +104,9 @@ func TestClient(t *testing.T) {
assert.NotNil(t, client)
defer client.Close()
- bindings := map[string]interface{}{"x": 2}
+ bindings := map[string]interface{}{"x": 1}
- resultSet, err := client.Submit("x + x", bindings)
+ resultSet, err := client.Submit("g.V(x).values(\"name\")", bindings)
assert.NoError(t, err)
assert.NotNil(t, resultSet)
@@ -114,7 +114,7 @@ func TestClient(t *testing.T) {
assert.NoError(t, err)
assert.True(t, ok)
- assert.Equal(t, int64(4), result.Data)
+ assert.Equal(t, "marko", result.Data)
})
t.Run("Test client.SubmitWithOptions() with bindings", func(t *testing.T) {
@@ -129,9 +129,9 @@ func TestClient(t *testing.T) {
assert.NotNil(t, client)
defer client.Close()
- bindings := map[string]interface{}{"x": 2}
+ bindings := map[string]interface{}{"x": 1}
- resultSet, err := client.SubmitWithOptions("x + x", new(RequestOptionsBuilder).SetBindings(bindings).Create())
+ resultSet, err := client.SubmitWithOptions("g.V(x).values(\"name\")", new(RequestOptionsBuilder).SetBindings(bindings).Create())
assert.NoError(t, err)
assert.NotNil(t, resultSet)
@@ -139,7 +139,7 @@ func TestClient(t *testing.T) {
assert.NoError(t, err)
assert.True(t, ok)
- assert.Equal(t, int64(4), result.Data)
+ assert.Equal(t, "marko", result.Data)
})
t.Run("Test client.submit() with materializeProperties", func(t *testing.T) {
diff --git a/gremlin-go/driver/connection_test.go b/gremlin-go/driver/connection_test.go
index d24c6158ff..be13a9a8e5 100644
--- a/gremlin-go/driver/connection_test.go
+++ b/gremlin-go/driver/connection_test.go
@@ -22,7 +22,6 @@ package gremlingo
import (
"crypto/tls"
"fmt"
- "github.com/stretchr/testify/assert"
"math/big"
"os"
"reflect"
@@ -30,6 +29,8 @@ import (
"strconv"
"sync"
"testing"
+
+ "github.com/stretchr/testify/assert"
)
const personLabel = "Person"
@@ -663,142 +664,28 @@ func TestConnection(t *testing.T) {
}
})
- t.Run("Test Client.Submit() Simple String Query with Bindings", func(t *testing.T) {
- skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
-
- client, err := NewClient(testNoAuthUrl,
- func(settings *ClientSettings) {
- settings.TlsConfig = testNoAuthTlsConfig
- settings.AuthInfo = testNoAuthAuthInfo
- })
- assert.Nil(t, err)
- assert.NotNil(t, client)
- defer client.Close()
-
- resultSet, err := client.Submit("g.inject(x).math('_+_')", map[string]interface{}{"x": 2})
- assert.Nil(t, err)
- assert.NotNil(t, resultSet)
- result, ok, err := resultSet.One()
- assert.Nil(t, err)
- assert.True(t, ok)
- assert.NotNil(t, result)
- res, err := result.GetInt()
- assert.Nil(t, err)
- assert.Equal(t, 4, res)
- })
-
- t.Run("Test Bindings To Server Configured with Modern Graph", func(t *testing.T) {
- skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthWithAliasEnable)
- remote, err := NewDriverRemoteConnection(testNoAuthWithAliasUrl,
- func(settings *DriverRemoteConnectionSettings) {
- settings.TlsConfig = testNoAuthWithAliasTlsConfig
- settings.AuthInfo = testNoAuthWithAliasAuthInfo
- settings.TraversalSource = testServerModernGraphAlias
- })
- assert.Nil(t, err)
- assert.NotNil(t, remote)
- defer remote.Close()
- g := Traversal_().With(remote)
-
- r, err := g.V((&Bindings{}).Of("x", 1)).Out("created").Map(&Lambda{Script: "it.get().value('name').length()", Language: ""}).Sum().ToList()
- assert.Nil(t, err)
- for _, res := range r {
- assert.Equal(t, int32(3), res.GetInterface())
- }
- r, err = g.V((&Bindings{}).Of("x", 4)).Out("created").Map(&Lambda{Script: "it.get().value('name').length()", Language: ""}).Sum().ToList()
- assert.Nil(t, err)
- for _, res := range r {
- assert.Equal(t, int32(9), res.GetInterface())
- }
- })
-
- t.Run("Test DriverRemoteConnection Invalid GraphTraversal", func(t *testing.T) {
- skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
-
- // Initialize graph
- g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
-
- // Drop the graph.
- dropGraph(t, g)
-
- // Add vertices and edges to graph.
- rs, err := g.AddV("person").Property("id", T__.Unfold().Property().AddV()).ToList()
- assert.Nil(t, rs)
- assert.True(t, isSameErrorCode(newError(err0502ResponseHandlerError), err))
-
- rs, err = g.V().Count().ToList()
- assert.NotNil(t, rs)
- assert.Nil(t, err)
-
- // Drop the graph.
- dropGraph(t, g)
- })
-
- t.Run("Test per-request arguments", func(t *testing.T) {
- skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
-
- g := getTestGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
- defer g.remoteConnection.Close()
-
- reqArgsTests := []struct {
- msg string
- traversal *GraphTraversal
- nilErr bool
- }{
- {
- "Traversal must time out (With)",
- g.
- With("evaluationTimeout", 10).
- Inject(1).
- SideEffect(&Lambda{"Thread.sleep(5000)", "gremlin-groovy"}),
- false,
- },
- {
- "Traversal must finish (With)",
- g.
- With("evaluationTimeout", 10000).
- Inject(1).
- SideEffect(&Lambda{"Thread.sleep(5000)", "gremlin-groovy"}),
- true,
- },
- {
- "evaluationTimeout is overridden and traversal must time out (With)",
- g.
- With("evaluationTimeout", 10000).With("evaluationTimeout", 10).
- Inject(1).
- SideEffect(&Lambda{"Thread.sleep(5000)", "gremlin-groovy"}),
- false,
- },
- {
- "Traversal must time out (OptionsStrategy)",
- g.
- WithStrategies(OptionsStrategy(map[string]interface{}{"evaluationTimeout": 10})).
- Inject(1).
- SideEffect(&Lambda{"Thread.sleep(5000)", "gremlin-groovy"}),
- false,
- },
- {
- "Traversal must finish (OptionsStrategy)",
- g.
- WithStrategies(OptionsStrategy(map[string]interface{}{"evaluationTimeout": 10000})).
- Inject(1).
- SideEffect(&Lambda{"Thread.sleep(5000)", "gremlin-groovy"}),
- true,
- },
- }
-
- gotErrs := make([]<-chan error, len(reqArgsTests))
-
- // Run tests in parallel.
- for i, tt := range reqArgsTests {
- gotErrs[i] = tt.traversal.Iterate()
- }
-
- // Check error promises.
- for i, tt := range reqArgsTests {
- assert.Equal(t, <-gotErrs[i] == nil, tt.nilErr, tt.msg)
- }
- })
+ // TODO enable after error response is deser properly
+ //t.Run("Test DriverRemoteConnection Invalid GraphTraversal", func(t *testing.T) {
+ // skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ //
+ // // Initialize graph
+ // g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
+ //
+ // // Drop the graph.
+ // dropGraph(t, g)
+ //
+ // // Add vertices and edges to graph.
+ // rs, err := g.AddV("person").Property("id", T__.Unfold().Property().AddV()).ToList()
+ // assert.Nil(t, rs)
+ // assert.True(t, isSameErrorCode(newError(err0502ResponseHandlerError), err))
+ //
+ // rs, err = g.V().Count().ToList()
+ // assert.NotNil(t, rs)
+ // assert.Nil(t, err)
+ //
+ // // Drop the graph.
+ // dropGraph(t, g)
+ //})
t.Run("Get all properties when materializeProperties is all", func(t *testing.T) {
skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
diff --git a/gremlin-go/driver/cucumber/cucumberSteps_test.go b/gremlin-go/driver/cucumber/cucumberSteps_test.go
index 0942ae1384..f9caa7e187 100644
--- a/gremlin-go/driver/cucumber/cucumberSteps_test.go
+++ b/gremlin-go/driver/cucumber/cucumberSteps_test.go
@@ -951,11 +951,8 @@ func InitializeScenario(ctx *godog.ScenarioContext) {
ctx.Step(`^the result should have a count of (\d+)$`, tg.theResultShouldHaveACountOf)
ctx.Step(`^the traversal of$`, tg.theTraversalOf)
ctx.Step(`^using the parameter (.+) defined as "(.+)"$`, tg.usingTheParameterDefined)
-<<<<<<< HEAD
-=======
ctx.Step(`^using the parameter (.+) of P\.(.+)\("(.+)"\)$`, tg.usingTheParameterOfP)
ctx.Step(`^using the side effect (.+) defined as"(.+)"$`, tg.usingTheSideEffectDefined)
->>>>>>> 3.8-dev
ctx.Step(`^the traversal will raise an error$`, tg.theTraversalWillRaiseAnError)
ctx.Step(`^the traversal will raise an error with message (\w+) text of "(.+)"$`, tg.theTraversalWillRaiseAnErrorWithMessageContainingTextOf)
}
diff --git a/gremlin-go/driver/cucumber/cucumberWorld.go b/gremlin-go/driver/cucumber/cucumberWorld.go
index 6e6d008af0..ac92ea1db8 100644
--- a/gremlin-go/driver/cucumber/cucumberWorld.go
+++ b/gremlin-go/driver/cucumber/cucumberWorld.go
@@ -21,11 +21,12 @@ package gremlingo
import (
"fmt"
- gremlingo "github.com/apache/tinkerpop/gremlin-go/v3/driver"
- "github.com/cucumber/godog"
"os"
"reflect"
"strconv"
+
+ gremlingo "github.com/apache/tinkerpop/gremlin-go/v3/driver"
+ "github.com/cucumber/godog"
)
type CucumberWorld struct {
@@ -164,8 +165,11 @@ func getVertices(g *gremlingo.GraphTraversalSource) map[string]*gremlingo.Vertex
func getEdges(g *gremlingo.GraphTraversalSource) map[string]*gremlingo.Edge {
edgeMap := make(map[string]*gremlingo.Edge)
- resE, err := g.E().Group().By(gremlingo.T__.Project("o", "l", "i").
- By(gremlingo.T__.OutV().Values("name")).By(gremlingo.T__.Label()).By(gremlingo.T__.InV().Values("name"))).
+ resE, err := g.E().Group().
+ By(gremlingo.T__.Project("o", "l", "i").
+ By(gremlingo.T__.OutV().Values("name")).
+ By(gremlingo.T__.Label()).
+ By(gremlingo.T__.InV().Values("name"))).
By(gremlingo.T__.Tail()).Next()
if err != nil {
return nil
@@ -190,38 +194,44 @@ func getEdgeKey(edgeKeyMap map[interface{}]interface{}) string {
}
func getVertexProperties(g *gremlingo.GraphTraversalSource) map[string]*gremlingo.VertexProperty {
- vertexPropertyMap := make(map[string]*gremlingo.VertexProperty)
- res, err := g.V().Properties().Group().By(&gremlingo.Lambda{
- Script: "{ it -> \n" +
- " def val = it.value()\n" +
- " if (val instanceof Integer)\n" +
- " val = 'd[' + val + '].i'\n" +
- " else if (val instanceof Float)\n" +
- " val = 'd[' + val + '].f'\n" +
- " else if (val instanceof Double)\n" +
- " val = 'd[' + val + '].d'\n" +
- " return it.element().value('name') + '-' + it.key() + '->' + val\n" +
- "}",
- Language: "",
- }).By(gremlingo.T__.Tail()).Next()
+ vertexPropsMap := make(map[string]*gremlingo.VertexProperty)
+ res, err := g.V().Properties().Group().
+ By(gremlingo.T__.Project("n", "k", "v").
+ By(gremlingo.T__.Element().Values("name")).
+ By(gremlingo.T__.Key()).
+ By(gremlingo.T__.Value())).
+ By(gremlingo.T__.Tail()).Next()
if res == nil {
return nil
}
if err != nil {
return nil
}
- v := reflect.ValueOf(res.GetInterface())
- if v.Kind() != reflect.Map {
- fmt.Printf("Expecting to get a map as a result, got %v instead.", v.Kind())
+ valMap := reflect.ValueOf(res.GetInterface())
+ if valMap.Kind() != reflect.Map {
+ fmt.Printf("Expecting to get a map as a result, got %v instead.", valMap.Kind())
return nil
}
- keys := v.MapKeys()
+ keys := valMap.MapKeys()
for _, k := range keys {
- convKey := k.Convert(v.Type().Key())
- val := v.MapIndex(convKey)
- vertexPropertyMap[k.Interface().(string)] = val.Interface().(*gremlingo.VertexProperty)
+ convKey := k.Convert(valMap.Type().Key())
+ val := valMap.MapIndex(convKey)
+ keyMap := reflect.ValueOf(k.Interface()).Elem().Interface().(map[interface{}]interface{})
+ vertexPropsMap[getVPKey(keyMap)] = val.Interface().(*gremlingo.VertexProperty)
+ }
+ return vertexPropsMap
+}
+
+func getVPKey(vpKeyMap map[interface{}]interface{}) string {
+ k := vpKeyMap["k"]
+ v := vpKeyMap["v"]
+ if k == "weight" {
+ v = fmt.Sprint("d[", v, "].d")
+ } else if k == "age" || k == "since" || k == "skill" {
+ v = fmt.Sprint("d[", v, "].i")
}
- return vertexPropertyMap
+ // Format as n-k->v
+ return fmt.Sprint(vpKeyMap["n"], "-", k, "->", v)
}
// This function is used to isolate connection problems to each scenario, and used in the Before context hook to prevent
diff --git a/gremlin-go/driver/driverRemoteConnection.go b/gremlin-go/driver/driverRemoteConnection.go
index d907a7fc34..a61a9e0ac7 100644
--- a/gremlin-go/driver/driverRemoteConnection.go
+++ b/gremlin-go/driver/driverRemoteConnection.go
@@ -144,22 +144,23 @@ func (driver *DriverRemoteConnection) submitGremlinLang(gremlinLang *GremlinLang
return driver.client.submitGremlinLang(gremlinLang)
}
+// TODO remove
// submitBytecode sends a Bytecode traversal to the server.
-func (driver *DriverRemoteConnection) submitBytecode(bytecode *Bytecode) (ResultSet, error) {
- if driver.isClosed {
- return nil, newError(err0203SubmitBytecodeToClosedConnectionError)
- }
- return driver.client.submitBytecode(bytecode)
-}
-
-func (driver *DriverRemoteConnection) commit() (ResultSet, error) {
- bc := &Bytecode{}
- bc.AddSource("tx", "commit")
- return driver.submitBytecode(bc)
-}
-
-func (driver *DriverRemoteConnection) rollback() (ResultSet, error) {
- bc := &Bytecode{}
- bc.AddSource("tx", "rollback")
- return driver.submitBytecode(bc)
-}
+//func (driver *DriverRemoteConnection) submitBytecode(bytecode *Bytecode) (ResultSet, error) {
+// if driver.isClosed {
+// return nil, newError(err0203SubmitBytecodeToClosedConnectionError)
+// }
+// return driver.client.submitBytecode(bytecode)
+//}
+//
+//func (driver *DriverRemoteConnection) commit() (ResultSet, error) {
+// bc := &Bytecode{}
+// bc.AddSource("tx", "commit")
+// return driver.submitBytecode(bc)
+//}
+//
+//func (driver *DriverRemoteConnection) rollback() (ResultSet, error) {
+// bc := &Bytecode{}
+// bc.AddSource("tx", "rollback")
+// return driver.submitBytecode(bc)
+//}
diff --git a/gremlin-go/driver/error_codes.go b/gremlin-go/driver/error_codes.go
index d1fd98af55..03a4b1cf05 100644
--- a/gremlin-go/driver/error_codes.go
+++ b/gremlin-go/driver/error_codes.go
@@ -58,6 +58,7 @@ const (
// response handling errors
err0501ResponseHandlerResultSetNotCreatedError errorCode = "E0501_PROTOCOL_RESPONSEHANDLER_NO_RESULTSET_ON_DATA_RECEIVE"
+ err0502ResponseHandlerReadLoopError errorCode = "E0502_PROTOCOL_RESPONSEHANDLER_READ_LOOP_ERROR"
err0502ResponseHandlerError errorCode = "E0502_PROTOCOL_RESPONSEHANDLER_ERROR"
err0503ResponseHandlerAuthError errorCode = "E0503_PROTOCOL_RESPONSEHANDLER_AUTH_ERROR"
diff --git a/gremlin-go/driver/graphBinary.go b/gremlin-go/driver/graphBinary.go
index de3c071695..c553b0a2e2 100644
--- a/gremlin-go/driver/graphBinary.go
+++ b/gremlin-go/driver/graphBinary.go
@@ -320,7 +320,7 @@ func edgeWriter(value interface{}, buffer *bytes.Buffer, typeSerializer *graphBi
}
// Not fully qualified.
- _, err = typeSerializer.writeValue(e.InV.Label, buffer, false)
+ _, err = typeSerializer.writeValue([1]string{e.InV.Label}, buffer, false)
if err != nil {
return nil, err
}
@@ -331,7 +331,7 @@ func edgeWriter(value interface{}, buffer *bytes.Buffer, typeSerializer *graphBi
}
// Not fully qualified.
- _, err = typeSerializer.writeValue(e.OutV.Label, buffer, false)
+ _, err = typeSerializer.writeValue([1]string{e.OutV.Label}, buffer, false)
if err != nil {
return nil, err
}
@@ -405,7 +405,7 @@ func setWriter(value interface{}, buffer *bytes.Buffer, typeSerializer *graphBin
return listWriter(slice, buffer, typeSerializer)
}
-func timeWriter(value interface{}, buffer *bytes.Buffer, _ *graphBinaryTypeSerializer) ([]byte, error) {
+func dateTimeWriter(value interface{}, buffer *bytes.Buffer, _ *graphBinaryTypeSerializer) ([]byte, error) {
t := value.(time.Time)
err := binary.Write(buffer, binary.BigEndian, int32(t.Year()))
if err != nil {
@@ -758,8 +758,8 @@ func readList(data *[]byte, i *int, flag byte) (interface{}, error) {
if err != nil {
return nil, err
}
- bulk := readIntSafe(data, i)
- for k := int32(0); k < bulk; k++ {
+ bulk := readLongSafe(data, i)
+ for k := int64(0); k < bulk; k++ {
valList = append(valList, val)
}
}
@@ -850,7 +850,7 @@ func readUuid(data *[]byte, i *int) (interface{}, error) {
return id, nil
}
-func timeReader(data *[]byte, i *int) (interface{}, error) {
+func dateTimeReader(data *[]byte, i *int) (interface{}, error) {
year := readIntSafe(data, i)
month := readByteSafe(data, i)
day := readByteSafe(data, i)
@@ -933,7 +933,7 @@ func edgeReader(data *[]byte, i *int) (interface{}, error) {
if err != nil {
return nil, err
}
- label, err := readUnqualified(data, i, listType, false)
+ label, err := readList(data, i, 0)
if err != nil {
return nil, err
}
diff --git a/gremlin-go/driver/graphBinary_test.go b/gremlin-go/driver/graphBinary_test.go
index f974bef652..eb44538fe1 100644
--- a/gremlin-go/driver/graphBinary_test.go
+++ b/gremlin-go/driver/graphBinary_test.go
@@ -23,15 +23,16 @@ import (
"bytes"
"encoding/binary"
"fmt"
- "github.com/stretchr/testify/assert"
- "golang.org/x/text/language"
"math/big"
"reflect"
"testing"
"time"
+
+ "github.com/stretchr/testify/assert"
+ "golang.org/x/text/language"
)
-func TestGraphBinaryV1(t *testing.T) {
+func TestGraphBinaryV4(t *testing.T) {
t.Run("graphBinaryTypeSerializer tests", func(t *testing.T) {
serializer := graphBinaryTypeSerializer{newLogHandler(&defaultLogger{}, Error, language.English)}
@@ -296,9 +297,9 @@ func TestGraphBinaryV1(t *testing.T) {
pos := 0
var buffer bytes.Buffer
source := time.Date(2022, 5, 10, 9, 51, 0, 0, time.Local)
- buf, err := timeWriter(source, &buffer, nil)
+ buf, err := dateTimeWriter(source, &buffer, nil)
assert.Nil(t, err)
- res, err := timeReader(&buf, &pos)
+ res, err := dateTimeReader(&buf, &pos)
assert.Nil(t, err)
// ISO format
assert.Equal(t, source.Format(time.RFC3339Nano), res.(time.Time).Format(time.RFC3339Nano))
@@ -307,9 +308,9 @@ func TestGraphBinaryV1(t *testing.T) {
pos := 0
var buffer bytes.Buffer
source := time.Date(2022, 5, 10, 9, 51, 0, 0, time.Local)
- buf, err := offsetDateTimeWriter(source, &buffer, nil)
+ buf, err := dateTimeWriter(source, &buffer, nil)
assert.Nil(t, err)
- res, err := offsetDateTimeReader(&buf, &pos)
+ res, err := dateTimeReader(&buf, &pos)
assert.Nil(t, err)
// ISO format
assert.Equal(t, source.Format(time.RFC3339Nano), res.(time.Time).Format(time.RFC3339Nano))
@@ -318,9 +319,9 @@ func TestGraphBinaryV1(t *testing.T) {
pos := 0
var buffer bytes.Buffer
source := time.Date(2022, 5, 10, 9, 51, 0, 0, time.UTC)
- buf, err := offsetDateTimeWriter(source, &buffer, nil)
+ buf, err := dateTimeWriter(source, &buffer, nil)
assert.Nil(t, err)
- res, err := offsetDateTimeReader(&buf, &pos)
+ res, err := dateTimeReader(&buf, &pos)
assert.Nil(t, err)
// ISO format
assert.Equal(t, source.Format(time.RFC3339Nano), res.(time.Time).Format(time.RFC3339Nano))
@@ -329,9 +330,9 @@ func TestGraphBinaryV1(t *testing.T) {
pos := 0
var buffer bytes.Buffer
source := time.Date(2022, 5, 10, 9, 51, 34, 123456789, GetTimezoneFromOffset(-36000))
- buf, err := offsetDateTimeWriter(source, &buffer, nil)
+ buf, err := dateTimeWriter(source, &buffer, nil)
assert.Nil(t, err)
- res, err := offsetDateTimeReader(&buf, &pos)
+ res, err := dateTimeReader(&buf, &pos)
assert.Nil(t, err)
// ISO format
assert.Equal(t, source.Format(time.RFC3339Nano), res.(time.Time).Format(time.RFC3339Nano))
diff --git a/gremlin-go/driver/graphTraversal.go b/gremlin-go/driver/graphTraversal.go
index abca84b18f..714e8ee447 100644
--- a/gremlin-go/driver/graphTraversal.go
+++ b/gremlin-go/driver/graphTraversal.go
@@ -116,7 +116,7 @@ func (g *GraphTraversal) As(args ...interface{}) *GraphTraversal {
// AsBool adds the asBool step to the GraphTraversal.
func (g *GraphTraversal) AsBool(args ...interface{}) *GraphTraversal {
- g.Bytecode.AddStep("asBool", args...)
+ g.GremlinLang.AddStep("asBool", args...)
return g
}
@@ -128,7 +128,7 @@ func (g *GraphTraversal) AsDate(args ...interface{}) *GraphTraversal {
// AsNumber adds the asNumber step to the GraphTraversal.
func (g *GraphTraversal) AsNumber(args ...interface{}) *GraphTraversal {
- g.Bytecode.AddStep("asNumber", args...)
+ g.GremlinLang.AddStep("asNumber", args...)
return g
}
@@ -947,8 +947,8 @@ func (t *Transaction) Begin() (*GraphTraversalSource, error) {
}
gts := &GraphTraversalSource{
- graph: t.g.graph,
- gremlinLang: t.g.gremlinLang}
+ graph: t.g.graph,
+ gremlinLang: t.g.gremlinLang}
return gts, nil
}
diff --git a/gremlin-go/driver/graphTraversalSource.go b/gremlin-go/driver/graphTraversalSource.go
index 12ae62b0f7..58ad12a9a6 100644
--- a/gremlin-go/driver/graphTraversalSource.go
+++ b/gremlin-go/driver/graphTraversalSource.go
@@ -51,9 +51,9 @@ func NewDefaultGraphTraversalSource() *GraphTraversalSource {
// GetBytecode gets the traversal Bytecode associated with this graph traversal source.
// TODO remove
-func (gts *GraphTraversalSource) GetBytecode() *Bytecode {
- return nil
-}
+//func (gts *GraphTraversalSource) GetBytecode() *Bytecode {
+// return nil
+//}
// GetGraphTraversal gets the graph traversal associated with this graph traversal source.
func (gts *GraphTraversalSource) GetGraphTraversal() *GraphTraversal {
diff --git a/gremlin-go/driver/gremlinClient.go b/gremlin-go/driver/gremlinClient.go
deleted file mode 100644
index 5a1369c612..0000000000
--- a/gremlin-go/driver/gremlinClient.go
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied. See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package gremlingo
-
-import (
- "net/http"
-)
-
-// responsible for serializing and sending requests and then receiving and deserializing responses
-type gremlinClient struct {
- serializer serializer
- logHandler *logHandler
- url string
- connSettings *connectionSettings
- httpClient *http.Client
-}
-
-func newGremlinClient(handler *logHandler, url string, connSettings *connectionSettings) *gremlinClient {
- transport := &http.Transport{
- TLSClientConfig: connSettings.tlsConfig,
- MaxConnsPerHost: 0, // TODO
- IdleConnTimeout: 0, // TODO
- DisableCompression: !connSettings.enableCompression,
- }
-
- httpClient := http.Client{
- Transport: transport,
- Timeout: connSettings.connectionTimeout,
- }
-
- httpProt := &gremlinClient{
- serializer: newGraphBinarySerializer(handler),
- logHandler: handler,
- url: url,
- connSettings: connSettings,
- httpClient: &httpClient,
- }
- return httpProt
-}
-
-// sends a query request and returns a ResultSet that can be used to obtain query results
-func (client *gremlinClient) send(request *request) (ResultSet, error) {
- rs := newChannelResultSet()
- bytes, err := client.serializer.serializeMessage(request)
- if err != nil {
- rs.setError(err)
- rs.Close()
- return rs, err
- }
-
- // one transport per request
- transport := newHttpTransporter(client.url, client.connSettings, client.httpClient, client.logHandler)
-
- // async send request
- transport.wg.Add(1)
- go func() {
- defer transport.wg.Done()
- err := transport.write(bytes)
- if err != nil {
- rs.setError(err)
- rs.Close()
- }
- }()
-
- // async receive response
- transport.wg.Add(1)
- go func() {
- defer transport.wg.Done()
- msg, err := transport.read()
- if err != nil {
- rs.setError(err)
- rs.Close()
- } else {
- err = client.receive(rs, msg)
- }
- transport.close()
- }()
-
- return rs, err
-}
-
-// receives a binary response message, deserializes, and adds results to the ResultSet
-func (client *gremlinClient) receive(rs ResultSet, msg []byte) error {
- resp, err := client.serializer.deserializeMessage(msg)
- if err != nil {
- client.logHandler.logf(Error, logErrorGeneric, "deserializeMessage()", err.Error())
- rs.Close()
- return err
- }
-
- err = client.handleResponse(rs, resp)
- if err != nil {
- client.logHandler.logf(Error, logErrorGeneric, "handleResponse()", err.Error())
- rs.Close()
- return err
- }
- return nil
-}
-
-// processes a deserialized response and attempts to add results to the ResultSet
-func (client *gremlinClient) handleResponse(rs ResultSet, response response) error {
- statusCode, data := response.responseStatus.code, response.responseResult.data
- if rs == nil {
- return newError(err0501ResponseHandlerResultSetNotCreatedError)
- }
-
- if statusCode == http.StatusNoContent {
- rs.addResult(&Result{make([]interface{}, 0)})
- rs.Close()
- client.logHandler.logf(Debug, readComplete)
- } else if statusCode == http.StatusOK {
- rs.addResult(&Result{data})
- rs.Close()
- client.logHandler.logf(Debug, readComplete)
- } else if statusCode == http.StatusUnauthorized || statusCode == http.StatusForbidden {
- rs.Close()
- err := newError(err0503ResponseHandlerAuthError, response.responseStatus, response.responseResult)
- rs.setError(err)
- return err
- } else {
- rs.Close()
- err := newError(err0502ResponseHandlerError, response.responseStatus, statusCode)
- rs.setError(err)
- return err
- }
- return nil
-}
-
-func (client *gremlinClient) close() {
- client.httpClient.CloseIdleConnections()
-}
diff --git a/gremlin-go/driver/gremlinlang.go b/gremlin-go/driver/gremlinlang.go
index 3a67515030..39165d2bc8 100644
--- a/gremlin-go/driver/gremlinlang.go
+++ b/gremlin-go/driver/gremlinlang.go
@@ -29,6 +29,8 @@ import (
"strings"
"sync/atomic"
"time"
+
+ "github.com/google/uuid"
)
type GremlinLang struct {
@@ -46,9 +48,17 @@ func NewGremlinLang(gl *GremlinLang) *GremlinLang {
optionsStrategies := make([]*traversalStrategy, 0)
paramCount := atomic.Uint64{}
if gl != nil {
- gremlin = gl.gremlin
- parameters = gl.parameters
- optionsStrategies = gl.optionsStrategies
+ gremlin = make([]string, len(gl.gremlin))
+ copy(gremlin, gl.gremlin)
+
+ parameters = make(map[string]interface{})
+ for k, v := range gl.parameters {
+ parameters[k] = v
+ }
+
+ optionsStrategies = make([]*traversalStrategy, len(gl.optionsStrategies))
+ copy(optionsStrategies, gl.optionsStrategies)
+
paramCount.Store(gl.paramCount.Load())
}
@@ -63,7 +73,6 @@ func NewGremlinLang(gl *GremlinLang) *GremlinLang {
func (gl *GremlinLang) addToGremlin(name string, args ...interface{}) error {
flattenedArgs := gl.flattenArguments(args...)
if name == "CardinalityValueTraversal" {
- gl.gremlin = append(gl.gremlin, "Cardinality.")
str0, err := gl.argAsString(flattenedArgs[0])
if err != nil {
return err
@@ -76,6 +85,7 @@ func (gl *GremlinLang) addToGremlin(name string, args ...interface{}) error {
gl.gremlin = append(gl.gremlin, "(")
gl.gremlin = append(gl.gremlin, str1)
gl.gremlin = append(gl.gremlin, ")")
+ return nil
}
gl.gremlin = append(gl.gremlin, ".")
@@ -112,9 +122,9 @@ func (gl *GremlinLang) argAsString(arg interface{}) (string, error) {
return fmt.Sprintf("\"%s\"", escapeQuotes.Replace(v)), nil
case bool:
return strconv.FormatBool(v), nil
- case uint8:
+ case int8, uint8:
return fmt.Sprintf("%dB", v), nil
- case int8, int16:
+ case int16:
return fmt.Sprintf("%dS", v), nil
case int32, uint16:
return fmt.Sprintf("%d", v), nil
@@ -130,7 +140,7 @@ func (gl *GremlinLang) argAsString(arg interface{}) (string, error) {
return fmt.Sprintf("%dN", v), nil
case float32:
if math.IsNaN(float64(v)) {
- return "Nan", nil
+ return "NaN", nil
}
if math.IsInf(float64(v), 1) {
return "Infinity", nil
@@ -141,7 +151,7 @@ func (gl *GremlinLang) argAsString(arg interface{}) (string, error) {
return fmt.Sprintf("%vF", v), nil
case float64:
if math.IsNaN(v) {
- return "Nan", nil
+ return "NaN", nil
}
if math.IsInf(v, 1) {
return "Infinity", nil
@@ -151,14 +161,19 @@ func (gl *GremlinLang) argAsString(arg interface{}) (string, error) {
}
return fmt.Sprintf("%vD", v), nil
case *SimpleSet:
- return gl.translateSlice(v.ToSlice())
- case *BigDecimal, BigDecimal:
- return fmt.Sprintf("%vM", v), nil
+ return gl.translateSet(v.ToSlice())
+ case BigDecimal:
+ return fmt.Sprintf("%vM", v.Value()), nil
+ case *BigDecimal:
+ return fmt.Sprintf("%vM", v.Value()), nil
case time.Time:
return fmt.Sprintf("datetime(\"%v\")", v.Format(time.RFC3339)), nil
- case cardinality, column, direction, operator, order, pick, pop, barrier, scope, t, merge:
+ case cardinality, column, direction, operator, order, pick, pop, barrier, scope, t, merge, gType:
name := reflect.ValueOf(v).Type().Name()
return fmt.Sprintf("%s.%s", strings.ToUpper(name[:1])+name[1:], v), nil
+ case dt:
+ name := reflect.ValueOf(v).Type().Name()
+ return fmt.Sprintf("%s.%s", strings.ToUpper(name), v), nil
case *Vertex:
id, _ := gl.argAsString(v.Id)
return fmt.Sprintf("new ReferenceVertex(%s,\"%s\")", escapeQuotes.Replace(id), escapeQuotes.Replace(v.Label)), nil
@@ -223,6 +238,8 @@ func (gl *GremlinLang) argAsString(arg interface{}) (string, error) {
gl.parameters[key] = v.Value()
}
return key, nil
+ case uuid.UUID:
+ return fmt.Sprintf("UUID(\"%v\")", v.String()), nil
default:
switch reflect.TypeOf(arg).Kind() {
case reflect.Map:
@@ -269,8 +286,16 @@ func (gl *GremlinLang) translateMap(arg interface{}) (string, error) {
}
func (gl *GremlinLang) translateSlice(arg interface{}) (string, error) {
+ return gl.translateCollection(arg, "[", "]")
+}
+
+func (gl *GremlinLang) translateSet(arg interface{}) (string, error) {
+ return gl.translateCollection(arg, "{", "}")
+}
+
+func (gl *GremlinLang) translateCollection(arg interface{}, open, close string) (string, error) {
sb := strings.Builder{}
- sb.WriteString("[")
+ sb.WriteString(open)
list := reflect.ValueOf(arg)
for i := 0; i < list.Len(); i++ {
@@ -283,82 +308,84 @@ func (gl *GremlinLang) translateSlice(arg interface{}) (string, error) {
}
sb.WriteString(vString)
}
- sb.WriteString("]")
+ sb.WriteString(close)
return sb.String(), nil
}
func (gl *GremlinLang) translateTextPredicate(v *textP) (string, error) {
- if v.operator == "" || len(v.values) == 0 {
+ if v.operator == "" && len(v.values) == 0 {
return "", nil
}
- instructionString := ""
- instructionString += v.operator
- instructionString += "("
- if len(v.values) == 1 {
- argString, err := gl.argAsString(v.values[0])
- if err != nil {
- return "", err
- }
- instructionString += argString
- } else if len(v.values) > 1 {
- for index, arg := range v.values {
- argString, err := gl.argAsString(arg)
- if err != nil {
- return "", err
- }
+ if v.operator == "or" || v.operator == "and" {
+ return gl.translateConnPOp(v.operator, v.values, gl.getPredicateString)
+ }
+ return gl.translatePValue(v.operator, v.values)
+}
- instructionString += argString
- if index < len(v.values)-1 && argString != "" {
- instructionString += ","
- }
- }
+func (gl *GremlinLang) translatePredicate(v *p) (string, error) {
+ if v.operator == "" && len(v.values) == 0 {
+ return "", nil
}
- instructionString += ")"
+ if v.operator == "or" || v.operator == "and" {
+ return gl.translateConnPOp(v.operator, v.values, gl.getPredicateString)
+ }
+ return gl.translatePValue(v.operator, v.values)
+}
- return instructionString, nil
+func (gl *GremlinLang) translateConnPOp(operator string, values []interface{}, translator func(interface{}) (string, error)) (string, error) {
+ arg1, err := translator(values[0])
+ if err != nil {
+ return "", err
+ }
+ arg2, err := translator(values[1])
+ if err != nil {
+ return "", err
+ }
+ return arg1 + "." + operator + "(" + arg2 + ")", nil
}
-func (gl *GremlinLang) translatePredicate(v *p) (string, error) {
+func (gl *GremlinLang) getPredicateString(v interface{}) (string, error) {
+ if val, ok := v.(textP); ok {
+ return gl.translateTextPredicate(&val)
+ }
+ if val, ok := v.(*textP); ok {
+ return gl.translateTextPredicate(val)
+ }
+ if val, ok := v.(p); ok {
+ return gl.translatePredicate(&val)
+ }
+ return gl.translatePredicate(v.(*p))
+}
- if v.operator == "" || len(v.values) == 0 {
- return "", nil
+func (gl *GremlinLang) translatePValue(operator string, values []interface{}) (string, error) {
+ sb := strings.Builder{}
+ sb.WriteString(operator + "(")
+
+ if len(values) > 1 && operator != "between" && operator != "inside" {
+ sb.WriteString("[")
}
- instructionString := ""
- instructionString += v.operator
- instructionString += "("
- if len(v.values) == 1 {
- argString, err := gl.argAsString(v.values[0])
+ for i, arg := range values {
+ argString, err := gl.argAsString(arg)
if err != nil {
return "", err
}
- instructionString += argString
- } else if len(v.values) > 1 {
- if v.operator != "between" && v.operator != "inside" {
- instructionString += "["
- }
- for index, arg := range v.values {
- argString, err := gl.argAsString(arg)
- if err != nil {
- return "", err
- }
-
- instructionString += argString
- if index < len(v.values)-1 && argString != "" {
- instructionString += ","
- }
- }
- if v.operator != "between" && v.operator != "inside" {
- instructionString += "]"
+ sb.WriteString(argString)
+ if i < len(values)-1 && argString != "" {
+ sb.WriteString(",")
}
}
- instructionString += ")"
+ if len(values) > 1 && operator != "between" && operator != "inside" {
+ sb.WriteString("]")
+ }
+ sb.WriteString(")")
- return instructionString, nil
+ return sb.String(), nil
}
+
func (gl *GremlinLang) asParameter(arg interface{}) string {
paramName := fmt.Sprintf("_%d", gl.paramCount.Load())
gl.paramCount.Add(1)
@@ -394,11 +421,15 @@ func (gl *GremlinLang) Reset() {
}
func (gl *GremlinLang) AddSource(name string, arguments ...interface{}) {
- if name == "withStrategies" && len(arguments) != 0 {
+ if (name == "withStrategies" || name == "withoutStrategies") && len(arguments) != 0 {
args := gl.buildStrategyArgs(arguments...)
// possible to have empty strategies list to send
if len(args) != 0 {
- gl.gremlin = append(gl.gremlin, ".withStrategies(")
+ if name == "withoutStrategies" {
+ gl.gremlin = append(gl.gremlin, ".withoutStrategies(")
+ } else {
+ gl.gremlin = append(gl.gremlin, ".withStrategies(")
+ }
gl.gremlin = append(gl.gremlin, args)
gl.gremlin = append(gl.gremlin, ")")
}
@@ -476,8 +507,13 @@ func (gl *GremlinLang) flattenArguments(arguments ...interface{}) []interface{}
arg, ok := argument.([]interface{})
if ok {
for _, nestedArg := range arg {
- converted, _ := gl.convertArgument(nestedArg)
- flatArgs = append(flatArgs, converted)
+ _, isUUID := nestedArg.(uuid.UUID)
+ if isUUID {
+ flatArgs = append(flatArgs, nestedArg)
+ } else {
+ converted, _ := gl.convertArgument(nestedArg)
+ flatArgs = append(flatArgs, converted)
+ }
}
} else {
converted, _ := gl.convertArgument(argument)
@@ -510,6 +546,10 @@ func (gl *GremlinLang) convertArgument(arg interface{}) (interface{}, error) {
}
return newMap, nil
case reflect.Array, reflect.Slice:
+ _, isUUID := arg.(uuid.UUID)
+ if isUUID {
+ return arg, nil
+ }
argList := reflect.ValueOf(arg)
newList := make([]interface{}, argList.Len())
for i := 0; i < argList.Len(); i++ {
diff --git a/gremlin-go/driver/gremlinlang_test.go b/gremlin-go/driver/gremlinlang_test.go
index 450bb729ff..d462e9f77b 100644
--- a/gremlin-go/driver/gremlinlang_test.go
+++ b/gremlin-go/driver/gremlinlang_test.go
@@ -20,9 +20,12 @@ under the License.
package gremlingo
import (
+ "math"
"regexp"
"testing"
"time"
+
+ "github.com/google/uuid"
)
func Test_GremlinLang(t *testing.T) {
@@ -234,12 +237,6 @@ func Test_GremlinLang(t *testing.T) {
},
equals: "g.withSack(0).V(\"3\",\"5\").sack(Operator.sum).by(\"runways\").sack()",
},
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Values("runways").Store("x").V("4").Values("runways").Store("x").By(T__.Constant(1)).V("6").Store("x").By(T__.Constant(1)).Select("x").Unfold().Sum()
- },
- equals: "g.V(\"3\").values(\"runways\").store(\"x\").V(\"4\").values(\"runways\").store(\"x\").by(__.constant(1)).V(\"6\").store(\"x\").by(__.constant(1)).select(\"x\").unfold().sum()",
- },
{
assert: func(g *GraphTraversalSource) *GraphTraversal {
return g.Inject(3, 4, 5)
@@ -641,6 +638,42 @@ func Test_GremlinLang(t *testing.T) {
},
equals: "g.V().has(\"p1\",null)",
},
+ {
+ assert: func(g *GraphTraversalSource) *GraphTraversal {
+ return g.V().HasLabel("person").Values("age").Is(P.Between(26, 30).Or(P.Gt(34)))
+ },
+ equals: "g.V().hasLabel(\"person\").values(\"age\").is(between(26,30).or(gt(34)))",
+ },
+ {
+ assert: func(g *GraphTraversalSource) *GraphTraversal {
+ return g.Inject(1).AsNumber(GType.Double)
+ },
+ equals: "g.inject(1).asNumber(GType.DOUBLE)",
+ },
+ {
+ assert: func(g *GraphTraversalSource) *GraphTraversal {
+ return g.Inject(uuid.MustParse("f47af10b-58cc-4372-a567-0f02b2f3d479"))
+ },
+ equals: "g.inject(UUID(\"f47af10b-58cc-4372-a567-0f02b2f3d479\"))",
+ },
+ {
+ assert: func(g *GraphTraversalSource) *GraphTraversal {
+ return g.V().Filter(T__.Has("name", TextP.StartingWith("m").Or(TextP.StartingWith("p"))))
+ },
+ equals: "g.V().filter(__.has(\"name\",startingWith(\"m\").or(startingWith(\"p\"))))",
+ },
+ {
+ assert: func(g *GraphTraversalSource) *GraphTraversal {
+ return g.V().Has("person", "age", P.Within())
+ },
+ equals: "g.V().has(\"person\",\"age\",within([]))",
+ },
+ {
+ assert: func(g *GraphTraversalSource) *GraphTraversal {
+ return g.Inject(math.NaN()).Is(P.Eq(math.NaN()))
+ },
+ equals: "g.inject(NaN).is(eq(NaN))",
+ },
}
var testsToRun []test
diff --git a/gremlin-go/driver/httpTransporter.go b/gremlin-go/driver/httpTransporter.go
index f11cc104e1..465b80d96e 100644
--- a/gremlin-go/driver/httpTransporter.go
+++ b/gremlin-go/driver/httpTransporter.go
@@ -22,12 +22,10 @@ package gremlingo
import (
"bytes"
"compress/zlib"
- "encoding/hex"
"errors"
"fmt"
"io"
"net/http"
- "os"
"sync"
)
@@ -101,8 +99,9 @@ func (transporter *HttpTransporter) Write(data []byte) error {
return err
}
- str := hex.EncodeToString(all)
- _, _ = fmt.Fprintf(os.Stdout, "Received response data : %s\n", str)
+ // TODO for debug, remove later, and check response handling
+ //str := hex.EncodeToString(all)
+ //_, _ = fmt.Fprintf(os.Stdout, "Received response data : %s\n", str)
fmt.Println("Sending response to responseChannel")
transporter.responseChannel <- all
diff --git a/gremlin-go/driver/logger.go b/gremlin-go/driver/logger.go
index eef29f9b07..f1f8c6986a 100644
--- a/gremlin-go/driver/logger.go
+++ b/gremlin-go/driver/logger.go
@@ -107,7 +107,6 @@ const (
creatingRequest errorKey = "CREATING_REQUEST"
readComplete errorKey = "READ_COMPLETE"
submitStartedString errorKey = "SUBMIT_STARTED_STRING"
- submitStartedBytecode errorKey = "SUBMIT_STARTED_BYTECODE"
failedToCloseInErrorCallback errorKey = "FAILED_TO_CLOSE_IN_ERROR_CALLBACK"
failedToWriteMessage errorKey = "FAILED_TO_WRITE_MESSAGE"
failedToSetWriteDeadline errorKey = "FAILED_TO_SET_WRITE_DEADLINE"
diff --git a/gremlin-go/driver/serializer.go b/gremlin-go/driver/serializer.go
index 5ef970a68f..1e1c7b2bf3 100644
--- a/gremlin-go/driver/serializer.go
+++ b/gremlin-go/driver/serializer.go
@@ -22,8 +22,6 @@ package gremlingo
import (
"bytes"
"encoding/binary"
- "fmt"
- "os"
"sync"
)
@@ -111,13 +109,16 @@ func (gs graphBinarySerializer) deserializeMessage(message []byte) (response, er
if err != nil {
return msg, err
}
- _, _ = fmt.Fprintf(os.Stdout, "Deserializing data : %v\n", n)
+ // TODO for debug, remove later
+ //_, _ = fmt.Fprintf(os.Stdout, "Deserializing data : %v\n", n)
if n == EndOfStream() {
break
}
results = append(results, n)
}
- _, _ = fmt.Fprintf(os.Stdout, "Deserialized results : %s\n", results)
+
+ // TODO for debug, remove later
+ //_, _ = fmt.Fprintf(os.Stdout, "Deserialized results : %s\n", results)
msg.responseResult.data = results
code := readUint32Safe(&message, &i)
msg.responseStatus.code = code
@@ -173,7 +174,7 @@ func initSerializers() {
propertyType: propertyWriter,
vertexPropertyType: vertexPropertyWriter,
pathType: pathWriter,
- datetimeType: timeWriter,
+ datetimeType: dateTimeWriter,
durationType: durationWriter,
directionType: enumWriter,
gTypeType: enumWriter,
@@ -209,7 +210,7 @@ func initDeserializers() {
byteBuffer: readByteBuffer,
// Date Time
- datetimeType: timeReader,
+ datetimeType: dateTimeReader,
durationType: durationReader,
// Graph
diff --git a/gremlin-go/driver/strategies.go b/gremlin-go/driver/strategies.go
index 939f7ea741..c0d8b3b578 100644
--- a/gremlin-go/driver/strategies.go
+++ b/gremlin-go/driver/strategies.go
@@ -74,7 +74,7 @@ func OptionsStrategy(options ...map[string]interface{}) TraversalStrategy {
if len(options) > 0 {
optsMap = options[0]
}
- return &traversalStrategy{name: "OptionsStrategy", configuration: options}
+ return &traversalStrategy{name: "OptionsStrategy", configuration: optsMap}
}
// PartitionStrategy partitions the Vertices, Edges and Vertex properties of a Graph into String named
@@ -210,21 +210,37 @@ type MatchAlgorithmStrategyConfig struct {
}
func ReferenceElementStrategy(options ...map[string]interface{}) TraversalStrategy {
- return &traversalStrategy{name: "ReferenceElementStrategy", configuration: options[0]}
+ config := make(map[string]interface{})
+ if len(options) > 0 {
+ config = options[0]
+ }
+ return &traversalStrategy{name: "ReferenceElementStrategy", configuration: config}
}
func ComputerFinalizationStrategy(options ...map[string]interface{}) TraversalStrategy {
- return &traversalStrategy{name: "ComputerFinalizationStrategy", configuration: options[0]}
+ config := make(map[string]interface{})
+ if len(options) > 0 {
+ config = options[0]
+ }
+ return &traversalStrategy{name: "ComputerFinalizationStrategy", configuration: config}
}
func ProfileStrategy(options ...map[string]interface{}) TraversalStrategy {
- return &traversalStrategy{name: "ProfileStrategy", configuration: options[0]}
+ config := make(map[string]interface{})
+ if len(options) > 0 {
+ config = options[0]
+ }
+ return &traversalStrategy{name: "ProfileStrategy", configuration: config}
}
// Verification strategies
func ComputerVerificationStrategy(options ...map[string]interface{}) TraversalStrategy {
- return &traversalStrategy{name: "ComputerVerificationStrategy", configuration: options[0]}
+ config := make(map[string]interface{})
+ if len(options) > 0 {
+ config = options[0]
+ }
+ return &traversalStrategy{name: "ComputerVerificationStrategy", configuration: config}
}
// EdgeLabelVerificationStrategy does not allow Edge traversal steps to have no label specified.
@@ -290,14 +306,6 @@ func VertexProgramRestrictionStrategy() TraversalStrategy {
return &traversalStrategy{name: "VertexProgramRestrictionStrategy"}
}
-func StandardVerificationStrategy() TraversalStrategy {
- return &traversalStrategy{name: "StandardVerificationStrategy"}
-}
-
-func VertexProgramRestrictionStrategy() TraversalStrategy {
- return &traversalStrategy{name: "VertexProgramRestrictionStrategy"}
-}
-
// Optimization strategies
// AdjacentToIncidentStrategy looks for Vertex- and value-emitting steps followed by a CountGlobalStep and replaces
@@ -387,7 +395,11 @@ func MatchPredicateStrategy() TraversalStrategy {
}
func MessagePassingReductionStrategy(options ...map[string]interface{}) TraversalStrategy {
- return &traversalStrategy{name: "MessagePassingReductionStrategy", configuration: options[0]}
+ config := make(map[string]interface{})
+ if len(options) > 0 {
+ config = options[0]
+ }
+ return &traversalStrategy{name: "MessagePassingReductionStrategy", configuration: config}
}
// OrderLimitStrategy is an OLAP strategy that folds a RangeGlobalStep into a preceding
diff --git a/gremlin-go/driver/translator.go b/gremlin-go/driver/translator.go
deleted file mode 100644
index 10629a51c3..0000000000
--- a/gremlin-go/driver/translator.go
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied. See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package gremlingo
-
-import (
- "fmt"
- "reflect"
- "strings"
- "time"
-)
-
-type Translator interface {
- Translate(bytecode *Bytecode) (string, error)
-}
-
-type translator struct {
- source string
-}
-
-func NewTranslator(source string) Translator {
- return &translator{source}
-}
-
-func (t *translator) Translate(bytecode *Bytecode) (string, error) {
- return t.translate(bytecode, true)
-}
-
-func (t *translator) translate(bytecode *Bytecode, initial bool) (string, error) {
- translated := ""
-
- if initial {
- translated += t.source
- appendDot(&translated)
- }
-
- for _, instruction := range bytecode.sourceInstructions {
- if len(instruction.arguments) == 0 {
- continue
- }
-
- appendDot(&translated)
-
- translatedInstruction, err := t.translateInstruction(instruction)
- if err != nil {
- return "", err
- }
- translated += translatedInstruction
- }
-
- appendDot(&translated)
-
- for _, instruction := range bytecode.stepInstructions {
-
- appendDot(&translated)
-
- translatedInstruction, err := t.translateInstruction(instruction)
- if err != nil {
- return "", err
- }
- translated += translatedInstruction
- }
-
- return translated, nil
-}
-
-func (t *translator) translateInstruction(instruction instruction) (string, error) {
- instructionString := fmt.Sprintf("%v(", instruction.operator)
-
- for index, arg := range instruction.arguments {
- if index > 0 {
- instructionString += ","
- }
-
- if instruction.operator == "with" {
- switch v := arg.(type) {
- case int32, string:
- translatedArg, err := t.translateWithOptions(v)
- if err != nil {
- return "", err
- }
- instructionString += translatedArg
- continue
- }
- }
-
- argString, err := t.toString(arg)
- if err != nil {
- return "", err
- }
- instructionString += argString
-
- }
-
- instructionString += ")"
-
- return instructionString, nil
-}
-
-func (t *translator) translateWithOptions(arg interface{}) (string, error) {
- if groovyWithOptions[arg] != "" {
- return groovyWithOptions[arg], nil
- }
-
- return t.toString(arg)
-}
-
-func (t *translator) translateMap(arg interface{}, isClassParamsMap bool) (string, error) {
- instructionString := ""
- iter := reflect.ValueOf(arg).MapRange()
-
- index := 0
- for iter.Next() {
- if index == 0 && !isClassParamsMap {
- instructionString += "{"
- }
-
- k := iter.Key().Interface()
- kString, err := t.toString(k)
- if err != nil {
- return "", err
- }
- if isClassParamsMap {
- kString = strings.Replace(kString, "'", "", -1)
- }
- v := iter.Value().Interface()
- vString, err := t.toString(v)
- if err != nil {
- return "", err
- }
- instructionString += fmt.Sprintf("%v:%v", kString, vString)
-
- if index < reflect.ValueOf(arg).Len()-1 {
- instructionString += ","
- }
-
- if index == reflect.ValueOf(arg).Len()-1 && !isClassParamsMap {
- instructionString += "}"
- }
- index++
-
- }
-
- return instructionString, nil
-}
-
-func (t *translator) translateSlice(arg interface{}) (string, error) {
- instructionString := "["
- oldSlice := reflect.ValueOf(arg)
- if oldSlice.Len() == 0 {
- return "", nil
- }
-
- for i := 0; i < oldSlice.Len(); i++ {
- if i > 0 {
- instructionString += ","
- }
- instructionStepString, err := t.toString(oldSlice.Index(i).Interface())
- if err != nil {
- return "", err
- }
- instructionString += fmt.Sprintf("%v", instructionStepString)
- }
- instructionString += "]"
-
- return instructionString, nil
-}
-
-func (t *translator) translateTextPredicate(v *textP) (string, error) {
- if v.operator == "" || len(v.values) == 0 {
- return "", nil
- }
-
- instructionString := ""
- instructionString += v.operator
- instructionString += "("
- if len(v.values) == 1 {
- argString, err := t.toString(v.values[0])
- if err != nil {
- return "", err
- }
- instructionString += argString
- } else if len(v.values) > 1 {
- for index, arg := range v.values {
- argString, err := t.toString(arg)
- if err != nil {
- return "", err
- }
-
- instructionString += argString
- if index < len(v.values)-1 && argString != "" {
- instructionString += ","
- }
- }
- }
-
- instructionString += ")"
-
- return instructionString, nil
-}
-
-func (t *translator) translatePredicate(v *p) (string, error) {
-
- if v.operator == "" || len(v.values) == 0 {
- return "", nil
- }
-
- instructionString := ""
- instructionString += v.operator
- instructionString += "("
- if len(v.values) == 1 {
- argString, err := t.toString(v.values[0])
- if err != nil {
- return "", err
- }
- instructionString += argString
- } else if len(v.values) > 1 {
- if v.operator != "between" && v.operator != "inside" {
- instructionString += "["
- }
- for index, arg := range v.values {
- argString, err := t.toString(arg)
- if err != nil {
- return "", err
- }
-
- instructionString += argString
- if index < len(v.values)-1 && argString != "" {
- instructionString += ","
- }
- }
- if v.operator != "between" && v.operator != "inside" {
- instructionString += "]"
- }
- }
-
- instructionString += ")"
-
- return instructionString, nil
-}
-
-func (t *translator) translateTraversalStrategy(v *traversalStrategy) (string, error) {
-
- instructionString := ""
- className := getGroovyClassName(v.name)
- instructionString += fmt.Sprintf("new %v(", className)
- instructionConfigurationString, err := t.translateMap(interface{}(v.configuration), true)
- if err != nil {
- return "", err
- }
- instructionString += instructionConfigurationString
- instructionString += ")"
-
- return instructionString, nil
-
-}
-
-func (t *translator) toString(arg interface{}) (string, error) {
- if arg == nil {
- return "null", nil
- }
- reflectedArg := reflect.TypeOf(arg)
- switch reflectedArg.Kind() {
-
- case reflect.Map:
- return t.translateMap(arg, false)
- case reflect.Slice:
- return t.translateSlice(arg)
- default:
- switch v := arg.(type) {
- case withOptions:
- {
- return groovyWithOptions[v], nil
- }
- case AnonymousTraversal:
- case *AnonymousTraversal:
- return t.toString(arg)
- case *Binding:
- return v.String(), nil
- case GraphTraversal:
- case *GraphTraversal:
- return t.translate(v.Bytecode, false)
- case traversalStrategy:
- case *traversalStrategy:
- return t.translateTraversalStrategy(v)
- case *Bytecode:
- return t.translate(v, false)
- case textP:
- case *textP:
- return t.translateTextPredicate(v)
- case p:
- case *p:
- return t.translatePredicate(v)
- default:
- {
- switch v := arg.(type) {
- case time.Time:
- {
- return timeToGroovyTime(v), nil
- }
- case string:
- {
- return fmt.Sprintf("'%v'", v), nil
- }
- default:
- {
- return fmt.Sprintf("%v", v), nil
- }
- }
- }
- }
- }
-
- return "", nil
-
-}
-
-func appendDot(s *string) {
- if len(*s) == 0 {
- return
- }
-
- if (*s)[len(*s)-1] != '.' {
- *s += "."
- }
-}
-
-func getGroovyClassName(classPath string) string {
- classPathArray := strings.Split(classPath, ".")
- return classPathArray[len(classPathArray)-1]
-}
-
-func timeToGroovyTime(t time.Time) string {
- return fmt.Sprintf("new Date(%v,%v,%v,%v,%v,%v)", t.Year()-1900, int(t.Month()), t.Day(), t.Hour(), t.Minute(), t.Second())
-
-}
-
-var groovyWithOptions map[any]string = map[any]string{
- WithOptions.Tokens: "WithOptions.tokens",
- WithOptions.None: "WithOptions.none",
- WithOptions.Ids: "WithOptions.ids",
- WithOptions.Labels: "WithOptions.labels",
- WithOptions.Keys: "WithOptions.keys",
- WithOptions.Values: "WithOptions.values",
- WithOptions.All: "WithOptions.all",
- WithOptions.Indexer: "WithOptions.indexer",
- WithOptions.List: "WithOptions.list",
- WithOptions.Map: "WithOptions.map",
-}
diff --git a/gremlin-go/driver/translator_test.go b/gremlin-go/driver/translator_test.go
deleted file mode 100644
index 8daa5ce312..0000000000
--- a/gremlin-go/driver/translator_test.go
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied. See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package gremlingo
-
-import (
- "regexp"
- "testing"
- "time"
-)
-
-func Test_translator_Translate(t *testing.T) {
- type test struct {
- name string
- assert func(g *GraphTraversalSource) *GraphTraversal
- equals string
- only bool
- skip bool
- wantErr bool
- containsRandomClassParams bool
- }
- tests := []test{
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V() },
- equals: "g.V()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V("1", "2", "3", "4") },
- equals: "g.V('1','2','3','4')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V("3").ValueMap(true) },
- equals: "g.V('3').valueMap(true)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V().Constant(5) },
- equals: "g.V().constant(5)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V().Constant(1.5) },
- equals: "g.V().constant(1.5)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V().Constant("Hello") },
- equals: "g.V().constant('Hello')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V().HasLabel("airport").Limit(5) },
- equals: "g.V().hasLabel('airport').limit(5)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V().HasLabel(P.Within("a", "b", "c")) },
- equals: "g.V().hasLabel(within(['a','b','c']))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().HasLabel("airport", "continent").Out().Limit(5)
- },
- equals: "g.V().hasLabel('airport','continent').out().limit(5)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().HasLabel("airport").Out().Values("code").Limit(5)
- },
- equals: "g.V().hasLabel('airport').out().values('code').limit(5)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").As("a").Out("route").Limit(10).Where(P.Eq("a")).By("region")
- },
- equals: "g.V('3').as('a').out('route').limit(10).where(eq('a')).by('region')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Repeat(T__.Out("route").SimplePath()).Times(2).Path().By("code")
- },
- equals: "g.V('3').repeat(out('route').simplePath()).times(2).path().by('code')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().HasLabel("airport").Out().Has("region", "US-TX").Values("code").Limit(5)
- },
- equals: "g.V().hasLabel('airport').out().has('region','US-TX').values('code').limit(5)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().HasLabel("airport").Union(T__.Values("city"), T__.Values("region")).Limit(5)
- },
- equals: "g.V().hasLabel('airport').union(values('city'),values('region')).limit(5)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V("3").As("a").Out("route", "routes") },
- equals: "g.V('3').as('a').out('route','routes')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V().Where(T__.Values("runways").Is(5)) },
- equals: "g.V().where(values('runways').is(5))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Repeat(T__.Out().SimplePath()).Until(T__.Has("code", "AGR")).Path().By("code").Limit(5)
- },
- equals: "g.V('3').repeat(out().simplePath()).until(has('code','AGR')).path().by('code').limit(5)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V().HasLabel("airport").Order().By(T__.Id()) },
- equals: "g.V().hasLabel('airport').order().by(id())",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal { return g.V().HasLabel("airport").Order().By(T.Id) },
- equals: "g.V().hasLabel('airport').order().by(id)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().HasLabel("airport").Order().By(T__.Id(), Order.Desc)
- },
- equals: "g.V().hasLabel('airport').order().by(id(),desc)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().HasLabel("airport").Order().By("code", Order.Desc)
- },
- equals: "g.V().hasLabel('airport').order().by('code',desc)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("1", "2", "3").Local(T__.Out().Out().Dedup().Fold())
- },
- equals: "g.V('1','2','3').local(out().out().dedup().fold())",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Out().Path().Count(Scope.Local)
- },
- equals: "g.V('3').out().path().count(local)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.E().Count()
- },
- equals: "g.E().count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("5").OutE("route").InV().Path().Limit(10)
- },
- equals: "g.V('5').outE('route').inV().path().limit(10)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("5").PropertyMap().Select(Column.Keys)
- },
- equals: "g.V('5').propertyMap().select(keys)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("5").PropertyMap().Select(Column.Values)
- },
- equals: "g.V('5').propertyMap().select(values)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Values("runways").Math("_ + 1")
- },
- equals: "g.V('3').values('runways').math('_ + 1')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Emit().Repeat(T__.Out().SimplePath()).Times(3).Limit(5).Path()
- },
- equals: "g.V('3').emit().repeat(out().simplePath()).times(3).limit(5).path()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Match(T__.As("a").Has("code", "LHR").As("b")).Select("b").By("code")
- },
- equals: "g.V().match(as('a').has('code','LHR').as('b')).select('b').by('code')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("test-using-keyword-as-property", "repeat")
- },
- equals: "g.V().has('test-using-keyword-as-property','repeat')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("1").AddE("test").To(T__.V("4"))
- },
- equals: "g.V('1').addE('test').to(V('4'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Values("runways").Max()
- },
- equals: "g.V().values('runways').max()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Values("runways").Min()
- },
- equals: "g.V().values('runways').min()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Values("runways").Sum()
- },
- equals: "g.V().values('runways').sum()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Values("runways").Mean()
- },
- equals: "g.V().values('runways').mean()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithSack(0).V("3", "5").Sack(Operator.Sum).By("runways").Sack()
- },
- equals: "g.withSack(0).V('3','5').sack(sum).by('runways').sack()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.Inject(3, 4, 5)
- },
- equals: "g.inject(3,4,5)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.Inject([]interface{}{3, 4, 5})
- },
- equals: "g.inject([3,4,5])",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.Inject(3, 4, 5).Count()
- },
- equals: "g.inject(3,4,5).count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("runways", P.Gt(5)).Count()
- },
- equals: "g.V().has('runways',gt(5)).count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("runways", P.Lte(5.3)).Count()
- },
- equals: "g.V().has('runways',lte(5.3)).count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("code", P.Within(123, 124))
- },
- equals: "g.V().has('code',within([123,124]))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("code", P.Within(123, "abc"))
- },
- equals: "g.V().has('code',within([123,'abc']))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("code", P.Within("abc", 123))
- },
- equals: "g.V().has('code',within(['abc',123]))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("code", P.Within("abc", "xyz"))
- },
- equals: "g.V().has('code',within(['abc','xyz']))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("1", "2").Has("region", P.Within("US-TX", "US-GA"))
- },
- equals: "g.V('1','2').has('region',within(['US-TX','US-GA']))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().And(T__.Has("runways", P.Gt(5)), T__.Has("region", "US-TX"))
- },
- equals: "g.V().and(has('runways',gt(5)),has('region','US-TX'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Union(T__.Has("runways", P.Gt(5)), T__.Has("region", "US-TX"))
- },
- equals: "g.V().union(has('runways',gt(5)),has('region','US-TX'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Choose(T__.Values("runways").Is(3), T__.Constant("three"), T__.Constant("not three"))
- },
- equals: "g.V('3').choose(values('runways').is(3),constant('three'),constant('not three'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Choose(T__.Values("runways")).Option(1, T__.Constant("three")).Option(2, T__.Constant("not three"))
- },
- equals: "g.V('3').choose(values('runways')).option(1,constant('three')).option(2,constant('not three'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Choose(T__.Values("runways")).Option(1.5, T__.Constant("one and a half")).Option(2, T__.Constant("not three"))
- },
- equals: "g.V('3').choose(values('runways')).option(1.5,constant('one and a half')).option(2,constant('not three'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Repeat(T__.Out().SimplePath()).Until(T__.Loops().Is(1)).Count()
- },
- equals: "g.V('3').repeat(out().simplePath()).until(loops().is(1)).count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().HasLabel("airport").Limit(20).Group().By("region").By("code").Order(Scope.Local).By(Column.Keys)
- },
- equals: "g.V().hasLabel('airport').limit(20).group().by('region').by('code').order(local).by(keys)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("1").As("a").V("2").As("a").Select(Pop.All, "a")
- },
- equals: "g.V('1').as('a').V('2').as('a').select(all,'a')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.AddV("test").Property(Cardinality.Set, "p1", 10)
- },
- equals: "g.addV('test').property(set,'p1',10)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.AddV("test").Property(Cardinality.List, "p1", 10)
- },
- equals: "g.addV('test').property(list,'p1',10)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.AddV("test").Property(Cardinality.Single, "p1", 10)
- },
- equals: "g.addV('test').property(single,'p1',10)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Limit(5).Order().By(T__.Label())
- },
- equals: "g.V().limit(5).order().by(label())",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Range(1, 5)
- },
- equals: "g.V().range(1,5)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.AddV("test").Property("p1", 123)
- },
- equals: "g.addV('test').property('p1',123)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("date", P.Gt(time.Date(2021, 1, 1, 9, 30, 0, 0, time.UTC)))
- },
- equals: "g.V().has('date',gt(new Date(121,1,1,9,30,0)))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.AddE("route").From(T__.V("1")).To(T__.V("2"))
- },
- equals: "g.addE('route').from(V('1')).to(V('2'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithSideEffect("a", []interface{}{1, 2}).V("3").Select("a")
- },
- equals: "g.withSideEffect('a',[1,2]).V('3').select('a')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithSideEffect("a", 1).V("3").Select("a")
- },
- equals: "g.withSideEffect('a',1).V('3').select('a')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithSideEffect("a", "abc").V("3").Select("a")
- },
- equals: "g.withSideEffect('a','abc').V('3').select('a')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("airport", "region", "US-NM").Limit(3).Values("elev").Fold().Index()
- },
- equals: "g.V().has('airport','region','US-NM').limit(3).values('elev').fold().index()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Repeat(T__.TimeLimit(1000).Out().SimplePath()).Until(T__.Has("code", "AGR")).Path()
- },
- equals: "g.V('3').repeat(timeLimit(1000).out().simplePath()).until(has('code','AGR')).path()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().HasLabel("airport").Where(T__.Values("elev").Is(P.Gt(14000)))
- },
- equals: "g.V().hasLabel('airport').where(values('elev').is(gt(14000)))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().HasLabel("airport").Where(T__.Out().Count().Is(P.Gt(250))).Values("code")
- },
- equals: "g.V().hasLabel('airport').where(out().count().is(gt(250))).values('code')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().HasLabel("airport").Filter(T__.Out().Count().Is(P.Gt(250))).Values("code")
- },
- equals: "g.V().hasLabel('airport').filter(out().count().is(gt(250))).values('code')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithSack(0).
- V("3").
- Repeat(T__.OutE("route").Sack(Operator.Sum).By("dist").InV()).
- Until(T__.Has("code", "AGR").Or().Loops().Is(4)).
- Has("code", "AGR").
- Local(T__.Union(T__.Path().By("code").By("dist"), T__.Sack()).Fold()).
- Limit(10)
- },
- equals: "g.withSack(0).V('3').repeat(outE('route').sack(sum).by('dist').inV()).until(has('code','AGR').or().loops().is(4)).has('code','AGR').local(union(path().by('code').by('dist'),sack()).fold()).limit(10)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.AddV().As("a").AddV().As("b").AddE("knows").From("a").To("b")
- },
- equals: "g.addV().as('a').addV().as('b').addE('knows').from('a').to('b')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.AddV("Person").As("a").AddV("Person").As("b").AddE("knows").From("a").To("b")
- },
- equals: "g.addV('Person').as('a').addV('Person').as('b').addE('knows').from('a').to('b')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("3").Project("Out", "In").By(T__.Out().Count()).By(T__.In().Count())
- },
- equals: "g.V('3').project('Out','In').by(out().count()).by(in().count())",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("44").Out().Aggregate("a").Out().Where(P.Within("a")).Path()
- },
- equals: "g.V('44').out().aggregate('a').out().where(within('a')).path()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("date", time.Date(2021, 2, 22, 0, 0, 0, 0, time.UTC))
- },
- equals: "g.V().has('date',new Date(121,2,22,0,0,0))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("date", P.Within(time.Date(2021, 2, 22, 0, 0, 0, 0, time.UTC), time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)))
- },
- equals: "g.V().has('date',within([new Date(121,2,22,0,0,0),new Date(121,1,1,0,0,0)]))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("date", P.Between(time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(2021, 2, 22, 0, 0, 0, 0, time.UTC)))
- },
- equals: "g.V().has('date',between(new Date(121,1,1,0,0,0),new Date(121,2,22,0,0,0)))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("date", P.Inside(time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), time.Date(2021, 2, 22, 0, 0, 0, 0, time.UTC)))
- },
- equals: "g.V().has('date',inside(new Date(121,1,1,0,0,0),new Date(121,2,22,0,0,0)))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("date", P.Gt(time.Date(2021, 1, 1, 9, 30, 0, 0, time.UTC)))
- },
- equals: "g.V().has('date',gt(new Date(121,1,1,9,30,0)))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("runways", P.Between(3, 5))
- },
- equals: "g.V().has('runways',between(3,5))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("runways", P.Inside(3, 5))
- },
- equals: "g.V().has('runways',inside(3,5))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("44").OutE().ElementMap()
- },
- equals: "g.V('44').outE().elementMap()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("44").ValueMap().By(T__.Unfold())
- },
- equals: "g.V('44').valueMap().by(unfold())",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("44").ValueMap().With(WithOptions.Tokens, WithOptions.Labels)
- },
- equals: "g.V('44').valueMap().with(WithOptions.tokens,WithOptions.labels)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("44").ValueMap().With(WithOptions.All)
- },
- equals: "g.V('44').valueMap().with(WithOptions.all)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("44").ValueMap().With(WithOptions.Indexer)
- },
- equals: "g.V('44').valueMap().with(WithOptions.indexer)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V("44").ValueMap().With(WithOptions.Tokens)
- },
- equals: "g.V('44').valueMap().with(WithOptions.tokens)",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithStrategies(ReadOnlyStrategy()).AddV("test")
- },
- equals: "g.withStrategies(new ReadOnlyStrategy()).addV('test')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithStrategies(SubgraphStrategy(SubgraphStrategyConfig{Vertices: T__.Has("region", "US-TX"), Edges: T__.HasLabel("route")})).V().Count()
- },
- containsRandomClassParams: true,
- equals: "g.withStrategies(new SubgraphStrategy(vertices:has('region','US-TX'),edges:hasLabel('route'))).V().count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithStrategies(SubgraphStrategy(SubgraphStrategyConfig{VertexProperties: T__.HasNot("runways")})).V().Count()
- },
- equals: "g.withStrategies(new SubgraphStrategy(vertexProperties:hasNot('runways'))).V().count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithStrategies(SubgraphStrategy(SubgraphStrategyConfig{Vertices: T__.Has("region", "US-TX"), VertexProperties: T__.HasNot("runways")})).V().Count()
- },
- containsRandomClassParams: true,
- equals: "g.withStrategies(new SubgraphStrategy(vertices:has('region','US-TX'),vertexProperties:hasNot('runways'))).V().count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithStrategies(ReadOnlyStrategy(), SubgraphStrategy(SubgraphStrategyConfig{Vertices: T__.Has("region", "US-TX"), Edges: T__.HasLabel("route")})).V().Count()
- },
- containsRandomClassParams: true,
- equals: "g.withStrategies(new ReadOnlyStrategy(),new SubgraphStrategy(vertices:has('region','US-TX'),edges:hasLabel('route'))).V().count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithStrategies(ReadOnlyStrategy(), SubgraphStrategy(SubgraphStrategyConfig{Vertices: T__.Has("region", "US-TX")})).V().Count()
- },
- equals: "g.withStrategies(new ReadOnlyStrategy(),new SubgraphStrategy(vertices:has('region','US-TX'))).V().count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithStrategies(OptionsStrategy(map[string]interface{}{"evaluationTimeout": 500})).V().Count()
- },
- equals: "g.withStrategies(new OptionsStrategy(evaluationTimeout:500)).V().count()",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithStrategies(PartitionStrategy(PartitionStrategyConfig{PartitionKey: "partition", WritePartition: "a", ReadPartitions: NewSimpleSet("a")})).AddV("test")
- },
- containsRandomClassParams: true,
- equals: "g.withStrategies(new PartitionStrategy(includeMetaProperties:false,partitionKey:'partition',writePartition:'a',readPartitions:['a'])).addV('test')",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.WithStrategies(VertexProgramStrategy(VertexProgramStrategyConfig{})).V().ShortestPath().With("~tinkerpop.shortestPath.target", T__.Has("name", "peter"))
- },
- equals: "g.withStrategies(new VertexProgramStrategy()).V().shortestPath().with('~tinkerpop.shortestPath.target',has('name','peter'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("p1", TextP.StartingWith("foo"))
- },
- equals: "g.V().has('p1',startingWith('foo'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("p1", TextP.EndingWith("foo"))
- },
- equals: "g.V().has('p1',endingWith('foo'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("p1", TextP.Containing("foo"))
- },
- equals: "g.V().has('p1',containing('foo'))",
- },
- {
- assert: func(g *GraphTraversalSource) *GraphTraversal {
- return g.V().Has("p1", nil)
- },
- equals: "g.V().has('p1',null)",
- },
- }
-
- var testsToRun []test
-
- onlyTests := make([]test, 0)
- for _, tt := range tests {
- if tt.only {
- onlyTests = append(onlyTests, tt)
- }
- }
-
- if len(onlyTests) > 0 {
- testsToRun = onlyTests
- } else {
- testsToRun = tests
- }
-
- for _, tt := range testsToRun {
- if tt.skip {
- continue
- }
-
- testName := tt.name
- if testName == "" {
- testName = tt.equals
- }
-
- t.Run(testName, func(t *testing.T) {
- tr := &translator{
- source: "g",
- }
- g := NewGraphTraversalSource(nil, nil)
- bytecode := tt.assert(g).Bytecode
- got, err := tr.Translate(bytecode)
- if (err != nil) != tt.wantErr {
- t.Errorf("translator.Translate() error = %v, wantErr %v", err, tt.wantErr)
- return
- }
- if !tt.containsRandomClassParams && got != tt.equals {
- t.Errorf("translator.Translate() = %v, equals %v", got, tt.equals)
- }
-
- if tt.containsRandomClassParams {
- equalsParams := getParams(tt.equals)
- gotParams := getParams(got)
-
- if len(equalsParams) != len(gotParams) {
- t.Errorf("translator.Translate() = %v, equals %v", got, tt.equals)
- }
-
- for _, equalsParam := range equalsParams {
- found := false
- for _, gotParam := range gotParams {
- if equalsParam == gotParam {
- found = true
- break
- }
- }
- if !found {
- t.Errorf("translator.Translate() = %v, equals %v", got, tt.equals)
- }
- }
- }
- })
- }
-}
-
-func getParams(result string) []string {
- pattern := `(\w+:.*?)`
- re := regexp.MustCompile(pattern)
- matches := re.FindAllStringSubmatch(result, -1)
-
- params := make([]string, 0)
- for _, match := range matches {
- if len(match) > 0 {
- params = append(params, match[0])
- }
- }
-
- return params
-}
diff --git a/gremlin-go/driver/traversal.go b/gremlin-go/driver/traversal.go
index a1948e6aa6..b76862849d 100644
--- a/gremlin-go/driver/traversal.go
+++ b/gremlin-go/driver/traversal.go
@@ -33,7 +33,7 @@ type Traverser struct {
// Traversal is the primary way in which graphs are processed.
type Traversal struct {
graph *Graph
- Bytecode *Bytecode
+ Bytecode *Bytecode //TODO remove
GremlinLang *GremlinLang
remote *DriverRemoteConnection
results ResultSet
@@ -162,33 +162,33 @@ var Cardinality = cardinalities{
}
type cv struct {
- Bytecode *Bytecode
+ GremlinLang *GremlinLang
}
type CardValue interface {
- Single(val interface{}) Bytecode
- Set(val interface{}) Bytecode
- List(val interface{}) Bytecode
+ Single(val interface{}) GremlinLang
+ Set(val interface{}) GremlinLang
+ List(val interface{}) GremlinLang
}
var CardinalityValue CardValue = &cv{}
-func (*cv) Single(val interface{}) Bytecode {
- bc := Bytecode{}
- bc.AddSource("CardinalityValueTraversal", Cardinality.Single, val)
- return bc
+func (*cv) Single(val interface{}) GremlinLang {
+ gl := GremlinLang{}
+ gl.AddSource("CardinalityValueTraversal", Cardinality.Single, val)
+ return gl
}
-func (*cv) Set(val interface{}) Bytecode {
- bc := Bytecode{}
- bc.AddSource("CardinalityValueTraversal", Cardinality.Set, val)
- return bc
+func (*cv) Set(val interface{}) GremlinLang {
+ gl := GremlinLang{}
+ gl.AddSource("CardinalityValueTraversal", Cardinality.Set, val)
+ return gl
}
-func (*cv) List(val interface{}) Bytecode {
- bc := Bytecode{}
- bc.AddSource("CardinalityValueTraversal", Cardinality.List, val)
- return bc
+func (*cv) List(val interface{}) GremlinLang {
+ gl := GremlinLang{}
+ gl.AddSource("CardinalityValueTraversal", Cardinality.List, val)
+ return gl
}
type column string
@@ -518,7 +518,7 @@ func newP(operator string, args ...interface{}) Predicate {
return &p{operator: operator, values: values}
}
-func newPWithP(operator string, pp p, args ...interface{}) Predicate {
+func newPWithP(operator string, pp *p, args ...interface{}) Predicate {
values := make([]interface{}, 1)
values[0] = pp
values = append(values, args...)
@@ -606,12 +606,12 @@ func (*p) Without(args ...interface{}) Predicate {
// And Predicate returns a Predicate composed of two predicates (logical AND of them).
func (pp *p) And(args ...interface{}) Predicate {
- return newPWithP("and", *pp, args...)
+ return newPWithP("and", pp, args...)
}
// Or Predicate returns a Predicate composed of two predicates (logical OR of them).
func (pp *p) Or(args ...interface{}) Predicate {
- return newPWithP("or", *pp, args...)
+ return newPWithP("or", pp, args...)
}
type TextPredicate interface {
@@ -784,6 +784,18 @@ type BigDecimal struct {
UnscaledValue *big.Int
}
+func (bd *BigDecimal) Value() *big.Float {
+ // Create the divisor: 10^scale
+ divisor := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(bd.Scale)), nil)
+
+ // Convert unscaled value and divisor to big.Float
+ unscaled := new(big.Float).SetInt(bd.UnscaledValue)
+ div := new(big.Float).SetInt(divisor)
+
+ // Divide: unscaledValue / 10^scale
+ return new(big.Float).Quo(unscaled, div)
+}
+
// ParseBigDecimal creates a BigDecimal from a string value.
func ParseBigDecimal(strValue string) *BigDecimal {
val := &BigDecimal{}
diff --git a/gremlin-go/driver/traversal_test.go b/gremlin-go/driver/traversal_test.go
index 97520bf76c..dff1876726 100644
--- a/gremlin-go/driver/traversal_test.go
+++ b/gremlin-go/driver/traversal_test.go
@@ -36,16 +36,16 @@ func TestTraversal(t *testing.T) {
clone := original.Clone().Out("knows")
cloneClone := clone.Clone().Out("created")
- assert.Equal(t, 2, len(original.Bytecode.stepInstructions))
- assert.Equal(t, 3, len(clone.Bytecode.stepInstructions))
- assert.Equal(t, 4, len(cloneClone.Bytecode.stepInstructions))
+ assert.Equal(t, "g.V().out(\"created\")", original.GremlinLang.GetGremlin())
+ assert.Equal(t, "g.V().out(\"created\").out(\"knows\")", clone.GremlinLang.GetGremlin())
+ assert.Equal(t, "g.V().out(\"created\").out(\"knows\").out(\"created\")", cloneClone.GremlinLang.GetGremlin())
original.Has("person", "name", "marko")
clone.V().Out()
- assert.Equal(t, 3, len(original.Bytecode.stepInstructions))
- assert.Equal(t, 5, len(clone.Bytecode.stepInstructions))
- assert.Equal(t, 4, len(cloneClone.Bytecode.stepInstructions))
+ assert.Equal(t, "g.V().out(\"created\").has(\"person\",\"name\",\"marko\")", original.GremlinLang.GetGremlin())
+ assert.Equal(t, "g.V().out(\"created\").out(\"knows\").V().out()", clone.GremlinLang.GetGremlin())
+ assert.Equal(t, "g.V().out(\"created\").out(\"knows\").out(\"created\")", cloneClone.GremlinLang.GetGremlin())
})
t.Run("Test Iterate with empty removeConnection", func(t *testing.T) {
@@ -524,7 +524,7 @@ func TestTraversal(t *testing.T) {
})
t.Run("Test should extract ID from Vertex", func(t *testing.T) {
- g := cloneGraphTraversalSource(&Graph{}, NewBytecode(nil), nil)
+ g := cloneGraphTraversalSource(&Graph{}, NewGremlinLang(nil), nil)
// Test basic V() step with mixed ID types
vStart := g.V(1, &Vertex{Element: Element{Id: 2}})
diff --git a/gremlin-go/examples/go.mod b/gremlin-go/examples/go.mod
index 20da81ee7d..6dd55e1afc 100644
--- a/gremlin-go/examples/go.mod
+++ b/gremlin-go/examples/go.mod
@@ -26,6 +26,6 @@ replace github.com/apache/tinkerpop/gremlin-go/v3 => ../
require (
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
- github.com/nicksnyder/go-i18n/v2 v2.5.0 // indirect
- golang.org/x/text v0.21.0 // indirect
+ github.com/nicksnyder/go-i18n/v2 v2.6.0 // indirect
+ golang.org/x/text v0.32.0 // indirect
)
diff --git a/gremlin-go/examples/go.sum b/gremlin-go/examples/go.sum
index b3d1c347c8..4d66940fd6 100644
--- a/gremlin-go/examples/go.sum
+++ b/gremlin-go/examples/go.sum
@@ -8,6 +8,7 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/nicksnyder/go-i18n/v2 v2.5.0 h1:3wH1gpaekcgGuwzWdSu7JwJhH9Tk87k1ezt0i1p2/Is=
github.com/nicksnyder/go-i18n/v2 v2.5.0/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ=
+github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
@@ -16,5 +17,6 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
+golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/gremlin-go/go.mod b/gremlin-go/go.mod
index 8b0e656723..c36ea3718d 100644
--- a/gremlin-go/go.mod
+++ b/gremlin-go/go.mod
@@ -20,22 +20,22 @@ module github.com/apache/tinkerpop/gremlin-go/v3
go 1.25
require (
- github.com/cucumber/godog v0.15.0
+ github.com/cucumber/godog v0.15.1
github.com/google/uuid v1.6.0
- github.com/nicksnyder/go-i18n/v2 v2.5.0
- github.com/stretchr/testify v1.9.0
- golang.org/x/text v0.21.0
+ github.com/nicksnyder/go-i18n/v2 v2.6.0
+ github.com/stretchr/testify v1.11.1
+ golang.org/x/text v0.32.0
)
require (
github.com/cucumber/gherkin/go/v26 v26.2.0 // indirect
github.com/cucumber/messages/go/v21 v21.0.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/gofrs/uuid v4.3.1+incompatible // indirect
+ github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
- github.com/hashicorp/go-memdb v1.3.4 // indirect
- github.com/hashicorp/golang-lru v0.5.4 // indirect
+ github.com/hashicorp/go-memdb v1.3.5 // indirect
+ github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
+ github.com/spf13/pflag v1.0.10 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/gremlin-go/go.sum b/gremlin-go/go.sum
index 87eb5eae01..59675a75c5 100644
--- a/gremlin-go/go.sum
+++ b/gremlin-go/go.sum
@@ -1,10 +1,10 @@
-github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
-github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
+github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
+github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI=
github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0=
-github.com/cucumber/godog v0.15.0 h1:51AL8lBXF3f0cyA5CV4TnJFCTHpgiy+1x1Hb3TtZUmo=
-github.com/cucumber/godog v0.15.0/go.mod h1:FX3rzIDybWABU4kuIXLZ/qtqEe1Ac5RdXmqvACJOces=
+github.com/cucumber/godog v0.15.1 h1:rb/6oHDdvVZKS66hrhpjFQFHjthFSrQBCOI1LwshNTI=
+github.com/cucumber/godog v0.15.1/go.mod h1:qju+SQDewOljHuq9NSM66s0xEhogx0q30flfxL4WUk8=
github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI=
github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s=
github.com/cucumber/messages/go/v22 v22.0.0/go.mod h1:aZipXTKc0JnjCsXrJnuZpWhtay93k7Rn3Dee7iyPJjs=
@@ -12,35 +12,40 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
-github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI=
github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
+github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
-github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c=
github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg=
+github.com/hashicorp/go-memdb v1.3.5 h1:b3taDMxCBCBVgyRrS1AZVHO14ubMYZB++QpNhBg+Nyo=
+github.com/hashicorp/go-memdb v1.3.5/go.mod h1:8IVKKBkVe+fxFgdFOYxzQQNjz+sWCyHCdIC/+5+Vy1Y=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
+github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/nicksnyder/go-i18n/v2 v2.5.0 h1:3wH1gpaekcgGuwzWdSu7JwJhH9Tk87k1ezt0i1p2/Is=
-github.com/nicksnyder/go-i18n/v2 v2.5.0/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ=
+github.com/nicksnyder/go-i18n/v2 v2.6.0 h1:C/m2NNWNiTB6SK4Ao8df5EWm3JETSTIGNXBpMJTxzxQ=
+github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
+github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -48,10 +53,10 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
-github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
-golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
+golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
diff --git a/gremlin-python/src/main/python/gremlin_python/process/traversal.py b/gremlin-python/src/main/python/gremlin_python/process/traversal.py
index ba40b8d992..a90678098e 100644
--- a/gremlin-python/src/main/python/gremlin_python/process/traversal.py
+++ b/gremlin-python/src/main/python/gremlin_python/process/traversal.py
@@ -522,7 +522,7 @@ class TextP(P):
def startingWith(*args):
warnings.warn(
"gremlin_python.process.TextP.startingWith will be replaced by "
- "gremlin_python.process.TextP.startingWith.",
+ "gremlin_python.process.TextP.starting_with.",
DeprecationWarning)
return TextP("startingWith", *args)