Skip to content

Commit ed72a01

Browse files
committed
Fixed bug where specifying label when using Cardinality arg with mergeV caused validatin error as the label would be treated as having cardinality CTR
1 parent 8cdadb6 commit ed72a01

6 files changed

Lines changed: 26 additions & 6 deletions

File tree

  • gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph
  • gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin
  • gremlin-go/driver/cucumber
  • gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber
  • gremlin-python/src/main/python/radish
  • gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4595,7 +4595,9 @@ public default <M, E2> GraphTraversal<S, E> option(final Merge merge, final Map<
45954595
// do explicit cardinality for every single pair in the map
45964596
for (Object k : m.keySet()) {
45974597
final Object o = m.get(k);
4598-
if (!(o instanceof CardinalityValueTraversal))
4598+
4599+
// don't override any explicit settings and can't set cardinality on T
4600+
if (!(o instanceof CardinalityValueTraversal) && !(k instanceof T))
45994601
m.put(k, new CardinalityValueTraversal(cardinality, o));
46004602
}
46014603
((TraversalOptionParent<M, E, E2>) lastStep).addChildOption((M) merge, (Traversal.Admin<E, E2>) new ConstantTraversal<>(m).asAdmin());

gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1443,7 +1443,8 @@ private static IDictionary<string, List<Func<GraphTraversalSource, IDictionary<s
14431443
{"g_mergeVXname_markoX_optionXonMatch_name_allen_age_singleX31X_singleX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name", "marko").Property(Cardinality.List, "age", 29).Property(Cardinality.List, "age", 31).Property(Cardinality.List, "age", 32), (g,p) =>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> {{ "name", "marko" }}).Option(Merge.OnMatch, new Dictionary<object, object> {{ "name", "allen" }, { "age", CardinalityValue.Single(31) }}, Cardinality.Single), (g,p) =>g.V().Has("person", "name", "marko"), (g,p) =>g.V().Has("person", "name", "allen").Has("age", 33), (g,p) =>g.V().Has("person", "name", "allen").Has("age", 31), (g,p) =>g.V().Has("person", "name", "allen").Has("age"), (g,p) =>g.V().Has("person", "name", "allen").Properties<object>("age")}},
14441444
{"g_mergeVXname_aliceX_optionXonCreate_age_singleX81XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> {{ "name", "alice" }, { T.Label, "person" }}).Option(Merge.OnCreate, (IDictionary<object, object>) new Dictionary<object, object> {{ "age", CardinalityValue.Single(81) }}), (g,p) =>g.V().Has("person", "name", "alice").Has("age", 81), (g,p) =>g.V().Has("person", "name", "alice").Has("age"), (g,p) =>g.V().Has("person", "name", "alice").Properties<object>("age")}},
14451445
{"g_mergeVXname_aliceX_optionXonCreate_age_setX81XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> {{ "name", "alice" }, { T.Label, "person" }}).Option(Merge.OnCreate, (IDictionary<object, object>) new Dictionary<object, object> {{ "age", CardinalityValue.Set(81) }}), (g,p) =>g.V().Has("person", "name", "alice").Has("age", 81), (g,p) =>g.V().Has("person", "name", "alice").Has("age"), (g,p) =>g.V().Has("person", "name", "alice").Properties<object>("age")}},
1446-
{"g_mergeVXname_aliceX_optionXonCreate_age_singleX81X_age_81_setX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> {{ "name", "alice" }, { T.Label, "person" }}).Option(Merge.OnCreate, new Dictionary<object, object> {{ "age", 81 }}, Cardinality.Set), (g,p) =>g.V().Has("person", "name", "alice").Has("age", 81), (g,p) =>g.V().Has("person", "name", "alice").Has("age"), (g,p) =>g.V().Has("person", "name", "alice").Properties<object>("age")}},
1446+
{"g_mergeVXname_aliceX_optionXonCreate_age_81_setX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> {{ "name", "alice" }, { T.Label, "person" }}).Option(Merge.OnCreate, new Dictionary<object, object> {{ "age", 81 }}, Cardinality.Set), (g,p) =>g.V().Has("person", "name", "alice").Has("age", 81), (g,p) =>g.V().Has("person", "name", "alice").Has("age"), (g,p) =>g.V().Has("person", "name", "alice").Properties<object>("age")}},
1447+
{"g_mergeVXname_aliceX_optionXonCreate_age_81_label_person_setX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> {{ "name", "alice" }}).Option(Merge.OnCreate, new Dictionary<object, object> {{ "age", 81 }, { T.Label, "person" }}, Cardinality.Set), (g,p) =>g.V().Has("person", "name", "alice").Has("age", 81), (g,p) =>g.V().Has("person", "name", "alice").Has("age"), (g,p) =>g.V().Has("person", "name", "alice").Properties<object>("age")}},
14471448
{"g_mergeV_hidden_label_key_onMatch_matched_prohibited", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.MergeV((IDictionary<object, object>) new Dictionary<object, object> {}).Option(Merge.OnMatch, (IDictionary<object, object>) p["xx1"])}},
14481449
{"g_injectXlist1_list2_list3X_fold_asXmX_mergeVXselectXmX_limitXlocal_1X_unfoldX_optionXonCreate_selectXmX_rangeXlocal_1_2X_unfoldX_optionXonMatch_selectXmX_tailXlocalX_unfoldX_to_match", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 29), (g,p) =>g.Inject<object>(new Dictionary<object, object> {{ T.Label, "person" }, { "name", "marko" }}, new Dictionary<object, object> {{ T.Label, "person" }, { "name", "marko" }}, new Dictionary<object, object> {{ "created", "N" }}).Fold().As("m").MergeV((ITraversal) __.Select<object>("m").Limit<object>(Scope.Local, 1).Unfold<object>()).Option(Merge.OnCreate, (ITraversal) __.Select<object>("m").Range<object>(Scope.Local, 1, 2).Unfold<object>()).Option(Merge.OnMatch, (ITraversal) __.Select<object>("m").Tail<object>(Scope.Local).Unfold<object>()), (g,p) =>g.V().Has("person", "name", "marko").Has("created", "N"), (g,p) =>g.V()}},
14491450
{"g_injectXlist1_list2_list3X_fold_asXmX_mergeVXselectXmX_limitXlocal_1X_unfoldX_optionXonCreate_selectXmX_rangeXlocal_1_2X_unfoldX_optionXonMatch_selectXmX_tailXlocalX_unfoldX_to_create", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name", "marko").Property("age", 29), (g,p) =>g.Inject<object>(new Dictionary<object, object> {{ T.Label, "person" }, { "name", "stephen" }}, new Dictionary<object, object> {{ T.Label, "person" }, { "name", "stephen" }}, new Dictionary<object, object> {{ "created", "N" }}).Fold().As("m").MergeV((ITraversal) __.Select<object>("m").Limit<object>(Scope.Local, 1).Unfold<object>()).Option(Merge.OnCreate, (ITraversal) __.Select<object>("m").Range<object>(Scope.Local, 1, 2).Unfold<object>()).Option(Merge.OnMatch, (ITraversal) __.Select<object>("m").Tail<object>(Scope.Local).Unfold<object>()), (g,p) =>g.V().Has("person", "name", "stephen").HasNot("created"), (g,p) =>g.V()}},

gremlin-go/driver/cucumber/gremlin.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,8 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
14131413
"g_mergeVXname_markoX_optionXonMatch_name_allen_age_singleX31X_singleX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "marko").Property(gremlingo.Cardinality.List, "age", 29).Property(gremlingo.Cardinality.List, "age", 31).Property(gremlingo.Cardinality.List, "age", 32)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.MergeV(map[interface{}]interface{}{"name": "marko" }).Option(gremlingo.Merge.OnMatch, map[interface{}]interface{}{"name": "allen", "age": gremlingo.CardinalityValue.Single(31) }, gremlingo.Cardinality.Single)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "marko")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "allen").Has("age", 33)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "allen").Has("age", 31)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "allen").Has("age")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "allen").Properties("age")}},
14141414
"g_mergeVXname_aliceX_optionXonCreate_age_singleX81XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.MergeV(map[interface{}]interface{}{"name": "alice", gremlingo.T.Label: "person" }).Option(gremlingo.Merge.OnCreate, map[interface{}]interface{}{"age": gremlingo.CardinalityValue.Single(81) })}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has("age", 81)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has("age")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Properties("age")}},
14151415
"g_mergeVXname_aliceX_optionXonCreate_age_setX81XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.MergeV(map[interface{}]interface{}{"name": "alice", gremlingo.T.Label: "person" }).Option(gremlingo.Merge.OnCreate, map[interface{}]interface{}{"age": gremlingo.CardinalityValue.Set(81) })}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has("age", 81)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has("age")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Properties("age")}},
1416-
"g_mergeVXname_aliceX_optionXonCreate_age_singleX81X_age_81_setX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.MergeV(map[interface{}]interface{}{"name": "alice", gremlingo.T.Label: "person" }).Option(gremlingo.Merge.OnCreate, map[interface{}]interface{}{"age": 81 }, gremlingo.Cardinality.Set)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has("age", 81)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has("age")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Properties("age")}},
1416+
"g_mergeVXname_aliceX_optionXonCreate_age_81_setX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.MergeV(map[interface{}]interface{}{"name": "alice", gremlingo.T.Label: "person" }).Option(gremlingo.Merge.OnCreate, map[interface{}]interface{}{"age": 81 }, gremlingo.Cardinality.Set)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has("age", 81)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has("age")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Properties("age")}},
1417+
"g_mergeVXname_aliceX_optionXonCreate_age_81_label_person_setX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.MergeV(map[interface{}]interface{}{"name": "alice" }).Option(gremlingo.Merge.OnCreate, map[interface{}]interface{}{"age": 81, gremlingo.T.Label: "person" }, gremlingo.Cardinality.Set)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has("age", 81)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Has("age")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Properties("age")}},
14171418
"g_mergeV_hidden_label_key_onMatch_matched_prohibited": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.MergeV(map[interface{}]interface{}{ }).Option(gremlingo.Merge.OnMatch, p["xx1"])}},
14181419
"g_injectXlist1_list2_list3X_fold_asXmX_mergeVXselectXmX_limitXlocal_1X_unfoldX_optionXonCreate_selectXmX_rangeXlocal_1_2X_unfoldX_optionXonMatch_selectXmX_tailXlocalX_unfoldX_to_match": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "marko").Property("age", 29)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(map[interface{}]interface{}{gremlingo.T.Label: "person", "name": "marko" }, map[interface{}]interface{}{gremlingo.T.Label: "person", "name": "marko" }, map[interface{}]interface{}{"created": "N" }).Fold().As("m").MergeV(gremlingo.T__.Select("m").Limit(gremlingo.Scope.Local, 1).Unfold()).Option(gremlingo.Merge.OnCreate, gremlingo.T__.Select("m").Range(gremlingo.Scope.Local, 1, 2).Unfold()).Option(gremlingo.Merge.OnMatch, gremlingo.T__.Select("m").Tail(gremlingo.Scope.Local).Unfold())}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "marko").Has("created", "N")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V()}},
14191420
"g_injectXlist1_list2_list3X_fold_asXmX_mergeVXselectXmX_limitXlocal_1X_unfoldX_optionXonCreate_selectXmX_rangeXlocal_1_2X_unfoldX_optionXonMatch_selectXmX_tailXlocalX_unfoldX_to_create": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "marko").Property("age", 29)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(map[interface{}]interface{}{gremlingo.T.Label: "person", "name": "stephen" }, map[interface{}]interface{}{gremlingo.T.Label: "person", "name": "stephen" }, map[interface{}]interface{}{"created": "N" }).Fold().As("m").MergeV(gremlingo.T__.Select("m").Limit(gremlingo.Scope.Local, 1).Unfold()).Option(gremlingo.Merge.OnCreate, gremlingo.T__.Select("m").Range(gremlingo.Scope.Local, 1, 2).Unfold()).Option(gremlingo.Merge.OnMatch, gremlingo.T__.Select("m").Tail(gremlingo.Scope.Local).Unfold())}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "stephen").HasNot("created")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V()}},

gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)