Martin Häusler created TINKERPOP-2932:
-----------------------------------------

             Summary: EarlyLimitStrategy drops too many steps if two .limit(0) 
steps exist in the query
                 Key: TINKERPOP-2932
                 URL: https://issues.apache.org/jira/browse/TINKERPOP-2932
             Project: TinkerPop
          Issue Type: Bug
          Components: language
    Affects Versions: 3.6.2
            Reporter: Martin Häusler


Please consider the following query (it will work on any graph, content doesn't 
matter):

 
{code:java}
int result = graph.traversal().inject(0).union(
    __.V<Vertex>()
        .has("kind", "entity")
        .limit(0)
        .limit(0)
        .fold()
        .sideEffect(
            
__.unfold<Vertex>().valueMap<String>("type").with(WithOptions.tokens, 
WithOptions.ids).aggregate("groupByType")
        )
        .unfold<Vertex>()
        .aggregate("result")
        .cap<Map<String, Object>>("groupByType", "result")
        .map( traverser -> {
            val map = traverser.get()
            return map.size()
        })
).next() {code}
Please note that the result type is {{int}}. This is perfectly fine and also 
compiles without issues. However, at runtime, this query throws a 
*{{ClassCastException}}*, claiming that {{java.util.HashMap}} cannot be cast to 
{{int}}.

Upon further investigation, I've discovered that the query looks fine in the 
optimizer:

{code}
[InjectStep([<Dummy>]), UnionStep([[GraphStep(vertex,[]), 
HasStep([kind.eq(entity)]), RangeGlobalStep(0,0), RangeGlobalStep(0,0), 
FoldStep, TraversalSideEffectStep([UnfoldStep, PropertyMapStep([type],value), 
AggregateGlobalStep(groupByType,null)]), UnfoldStep, 
AggregateGlobalStep(result,null), SideEffectCapStep([result, groupByType]), 
LambdaMapStep(lambda), EndStep]])]
{code}

... *until* the {{EarlyLimitStrategy}} is executed. After this strategy has 
been executed, the query looks like this:

{code}
[InjectStep([<Dummy>]), UnionStep([[GraphStep(vertex,[]), 
HasStep([kind.eq(entity)]), NoneStep, SideEffectCapStep([result, 
groupByType])]])]
{code}

It is perfectly fine that the side effect was dropped, but the problem is: the 
trailing lambda {{map}} step was also dropped. *This changes the result type of 
the query!*


My *suggested fix* is to stop the {{for}} loop in {{EarlyLimitStrategy}} which 
drops steps as soon as an {{inject}} or {{cap}} step is reached. All steps 
afterwards must not be touched by this optimization.


A *workaround* is to only have a single {{.limit(0)}} in the query. However, 
I'd argue that it should still work even if there are multiple {{.limit(0)}} 
steps as it doesn't change the semantics of the query at all. The query I've 
posted above is auto-generated by our application, that's why it may appear 
strange.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to