This is an automated email from the ASF dual-hosted git repository.
mtaha pushed a commit to branch PG16
in repository https://gitbox.apache.org/repos/asf/age.git
The following commit(s) were added to refs/heads/PG16 by this push:
new 2a17d942 Fix issue 1910: Server crashes when using exists(vle path)
(#1927)
2a17d942 is described below
commit 2a17d942dbce2fb0f83cc797db5c34edfdbd6c80
Author: John Gemignani <[email protected]>
AuthorDate: Thu Jun 20 06:48:22 2024 -0700
Fix issue 1910: Server crashes when using exists(vle path) (#1927)
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 dfd3fedf..7e21266d 100644
--- a/src/backend/parser/cypher_clause.c
+++ b/src/backend/parser/cypher_clause.c
@@ -5383,6 +5383,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.
@@ -5400,7 +5402,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 499c9528..e1ca6393 100644
--- a/src/backend/parser/cypher_expr.c
+++ b/src/backend/parser/cypher_expr.c
@@ -482,7 +482,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)