[ 
https://issues.apache.org/jira/browse/TINKERPOP-2961?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17751200#comment-17751200
 ] 

Stephen Mallette commented on TINKERPOP-2961:
---------------------------------------------

coming back to this after a long while - sorry it took so long.

> The two queries are equivalent, the only difference is the expression of the 
> traversal "__.as("n4").both().out().out().out().out().as("n2")".

if you reversed the bindings i think it's expected that there would be a 
difference in the result. take a more simplistic example:

{code}
gremlin> g.V().match(__.as('a').out('created').as('b'),
......1>             __.as('b').has('name', 'lop'),
......2>             __.as('b').in('created').as('c'),
......3>             __.as('c').has('age', 29)).
......4>   select('a','c').by('name')
==>[a:marko,c:marko]
==>[a:josh,c:marko]
==>[a:peter,c:marko]
gremlin> g.V().match(__.as('a').out('created').as('b'),
......1>             __.as('b').has('name', 'lop'),
......2>             __.as('c').out('created').as('b'),
......3>             __.as('c').has('age', 29)).
......4>   select('a','c').by('name')  
The provided match pattern is unsolvable: [[MatchStartStep(c), 
VertexStep(OUT,[created],vertex), MatchEndStep(b)], [MatchStartStep(c), 
HasStep([age.eq(29)]), MatchEndStep(null)], [MatchStartStep(b), 
HasStep([name.eq(lop)]), MatchEndStep(null)], [MatchStartStep(a), 
VertexStep(OUT,[created],vertex), MatchEndStep(b)]]
Type ':help' or ':h' for help.
Display stack trace? [yN]
{code}

reversing things in line 2 is unsolvable in this case. in the first example "b" 
is a "software" vertex bound from that first line so it works nicely when you 
traverse {{in('created')}}. But when you reversed it, "c" is not yet bound to 
anything and is thus unsolvable. 

Please re-read the {{match()}} documentation 
[here](https://tinkerpop.apache.org/docs/current/reference/#match-step) as 
there is a neat paragraph there that explains this. I will post here for 
convenience:

{quote}
There are three types of match() traversal patterns.

1. as('a')…​as('b'): both the start and end of the traversal have a declared 
variable.
2. as('a')…​: only the start of the traversal has a declared variable.
3. …​: there are no declared variables.

If a variable is at the start of a traversal pattern it must exist as a label 
in the path history of the traverser else the traverser can not go down that 
path. If a variable is at the end of a traversal pattern then if the variable 
exists in the path history of the traverser, the traverser’s current location 
must match (i.e. equal) its historic location at that same label. However, if 
the variable does not exist in the path history of the traverser, then the 
current location is labeled as the variable and thus, becomes a bound variable 
for subsequent traversal patterns. If a traversal pattern does not have an end 
label, then the traverser must simply "survive" the pattern (i.e. not be 
filtered) to continue to the next pattern. If a traversal pattern does not have 
a start label, then the traverser can go down that path at any point, but will 
only go down that pattern once as a traversal pattern is executed once and only 
once for the history of the traverser. Typically, traversal patterns that do 
not have a start and end label are used in conjunction with and(), or(), and 
where(). Once the traverser has "survived" all the patterns (or at least one 
for or()), match()-step analyzes the traverser
{quote}

The first sentence of the big paragraph describes this important condition that 
is being violated. The exception for "a" in this case is also noted as you read 
further along. 


> Missing exceptions for unsolvable match pattern, which may lead to logic 
> inconsistency
> --------------------------------------------------------------------------------------
>
>                 Key: TINKERPOP-2961
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-2961
>             Project: TinkerPop
>          Issue Type: Bug
>          Components: process
>    Affects Versions: 3.6.0
>            Reporter: Miracy Cavendish
>            Priority: Major
>         Attachments: create-8.log
>
>
> Hi all! From 
> [Discord|https://discord.com/channels/838910279550238720/1064868348925583442/threads/1117146194666332250].
> We noticed that in some cases unsolvable matching will not lead to the 
> exception "unsolvable pattern" in Gremlin.
> For a simple example, in the empty graph, the following query will not lead 
> to an exception, while it will result in an exception in the GraphModern:
> {code:java}
> g.V().match(__.as("A").out().as("B"), __.as("C").out().as("B"), 
> __.as("D").out().as("A"))
> {code}
> In more complex cases, this missing may lead to a worse result.
> For example, in the graph created by attachment _create-8.log_
> {code:java}
> g.V().match(
> __.as("n2").out().as("n1"), 
> __.as("n2").in().in().in().both().in().as("n1"), 
> __.as("n2").both().in().in().as("n3"), 
> __.as("n3").in().both().as("n2"), 
> __.as("n2").in().in().in().in().both().as("n4"), 
> __.as("n2").out().both().in().as("n4"), 
> __.as("n3").both().as("n4"), 
> __.as("n1").in().both().both().both().as("n5")
> ).dedup().count()
> =>306691
> g.V().match(
> __.as("n2").out().as("n1"), 
> __.as("n2").in().in().in().both().in().as("n1"), 
> __.as("n2").both().in().in().as("n3"), 
> __.as("n3").in().both().as("n2"), 
> __.as("n4").both().out().out().out().out().as("n2"), 
> __.as("n2").out().both().in().as("n4"), 
> __.as("n3").both().as("n4"), 
> __.as("n1").in().both().both().both().as("n5")
> ).dedup().count()
> =>306075
> {code}
> The two queries are equivalent, the only difference is the expression of the 
> traversal "__.as("n4").both().out().out().out().out().as("n2")".
> I am not sure which of their results in the correct result, but the logic 
> inconsistency indicates that the missing exception may cause worse results 
> than we thought before.
> After the discussion with [~spmallette], we believe that it would be better 
> if detect the unsolvable pattern before the execution.
> {*}In addition{*}, *it would be highly appreciated if someone can reproduce 
> and confirm the logic inconsistency in the complex cases. I think it may 
> imply other potential issues of the traversal strategies.* And if such logic 
> inconsistency still exists using both solvable equivalent patterns, we will 
> reduce & report is ASAP.
>  
> Best regards,
> Joye Mang



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

Reply via email to