This is an automated email from the ASF dual-hosted git repository.

mtaha pushed a commit to branch PG14
in repository https://gitbox.apache.org/repos/asf/age.git


The following commit(s) were added to refs/heads/PG14 by this push:
     new dbce2dc4 Fix issue 1910: Server crashes when using exists(vle path) 
(#1929)
dbce2dc4 is described below

commit dbce2dc454f9d82ab5d0e6bd6155f7ae44ec9543
Author: John Gemignani <[email protected]>
AuthorDate: Thu Jun 20 06:46:46 2024 -0700

    Fix issue 1910: Server crashes when using exists(vle path) (#1929)
    
    Fixed issue 1910: Server crashes when using exists(path) with explicit
    length paths.
    
    The crash was caused because transform_ColumnRef did not pass down the
    levels_up value into scanNSItemForColumn.
    
    Upon fixing that issue, it was found that the transform_cypher_node
    function did not correctly process the vle_function_end_var end
    variable. In some cases, in the WHERE clause, it needs to be created.
    
    Added regression tests.
---
 regress/expected/cypher_vle.out    | 65 ++++++++++++++++++++++++++++++++++++++
 regress/sql/cypher_vle.sql         | 18 +++++++++++
 src/backend/parser/cypher_clause.c | 19 ++++++++++-
 src/backend/parser/cypher_expr.c   |  2 +-
 4 files changed, 102 insertions(+), 2 deletions(-)

diff --git a/regress/expected/cypher_vle.out b/regress/expected/cypher_vle.out
index 74d392e4..b3cada60 100644
--- a/regress/expected/cypher_vle.out
+++ b/regress/expected/cypher_vle.out
@@ -1044,6 +1044,71 @@ NOTICE:  graph "issue_1043" has been dropped
  
 (1 row)
 
+-- issue 1910
+SELECT create_graph('issue_1910');
+NOTICE:  graph "issue_1910" has been created
+ create_graph 
+--------------
+ 
+(1 row)
+
+SELECT * FROM cypher('issue_1910', $$ MATCH (n) WHERE EXISTS((n)-[*1]-({name: 
'Willem Defoe'}))
+                                      RETURN n.full_name $$) AS (full_name 
agtype);
+ full_name 
+-----------
+(0 rows)
+
+SELECT * FROM cypher('issue_1910', $$ CREATE ({name: 'Jane 
Doe'})-[:KNOWS]->({name: 'John Doe'}) $$) AS (result agtype);
+ result 
+--------
+(0 rows)
+
+SELECT * FROM cypher('issue_1910', $$ CREATE ({name: 'Donald 
Defoe'})-[:KNOWS]->({name: 'Willem Defoe'}) $$) AS (result agtype);
+ result 
+--------
+(0 rows)
+
+SELECT * FROM cypher('issue_1910', $$ MATCH (u {name: 'John Doe'})
+                                      MERGE (u)-[:KNOWS]->({name: 'Willem 
Defoe'}) $$) AS (result agtype);
+ result 
+--------
+(0 rows)
+
+SELECT * FROM cypher('issue_1910', $$ MATCH (n) WHERE EXISTS((n)-[*]-({name: 
'Willem Defoe'}))
+                                      RETURN n.name $$) AS (name agtype);
+      name      
+----------------
+ "Jane Doe"
+ "John Doe"
+ "Donald Defoe"
+(3 rows)
+
+SELECT * FROM cypher('issue_1910', $$ MATCH (n) WHERE EXISTS((n)-[*1]-({name: 
'Willem Defoe'}))
+                                      RETURN n.name $$) AS (name agtype);
+      name      
+----------------
+ "John Doe"
+ "Donald Defoe"
+(2 rows)
+
+SELECT * FROM cypher('issue_1910', $$ MATCH (n) WHERE 
EXISTS((n)-[*2..2]-({name: 'Willem Defoe'}))
+                                      RETURN n.name $$) AS (name agtype);
+    name    
+------------
+ "Jane Doe"
+(1 row)
+
+SELECT drop_graph('issue_1910', true);
+NOTICE:  drop cascades to 3 other objects
+DETAIL:  drop cascades to table issue_1910._ag_label_vertex
+drop cascades to table issue_1910._ag_label_edge
+drop cascades to table issue_1910."KNOWS"
+NOTICE:  graph "issue_1910" has been dropped
+ drop_graph 
+------------
+ 
+(1 row)
+
 --
 -- Clean up
 --
diff --git a/regress/sql/cypher_vle.sql b/regress/sql/cypher_vle.sql
index 20fecf0e..5835627c 100644
--- a/regress/sql/cypher_vle.sql
+++ b/regress/sql/cypher_vle.sql
@@ -339,6 +339,24 @@ SELECT * FROM cypher('issue_1043', $$ MATCH (x)<-[y 
*]-(),({n:y[0].n}) RETURN x
 
 SELECT drop_graph('issue_1043', true);
 
+-- issue 1910
+SELECT create_graph('issue_1910');
+SELECT * FROM cypher('issue_1910', $$ MATCH (n) WHERE EXISTS((n)-[*1]-({name: 
'Willem Defoe'}))
+                                      RETURN n.full_name $$) AS (full_name 
agtype);
+SELECT * FROM cypher('issue_1910', $$ CREATE ({name: 'Jane 
Doe'})-[:KNOWS]->({name: 'John Doe'}) $$) AS (result agtype);
+SELECT * FROM cypher('issue_1910', $$ CREATE ({name: 'Donald 
Defoe'})-[:KNOWS]->({name: 'Willem Defoe'}) $$) AS (result agtype);
+SELECT * FROM cypher('issue_1910', $$ MATCH (u {name: 'John Doe'})
+                                      MERGE (u)-[:KNOWS]->({name: 'Willem 
Defoe'}) $$) AS (result agtype);
+
+SELECT * FROM cypher('issue_1910', $$ MATCH (n) WHERE EXISTS((n)-[*]-({name: 
'Willem Defoe'}))
+                                      RETURN n.name $$) AS (name agtype);
+SELECT * FROM cypher('issue_1910', $$ MATCH (n) WHERE EXISTS((n)-[*1]-({name: 
'Willem Defoe'}))
+                                      RETURN n.name $$) AS (name agtype);
+SELECT * FROM cypher('issue_1910', $$ MATCH (n) WHERE 
EXISTS((n)-[*2..2]-({name: 'Willem Defoe'}))
+                                      RETURN n.name $$) AS (name agtype);
+
+SELECT drop_graph('issue_1910', true);
+
 --
 -- Clean up
 --
diff --git a/src/backend/parser/cypher_clause.c 
b/src/backend/parser/cypher_clause.c
index 8e054a05..d00c2422 100644
--- a/src/backend/parser/cypher_clause.c
+++ b/src/backend/parser/cypher_clause.c
@@ -5355,6 +5355,8 @@ static Expr *transform_cypher_node(cypher_parsestate 
*cpstate,
         {
             cypher_parsestate *parent_cpstate =
                (cypher_parsestate *)pstate->parentParseState->parentParseState;
+            bool is_vle = false;
+
             /*
              *  If expr_kind is WHERE, the expressions are in the parent's
              *  parent's parsestate, due to the way we transform sublinks.
@@ -5372,7 +5374,22 @@ static Expr *transform_cypher_node(cypher_parsestate 
*cpstate,
             {
                 return get_relative_expr(tentity, 2);
             }
-            else
+
+            /*
+             * Is this a VLE end node? We check this now in case it did exist
+             * outside of the WHERE clause. In that case we would want to
+             * process it normally.
+             */
+            is_vle = (strncmp(node->name,
+                              AGE_DEFAULT_PREFIX"vle_function_end_var",
+                              strlen(AGE_DEFAULT_PREFIX"vle_function_end_var"))
+                      == 0);
+
+            /*
+             * The vle end node is an exception and needs to be created if it
+             * doesn't exist. So fall through for it, otherwise error out.
+             */
+            if (!is_vle)
             {
                 ereport(ERROR,
                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
diff --git a/src/backend/parser/cypher_expr.c b/src/backend/parser/cypher_expr.c
index 8d7679a5..97324414 100644
--- a/src/backend/parser/cypher_expr.c
+++ b/src/backend/parser/cypher_expr.c
@@ -472,7 +472,7 @@ static Node *transform_ColumnRef(cypher_parsestate 
*cpstate, ColumnRef *cref)
                 Assert(IsA(field2, String));
 
                 /* try to identify as a column of the RTE */
-                node = scanNSItemForColumn(pstate, pnsi, 0, colname,
+                node = scanNSItemForColumn(pstate, pnsi, levels_up, colname,
                                            cref->location);
 
                 if (node == NULL)

Reply via email to