Silence6666668 opened a new issue, #2378:
URL: https://github.com/apache/age/issues/2378

   **Describe the bug**
   `OPTIONAL MATCH` may incorrectly drop null-preserving outer rows when its 
`WHERE` clause contains a correlated subquery predicate.
   
   In the repro below, no matched `friend` satisfies the `EXISTS { ... }` 
predicate. Under Cypher optional semantics, each outer `p` row should still be 
preserved with `friend = null`.
   
   Instead, Apache AGE returns no rows at all.
   
   **How are you accessing AGE (Command line, driver, etc.)?**
   - PostgreSQL `cypher(...)` wrapper through the local Python 
differential-testing harness
   - Reproducible directly in `psql` inside the Docker container
   
   **What data setup do we need to do?**
   ```pgsql
   SELECT * FROM cypher('fuzz_graph', $$
     CREATE (a:Person {name: 'Alice', age: 30}),
            (b:Person {name: 'Bob', age: 25}),
            (c:Person {name: 'Charlie', age: 35}),
            (a)-[:KNOWS]->(b),
            (a)-[:KNOWS]->(c)
   $$) AS (v agtype);
   ```
   
   **What is the necessary configuration info needed?**
   - Plain Apache AGE Docker image was enough
   - Docker image in local repro: `apache/age`
   - AGE extension version: `1.7.0`
   - PostgreSQL version: `18.1`
   - Graph name used in repro: `fuzz_graph`
   - No extra extensions or special configuration were required
   
   **What is the command that caused the error?**
   ```pgsql
   SELECT * FROM cypher('fuzz_graph', $$
     MATCH (p:Person)
     OPTIONAL MATCH (p)-[:KNOWS]->(friend:Person)
     WHERE EXISTS { (friend)-[:KNOWS]->(:Person) }
     RETURN p.name AS name, friend.name AS friend
     ORDER BY name, friend
   $$) AS (name agtype, friend agtype);
   ```
   
   Returned result on AGE:
   ```text
   (0 rows)
   ```
   
   **Expected behavior**
   Since neither `Bob` nor `Charlie` knows another person in this setup, the 
optional pattern should fail to bind `friend`, but the outer `p` rows should 
remain:
   
   ```text
   Alice, null
   Bob, null
   Charlie, null
   ```
   
   **Environment (please complete the following information):**
   - Version: Apache AGE `1.7.0`
   - PostgreSQL: `18.1`
   - Host OS: Windows 10
   - Architecture: x86_64
   - Deployment: Docker
   
   **Additional context**
   Two control cases suggest this is specifically tied to correlated subquery 
predicates on `OPTIONAL MATCH`, not to `OPTIONAL MATCH` in general.
   
   Control case 1, without the correlated subquery predicate, behaves as 
expected:
   
   ```pgsql
   SELECT * FROM cypher('fuzz_graph', $$
     MATCH (p:Person)
     OPTIONAL MATCH (p)-[:KNOWS]->(friend:Person)
     RETURN p.name AS name, COUNT(DISTINCT friend.name) AS friendCount
     ORDER BY name
   $$) AS (name agtype, friendCount agtype);
   ```
   
   Expected and observed result:
   ```text
   Alice, 2
   Bob, 0
   Charlie, 0
   ```
   
   Control case 2, with `WHERE false`, also preserves null rows correctly:
   
   ```pgsql
   SELECT * FROM cypher('fuzz_graph', $$
     MATCH (p:Person)
     OPTIONAL MATCH (p)-[:KNOWS]->(friend:Person)
     WHERE false
     RETURN p.name AS name, friend.name AS friend
     ORDER BY name
   $$) AS (name agtype, friend agtype);
   ```
   
   Expected and observed result:
   ```text
   Alice, null
   Bob, null
   Charlie, null
   ```
   
   A second variant in the same family also reproduces the issue with `COUNT { 
... }`:
   
   ```pgsql
   SELECT * FROM cypher('fuzz_graph', $$
     MATCH (p:Person)
     OPTIONAL MATCH (p)-[:FRIEND]->(f)
     WHERE COUNT { MATCH (p)-[:FRIEND*..2]->(x) RETURN x } > 1
     RETURN p.name AS person, f.name AS friend
     ORDER BY person, friend
   $$) AS (person agtype, friend agtype);
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to