Cameron Smith created TINKERPOP-2811:
----------------------------------------
Summary: ElementIdStrategy doesn't replace all references of an
element's id with the specified custom id property
Key: TINKERPOP-2811
URL: https://issues.apache.org/jira/browse/TINKERPOP-2811
Project: TinkerPop
Issue Type: Bug
Components: process
Affects Versions: 3.6.1, 3.4.0
Reporter: Cameron Smith
When using the ElementIdStrategy, if a traversal attempts to filter graph
elements with multiple _has_ steps and the id filter is not the first property
to be filtered on, then the reference to the element's id is not replaced with
the custom id property during the ElementIdStrategy's mutation of the traversal:
{noformat}
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> g =
graph.traversal().withStrategies(ElementIdStrategy.build().create())
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.V().hasId("foo").has("name", "bar").explain()
==>Traversal Explanation
===================================================================================================
Original Traversal [GraphStep(vertex,[]),
HasStep([~id.eq(foo), name.eq(bar)])]ConnectiveStrategy [D]
[GraphStep(vertex,[]), HasStep([~id.eq(foo), name.eq(bar)])]
ElementIdStrategy [D] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
IdentityRemovalStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
MatchPredicateStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
FilterRankingStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
InlineFilterStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
IncidentToAdjacentStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
AdjacentToIncidentStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
EarlyLimitStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
ByModulatorOptimizationStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
RepeatUnrollStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
CountStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
PathRetractionStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
LazyBarrierStrategy [O] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
TinkerGraphCountStrategy [P] [GraphStep(vertex,[]),
HasStep([__id.eq(foo), name.eq(bar)])]
TinkerGraphStepStrategy [P] [TinkerGraphStep(vertex,[__id.eq(foo),
name.eq(bar)])]
TinkerMergeEVStepStrategy [P] [TinkerGraphStep(vertex,[__id.eq(foo),
name.eq(bar)])]
ProfileStrategy [F] [TinkerGraphStep(vertex,[__id.eq(foo),
name.eq(bar)])]
StandardVerificationStrategy [V] [TinkerGraphStep(vertex,[__id.eq(foo),
name.eq(bar)])]Final Traversal
[TinkerGraphStep(vertex,[__id.eq(foo), name.eq(bar)])]
gremlin> g.V().has("name", "bar").hasId("foo").explain()
==>Traversal Explanation
==================================================================================================
Original Traversal [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]ConnectiveStrategy [D]
[GraphStep(vertex,[]), HasStep([name.eq(bar), ~id.eq(foo)])]
ElementIdStrategy [D] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
IdentityRemovalStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
MatchPredicateStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
FilterRankingStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
InlineFilterStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
IncidentToAdjacentStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
AdjacentToIncidentStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
EarlyLimitStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
ByModulatorOptimizationStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
RepeatUnrollStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
CountStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
PathRetractionStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
LazyBarrierStrategy [O] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
TinkerGraphCountStrategy [P] [GraphStep(vertex,[]),
HasStep([name.eq(bar), ~id.eq(foo)])]
TinkerGraphStepStrategy [P]
[TinkerGraphStep(vertex,[foo],[name.eq(bar)])]
TinkerMergeEVStepStrategy [P]
[TinkerGraphStep(vertex,[foo],[name.eq(bar)])]
ProfileStrategy [F]
[TinkerGraphStep(vertex,[foo],[name.eq(bar)])]
StandardVerificationStrategy [V]
[TinkerGraphStep(vertex,[foo],[name.eq(bar)])]Final Traversal
[TinkerGraphStep(vertex,[foo],[name.eq(bar)])]{noformat}
In the above example, the first traversal shows the behavior when id filtering
is done first, and the second traversal demonstrates the behavior when id
filtering is not the first filtering step.
This was reproduced on both TinkerPop 3.6.1 and 3.4.0.
The current workaround is to ensure that when chaining _has_ steps together
that the first filter on id, if filtering on id is required.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)