You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2024/02/06 23:48:37 UTC
(tinkerpop) branch master updated: TINKERPOP-3049 Fixed Cardinality function in onCreate
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/master by this push:
new 66db18e17a TINKERPOP-3049 Fixed Cardinality function in onCreate
new b837fc7eb2 Merge branch '3.7-dev'
66db18e17a is described below
commit 66db18e17ad2937c71a3b2167fd0d7989ab2cbd7
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Tue Feb 6 18:46:13 2024 -0500
TINKERPOP-3049 Fixed Cardinality function in onCreate
Not sure why this wasn't implemented earlier, but I think the intent was that providers would natively handled the CardinalityValueTraversal. Don't think that was a great choice becasue then this feature doesn't work out of the box. CTR
---
CHANGELOG.asciidoc | 1 +
.../traversal/step/map/MergeVertexStep.java | 21 +++++++++--
.../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 3 ++
gremlin-go/driver/cucumber/gremlin.go | 3 ++
.../gremlin-javascript/test/cucumber/gremlin.js | 3 ++
gremlin-python/src/main/python/radish/gremlin.py | 3 ++
.../gremlin/test/features/map/MergeVertex.feature | 44 +++++++++++++++++++++-
7 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index cd9d7e2b11..3029735004 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -24,6 +24,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
=== TinkerPop 3.7.2 (NOT OFFICIALLY RELEASED YET)
* Deprecated `ltrim()` and `rTrim()` in favor of `l_trim()` and `r_trim` in Python.
+* Fixed bug in `onCreate` for `mergeV()` where use of the `Cardinality` functions was not properly handled.
[[release-3-7-1]]
=== TinkerPop 3.7.1 (November 20, 2023)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MergeVertexStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MergeVertexStep.java
index 1b7ba4bafc..713b839e8d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MergeVertexStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MergeVertexStep.java
@@ -145,10 +145,23 @@ public class MergeVertexStep<S> extends MergeStep<S, Vertex, Map> {
*/
final Map<?,?> onCreateMap = onCreateMap(traverser, mergeMap);
- final Object[] flatArgs = onCreateMap.entrySet().stream()
- .flatMap(e -> Stream.of(e.getKey(), e.getValue())).collect(toList()).toArray();
-
- final Vertex vertex = graph.addVertex(flatArgs);
+ // extract the key/value pairs from the map and flatten them into an array but exclude any that have a
+ // CardinalityValueTraversal as the value. you have to ignore those in a call to addVertex because that would
+ // make it so that the Graph had to know how to deal with the CardinalityValueTraversal which it doesn't. this
+ // allows this feature to work out of the box.
+ final Object[] flatArgsWithoutExplicitCardinality = onCreateMap.entrySet().stream().
+ filter(e -> !(e.getValue() instanceof CardinalityValueTraversal)).
+ flatMap(e -> Stream.of(e.getKey(), e.getValue())).collect(toList()).toArray();
+
+ final Vertex vertex = graph.addVertex(flatArgsWithoutExplicitCardinality);
+
+ // deal with values that have the cardinality explicitly set which should only occur on string keys
+ onCreateMap.entrySet().stream().
+ filter(e -> e.getKey() instanceof String && e.getValue() instanceof CardinalityValueTraversal).
+ forEach(e -> {
+ final CardinalityValueTraversal cardinalityValueTraversal = (CardinalityValueTraversal) e.getValue();
+ vertex.property(cardinalityValueTraversal.getCardinality(), (String) e.getKey(), cardinalityValueTraversal.getValue());
+ });
// trigger callbacks for eventing - in this case, it's a VertexAddedEvent
if (this.callbackRegistry != null && !callbackRegistry.getCallbacks().isEmpty()) {
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 4df9adfe09..12fd0ddb9f 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -965,6 +965,9 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
{"g_mergeVXname_markoX_optionXonMatch_age_33_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> {{"age", 33}},Cardinality.Single), ( [...]
{"g_mergeVXname_markoX_optionXonMatch_name_allen_age_setX31X_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"}, [...]
{"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" [...]
+ {"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") [...]
+ {"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(" [...]
+ {"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().H [...]
{"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"])}},
{"g_V_age_min", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Min<object>()}},
{"g_V_foo_min", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("foo").Min<object>()}},
diff --git a/gremlin-go/driver/cucumber/gremlin.go b/gremlin-go/driver/cucumber/gremlin.go
index bef853eefe..b052bf8db4 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -936,6 +936,9 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
"g_mergeVXname_markoX_optionXonMatch_age_33_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": [...]
"g_mergeVXname_markoX_optionXonMatch_name_allen_age_setX31X_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{}]int [...]
"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{}] [...]
+ "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"). [...]
+ "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("a [...]
+ "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 [...]
"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"])}},
"g_V_age_min": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Min()}},
"g_V_foo_min": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("foo").Min()}},
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
index ba94bc9794..e0072a4ffe 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
@@ -956,6 +956,9 @@ const gremlins = {
g_mergeVXname_markoX_optionXonMatch_age_33_singleX: [function({g}) { return g.addV("person").property("name","marko").property(Cardinality.list,"age",29).property(Cardinality.list,"age",31).property(Cardinality.list,"age",32) }, function({g}) { return g.mergeV(new Map([["name","marko"]])).option(Merge.onMatch,new Map([["age",33]]),Cardinality.single) }, function({g}) { return g.V().has("person","name","marko").has("age",33) }, function({g}) { return g.V().has("person","name","marko") [...]
g_mergeVXname_markoX_optionXonMatch_name_allen_age_setX31X_singleX: [function({g}) { return g.addV("person").property("name","marko").property(Cardinality.list,"age",29).property(Cardinality.list,"age",31).property(Cardinality.list,"age",32) }, function({g}) { return g.mergeV(new Map([["name","marko"]])).option(Merge.onMatch,new Map([["name","allen"],["age",CardinalityValue.set(31)]]),Cardinality.single) }, function({g}) { return g.V().has("person","name","marko") }, function({g}) { [...]
g_mergeVXname_markoX_optionXonMatch_name_allen_age_singleX31X_singleX: [function({g}) { return g.addV("person").property("name","marko").property(Cardinality.list,"age",29).property(Cardinality.list,"age",31).property(Cardinality.list,"age",32) }, function({g}) { return g.mergeV(new Map([["name","marko"]])).option(Merge.onMatch,new Map([["name","allen"],["age",CardinalityValue.single(31)]]),Cardinality.single) }, function({g}) { return g.V().has("person","name","marko") }, function({ [...]
+ g_mergeVXname_aliceX_optionXonCreate_age_singleX81XX: [function({g}) { return g.mergeV(new Map([["name","alice"],[T.label,"person"]])).option(Merge.onCreate,new Map([["age",CardinalityValue.single(81)]])) }, function({g}) { return g.V().has("person","name","alice").has("age",81) }, function({g}) { return g.V().has("person","name","alice").has("age") }, function({g}) { return g.V().has("person","name","alice").properties("age") }],
+ g_mergeVXname_aliceX_optionXonCreate_age_setX81XX: [function({g}) { return g.mergeV(new Map([["name","alice"],[T.label,"person"]])).option(Merge.onCreate,new Map([["age",CardinalityValue.set(81)]])) }, function({g}) { return g.V().has("person","name","alice").has("age",81) }, function({g}) { return g.V().has("person","name","alice").has("age") }, function({g}) { return g.V().has("person","name","alice").properties("age") }],
+ g_mergeVXname_aliceX_optionXonCreate_age_singleX81X_age_81_setX: [function({g}) { return g.mergeV(new Map([["name","alice"],[T.label,"person"]])).option(Merge.onCreate,new Map([["age",81]]),Cardinality.set) }, function({g}) { return g.V().has("person","name","alice").has("age",81) }, function({g}) { return g.V().has("person","name","alice").has("age") }, function({g}) { return g.V().has("person","name","alice").properties("age") }],
g_mergeV_hidden_label_key_onMatch_matched_prohibited: [function({g, xx1}) { return g.mergeV(new Map([])).option(Merge.onMatch,xx1) }],
g_V_age_min: [function({g}) { return g.V().values("age").min() }],
g_V_foo_min: [function({g}) { return g.V().values("foo").min() }],
diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py
index ff19fc3506..5c156db166 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -938,6 +938,9 @@ world.gremlins = {
'g_mergeVXname_markoX_optionXonMatch_age_33_singleX': [(lambda g:g.addV('person').property('name','marko').property(Cardinality.list_,'age',29).property(Cardinality.list_,'age',31).property(Cardinality.list_,'age',32)), (lambda g:g.merge_v({'name':'marko'}).option(Merge.on_match,{'age':33},Cardinality.single)), (lambda g:g.V().has('person','name','marko').has('age',33)), (lambda g:g.V().has('person','name','marko').has('age')), (lambda g:g.V().has('person','name','marko').properties( [...]
'g_mergeVXname_markoX_optionXonMatch_name_allen_age_setX31X_singleX': [(lambda g:g.addV('person').property('name','marko').property(Cardinality.list_,'age',29).property(Cardinality.list_,'age',31).property(Cardinality.list_,'age',32)), (lambda g:g.merge_v({'name':'marko'}).option(Merge.on_match,{'name':'allen','age':CardinalityValue.set_(31)},Cardinality.single)), (lambda g:g.V().has('person','name','marko')), (lambda g:g.V().has('person','name','allen').has('age',31)), (lambda g:g.V [...]
'g_mergeVXname_markoX_optionXonMatch_name_allen_age_singleX31X_singleX': [(lambda g:g.addV('person').property('name','marko').property(Cardinality.list_,'age',29).property(Cardinality.list_,'age',31).property(Cardinality.list_,'age',32)), (lambda g:g.merge_v({'name':'marko'}).option(Merge.on_match,{'name':'allen','age':CardinalityValue.single(31)},Cardinality.single)), (lambda g:g.V().has('person','name','marko')), (lambda g:g.V().has('person','name','allen').has('age',33)), (lambda [...]
+ 'g_mergeVXname_aliceX_optionXonCreate_age_singleX81XX': [(lambda g:g.merge_v({'name':'alice',T.label:'person'}).option(Merge.on_create,{'age':CardinalityValue.single(81)})), (lambda g:g.V().has('person','name','alice').has('age',81)), (lambda g:g.V().has('person','name','alice').has('age')), (lambda g:g.V().has('person','name','alice').properties('age'))],
+ 'g_mergeVXname_aliceX_optionXonCreate_age_setX81XX': [(lambda g:g.merge_v({'name':'alice',T.label:'person'}).option(Merge.on_create,{'age':CardinalityValue.set_(81)})), (lambda g:g.V().has('person','name','alice').has('age',81)), (lambda g:g.V().has('person','name','alice').has('age')), (lambda g:g.V().has('person','name','alice').properties('age'))],
+ 'g_mergeVXname_aliceX_optionXonCreate_age_singleX81X_age_81_setX': [(lambda g:g.merge_v({'name':'alice',T.label:'person'}).option(Merge.on_create,{'age':81},Cardinality.set_)), (lambda g:g.V().has('person','name','alice').has('age',81)), (lambda g:g.V().has('person','name','alice').has('age')), (lambda g:g.V().has('person','name','alice').properties('age'))],
'g_mergeV_hidden_label_key_onMatch_matched_prohibited': [(lambda g, xx1=None:g.merge_v({}).option(Merge.on_match,xx1))],
'g_V_age_min': [(lambda g:g.V().age.min_())],
'g_V_foo_min': [(lambda g:g.V().foo.min_())],
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeVertex.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeVertex.feature
index 7c015e3496..af34ce42dd 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeVertex.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/MergeVertex.feature
@@ -926,7 +926,7 @@ Feature: Step - mergeV()
g.addV("person").property("name", "marko").property(Cardinality.list, "age", 29).property(Cardinality.list, "age", 31).property(Cardinality.list, "age", 32)
"""
And the traversal of
- """
+ """e
g.mergeV([name: "marko"]).
option(Merge.onMatch, [name: "allen", age: Cardinality.set(31)], single)
"""
@@ -957,6 +957,48 @@ Feature: Step - mergeV()
And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"allen\").has(\"age\")"
And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"allen\").properties(\"age\")"
+ @MultiProperties
+ Scenario: g_mergeVXname_aliceX_optionXonCreate_age_singleX81XX
+ Given the empty graph
+ And the traversal of
+ """
+ g.mergeV([name: "alice", (T.label): "person"]).
+ option(Merge.onCreate, [age: Cardinality.single(81)])
+ """
+ When iterated to list
+ Then the result should have a count of 1
+ And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"alice\").has(\"age\", 81)"
+ And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"alice\").has(\"age\")"
+ And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"alice\").properties(\"age\")"
+
+ @MultiProperties
+ Scenario: g_mergeVXname_aliceX_optionXonCreate_age_setX81XX
+ Given the empty graph
+ And the traversal of
+ """
+ g.mergeV([name: "alice", (T.label): "person"]).
+ option(Merge.onCreate, [age: Cardinality.set(81)])
+ """
+ When iterated to list
+ Then the result should have a count of 1
+ And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"alice\").has(\"age\", 81)"
+ And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"alice\").has(\"age\")"
+ And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"alice\").properties(\"age\")"
+
+ @MultiProperties
+ Scenario: g_mergeVXname_aliceX_optionXonCreate_age_singleX81X_age_81_setX
+ Given the empty graph
+ And the traversal of
+ """
+ g.mergeV([name: "alice", (T.label): "person"]).
+ option(Merge.onCreate, [age: 81], Cardinality.set)
+ """
+ When iterated to list
+ Then the result should have a count of 1
+ And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"alice\").has(\"age\", 81)"
+ And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"alice\").has(\"age\")"
+ And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"alice\").properties(\"age\")"
+
# cannot use hidden namespace for label key for onMatch
Scenario: g_mergeV_hidden_label_key_onMatch_matched_prohibited
Given the empty graph