title: Incorrect results when matching multiple labels with Cypher
body: <p>I have a graph that has nodes that represent roles in a permission hierarchy. The permission hierarchy looks like this:</p>
  
  <pre><code>(:role:owners)-[:CONTACT]-&gt;(:role:admins)-[:CONTACT]-&gt;(:role:employees)
  -[:CONTACT]-&gt;(:role:contacts)
  </code></pre>
  
  <p>Contacts are then attached to each of the role nodes like this:</p>
  
  <pre><code>(:contact {id: "1"})-[:CONTACT]-&gt;(:role:owners)
  (:contact {id: "2"})-[:CONTACT]-&gt;(:role:employees)
  </code></pre>
  
  <p>I'm trying to run the following query that returns the <code>:contacts</code> role if the user is an owner or an admin (such as contact 1) and the <code>:employees</code> role if the user is an employee (such as contact 2).</p>
  
  <pre><code>MATCH (c:contact {id: "1"})
  WITH c
  
  MATCH (g:role)
  WHERE
    (c)-[:CONTACT*1..2]-&gt;(:admins)--&gt;(:employees)--&gt;(g:contacts) OR
    (c)-[:CONTACT]-&gt;(g:employees)
  RETURN DISTINCT c, g
  </code></pre>
  
  <p>Expected result</p>
  
  <pre><code>c                          g
  (:contact {id: "1"})       (:role:contacts)
  Returned 1 row
  </code></pre>
  
  <p>Actual result</p>
  
  <pre><code>c                          g
  (:contact {id: "1"})       (:role:owners)
  (:contact {id: "1"})       (:role:admins)
  (:contact {id: "1"})       (:role:employees)
  (:contact {id: "1"})       (:role:contacts)
  Returned 4 rows
  </code></pre>
  
  <p>I thought this query would only return nodes with both the <code>:role</code> label and either <code>:contacts</code> or <code>:employees</code> but instead it also returns nodes with <code>:owners</code> and <code>:admins</code> labels.</p>
  
  <p>Why is it returning these extra nodes and how can I prevent it from doing so? This is for Neo4j 2.1.2.</p>
  
  <p><strong>Additional Information</strong></p>
  
  <p>I think I've found the bug. Looks like the label check is being dropped if a valid path is not found. In the following example, note that there is no path between <code>(c1)</code> and <code>(g:projectcontacts)</code> since there are no <code>(:projectcontacts)</code> nodes.  In this case, the <code>projectcontacts</code> match is dropped and all nodes that match <code>(c1)-[:CONTACT*1..3]-&gt;(g:role)</code> are returned instead.</p>
  
  <p>This is on a Neo4j 2.1.3 server:</p>
  
  <pre><code>neo4j-sh (?)$ CREATE
  &gt;   (o:role:owners {name:"Owners"})-[:CONTACT]-&gt;(:role:admins {name:"Admins"})-[:CONTACT]-&gt;
  &gt;   (e:role:employees {name:"Employees"})-[:CONTACT]-&gt;(:role:contacts {name:"Contacts"})
  &gt; CREATE
  &gt;   (c1:contact {id: "test1"})-[:CONTACT]-&gt;(o)
  &gt; CREATE
  &gt;   (c2:contact {id: "test2"})-[:CONTACT]-&gt;(e)
  &gt; 
  &gt; WITH c1
  &gt; 
  &gt; MATCH (g:role)
  &gt; WHERE
  &gt;   (c1)-[:CONTACT*1..2]-&gt;(:admins)--&gt;(:employees)--&gt;(g:contacts) OR
  &gt;   (c1)-[:CONTACT]-&gt;(g:employees) OR
  &gt;   (c1)-[:CONTACT*1..3]-&gt;(g:projectcontacts)
  &gt; RETURN DISTINCT c1, g;
  +-------------------------------------------------------+
  | c1                     | g                            |
  +-------------------------------------------------------+
  | Node[4439]{id:"test1"} | Node[4438]{name:"Contacts"}  |
  | Node[4439]{id:"test1"} | Node[4436]{name:"Admins"}    |
  | Node[4439]{id:"test1"} | Node[4437]{name:"Employees"} |
  | Node[4439]{id:"test1"} | Node[4435]{name:"Owners"}    |
  +-------------------------------------------------------+
  4 rows
  Nodes created: 6
  Relationships created: 5
  Properties set: 6
  Labels added: 10
  50 ms
  </code></pre>
  
  <p>If we drop the non-existant node label from our match query, we get the expected results.</p>
  
  <pre><code>neo4j-sh (?)$ CREATE
  &gt;   (o:role:owners {name:"Owners"})-[:CONTACT]-&gt;(:role:admins {name:"Admins"})-[:CONTACT]-&gt;
  &gt;   (e:role:employees {name:"Employees"})-[:CONTACT]-&gt;(:role:contacts {name:"Contacts"})
  &gt; CREATE
  &gt;   (c1:contact {id: "test1"})-[:CONTACT]-&gt;(o)
  &gt; CREATE
  &gt;   (c2:contact {id: "test2"})-[:CONTACT]-&gt;(e)
  &gt; 
  &gt; WITH c1
  &gt; 
  &gt; MATCH (g:role)
  &gt; WHERE
  &gt;   (c1)-[:CONTACT*1..2]-&gt;(:admins)--&gt;(:employees)--&gt;(g:contacts) OR
  &gt;   (c1)-[:CONTACT]-&gt;(g:employees)
  &gt; RETURN DISTINCT c1, g;
  +------------------------------------------------------+
  | c1                     | g                           |
  +------------------------------------------------------+
  | Node[4445]{id:"test1"} | Node[4444]{name:"Contacts"} |
  +------------------------------------------------------+
  1 row
  Nodes created: 6
  Relationships created: 5
  Properties set: 6
  Labels added: 10
  55 ms
  </code></pre>