@@ -61,6 +61,7 @@ upgrade plan.
6161|Breaking |Step Behavior Change |<<group-value-traversal-semantics,group() Value Traversal Semantics>>
6262|Breaking |Step Behavior Change |<<remove-undocumented-with-modulation,Remove Undocumented `with()` modulation>>
6363|Breaking |Step Behavior Change |<<by-modulation-semantics,By Modulation Semantics>>
64+ |Breaking |Step Behavior change |<<element-promoted-for-mergeV>>,Element Promoted for `mergeV()` and `mergeE()`>>
6465|Breaking |Grammar Removal |<<removed-structurevertex-from-grammar,Removed StructureVertex from Grammar>>
6566|Breaking |Grammar Restriction |<<map-keys-restrictions,`Map` keys restrictions>>
6667|Breaking |Grammar Restriction |<<restriction-of-step-arguments,Restriction of Step Arguments>>
@@ -932,6 +933,62 @@ last one, which was not intuitive.
932933See: link:https://issues.apache.org/jira/browse/TINKERPOP-3121[TINKERPOP-3121],
933934link:https://issues.apache.org/jira/browse/TINKERPOP-2974[TINKERPOP-2974]
934935
936+ [[element-promoted-for-mergeV]]
937+ ===== Element Promoted for `mergeV()` and `mergeE()
938+
939+ Mid-traversal usage of `mergeV()` and `mergeE()` had different behavior from their start step counterparts. Used
940+ mid-traversal, it would pass through the current traverser. On the other hand, the start forms would pass through the
941+ newly created or matched `Element`. This was never the intended behavior. As of 3.8.0, the mid-traversal forms now have
942+ the same behavior as start steps. Expect the created or matched `Element` to be provided to the child traversal for
943+ `onCreate` and `onMatch`.
944+
945+ [source,text]
946+ ----
947+ // 3.7.x allowed the following syntax, where each Map is being given to the child
948+ // traversals in option() steps
949+ gremlin> m = [[search: [code: 'IAD', (T.label): 'airport'], create: [desc: 'Washington Dulles International Airport', country: 'US'], match: [elev: 313]],
950+ ......1> [search: [code: 'LTA',(T.label): 'airport'], create: [country: 'US',desc: 'Little Tiny Airport'], match: [elev: 555]],
951+ ......2> [search: [code: 'DCA', (T.label): 'airport'], create: [country: 'US',desc: 'Ronald Reagan Washington National Airport'], match: [elev: 14]]]
952+ ==>[search:[code:IAD,label:airport],create:[desc:Washington Dulles International Airport,country:US],match:[elev:313]]
953+ ==>[search:[code:LTA,label:airport],create:[country:US,desc:Little Tiny Airport],match:[elev:555]]
954+ ==>[search:[code:DCA,label:airport],create:[country:US,desc:Ronald Reagan Washington National Airport],match:[elev:14]]
955+ gremlin> g.inject(m).unfold().
956+ ......1> mergeV(select('search')).
957+ ......2> option(onCreate, select('create')).
958+ ......3> option(onMatch, select('match'))
959+ ==>v[0]
960+ ==>v[4]
961+ ==>v[8]
962+
963+ // 3.8.x will produce an error because the traverser given to select() steps is
964+ // no longer a Map, but is instead the created or matched Vertex and select()
965+ // will not work on that
966+ gremlin> g.inject(m).unfold().
967+ ......1> mergeV(select('search')).
968+ ......2> option(onCreate, select('create')).
969+ ......3> option(onMatch, select('match')).
970+ ......4> elementMap('code','country','desc','elev')
971+ The provided traverser does not map to a value: v[10][TinkerVertex]->[SelectOneStep(last,match,null)][DefaultGraphTraversal] parent[[InjectStep([[{search={code=IAD, label=airport}, create={desc=Washington Dulles International Airport, country=US}, match={elev=313}}, {search={code=LTA, label=airport}, create={country=US, desc=Little Tiny Airport}, match={elev=555}}, {search={code=DCA, label=airport}, create={country=US, desc=Ronald Reagan Washington National Airport}, match={elev=14}}]]), UnfoldStep, MergeVertexStep([SelectOneStep(last,search,null)],[SelectOneStep(last,create,null)],[SelectOneStep(last,match,null)]), NoOpBarrierStep(2500), ElementMapStep([code, country, desc, elev])]]
972+
973+ // in 3.8.0, there are multiple ways to fix this problem and in this case, one
974+ // might access the Map via step label "m":
975+ gremlin> g.inject(m).unfold().as('m').
976+ ......1> mergeV(select('m').select('search')).
977+ ......2> option(onCreate, select('m').select('create')).
978+ ......3> option(onMatch, select('m').select('match')).
979+ ......4> elementMap('code','country','desc','elev')
980+ ==>[id:10,label:airport,country:US,code:IAD,elev:313,desc:Washington Dulles International Airport]
981+ ==>[id:61394,label:airport,country:US,code:LTA,desc:Little Tiny Airport]
982+ ==>[id:7,label:airport,country:US,code:DCA,elev:14,desc:Ronald Reagan Washington National Airport]
983+ ----
984+
985+ Users should carefully search their code for any use of mid-traversal `mergeV()` or `mergeE()` to consider the nature of
986+ their `onCreate` and `onMatch` child traversals. Determine if they are written in a way that expects the traverser to
987+ pass through unchanged to those children. If they are being used in that fashion, it will be necessary to restructure
988+ the traversal around the expectation that the `Element` will be handed to the child.
989+
990+ See link:https://issues.apache.org/jira/browse/TINKERPOP-3056[TINKERPOP-3056]
991+
935992==== Gremlin Grammar Changes
936993
937994A number of changes have been introduced to the Gremlin grammar to help make it be more consistent and easier to use.
0 commit comments