This is an automated email from the ASF dual-hosted git repository.
dehowef pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/age.git
The following commit(s) were added to refs/heads/master by this push:
new b50a5cf8 Fix issue #898 - Crash on property access of node in same
MATCH (#903)
b50a5cf8 is described below
commit b50a5cf8263c0ab4b6bbfa1169596ed6ec149a97
Author: Muhammad Taha Naveed <[email protected]>
AuthorDate: Tue May 9 02:59:31 2023 +0500
Fix issue #898 - Crash on property access of node in same MATCH (#903)
- Transformed entity was not added in cpstate entities before
tranforming props due to which self referencing props were not
resolving. Added them to cpstate before transforming props.
- Added test cases.
---
regress/expected/cypher_match.out | 55 ++++++++++++++++++++++++++++++++++++++
regress/sql/cypher_match.sql | 13 +++++++++
src/backend/parser/cypher_clause.c | 17 ++++++++----
3 files changed, 80 insertions(+), 5 deletions(-)
diff --git a/regress/expected/cypher_match.out
b/regress/expected/cypher_match.out
index 63c623a9..e322a3b7 100644
--- a/regress/expected/cypher_match.out
+++ b/regress/expected/cypher_match.out
@@ -1786,6 +1786,61 @@ SELECT * FROM cypher('cypher_match', $$ MATCH
p=(a)-[b:knows]->()-[b]->(a) RETUR
ERROR: duplicate edge variable 'b' within a clause
LINE 1: ...pher('cypher_match', $$ MATCH p=(a)-[b:knows]->()-[b]->(a) R...
^
+--
+-- self referencing property constraints (issue #898)
+--
+SELECT * FROM cypher('cypher_match', $$ MATCH (a {name:a.name}) RETURN a $$)
as (a agtype);
+ a
+------------------------------------------------------------------------------------------
+ {"id": 281474976710660, "label": "", "properties": {"age": 4, "name":
"F"}}::vertex
+ {"id": 281474976710661, "label": "", "properties": {"age": 4, "name":
"T"}}::vertex
+ {"id": 281474976710659, "label": "", "properties": {"age": 3, "name":
"orphan"}}::vertex
+ {"id": 281474976710667, "label": "", "properties": {"name": "Dave"}}::vertex
+ {"id": 281474976710668, "label": "", "properties": {"name": "John"}}::vertex
+(5 rows)
+
+SELECT * FROM cypher('cypher_match', $$ MATCH (a {name:a.name, age:a.age})
RETURN a $$) as (a agtype);
+ a
+------------------------------------------------------------------------------------------
+ {"id": 281474976710660, "label": "", "properties": {"age": 4, "name":
"F"}}::vertex
+ {"id": 281474976710661, "label": "", "properties": {"age": 4, "name":
"T"}}::vertex
+ {"id": 281474976710659, "label": "", "properties": {"age": 3, "name":
"orphan"}}::vertex
+(3 rows)
+
+SELECT * FROM cypher('cypher_match', $$ MATCH (a {name:a.name}) MATCH (a
{age:a.age}) RETURN a $$) as (a agtype);
+ a
+------------------------------------------------------------------------------------------
+ {"id": 281474976710660, "label": "", "properties": {"age": 4, "name":
"F"}}::vertex
+ {"id": 281474976710661, "label": "", "properties": {"age": 4, "name":
"T"}}::vertex
+ {"id": 281474976710659, "label": "", "properties": {"age": 3, "name":
"orphan"}}::vertex
+(3 rows)
+
+SELECT * FROM cypher('cypher_match', $$ MATCH p=(a)-[u {relationship:
u.relationship}]->(b) RETURN p $$) as (a agtype);
+
a
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [{"id": 281474976710661, "label": "", "properties": {"age": 4, "name":
"T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id":
281474976710666, "start_id": 281474976710661, "properties": {"years": 3,
"relationship": "friends"}}::edge, {"id": 281474976710666, "label": "",
"properties": {"age": 6}}::vertex]::path
+ [{"id": 281474976710659, "label": "", "properties": {"age": 3, "name":
"orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id":
281474976710666, "start_id": 281474976710659, "properties": {"years": 4,
"relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "",
"properties": {"age": 6}}::vertex]::path
+(2 rows)
+
+SELECT * FROM cypher('cypher_match', $$ MATCH p=(a)-[u {relationship:
u.relationship, years: u.years}]->(b) RETURN p $$) as (a agtype);
+
a
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [{"id": 281474976710661, "label": "", "properties": {"age": 4, "name":
"T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id":
281474976710666, "start_id": 281474976710661, "properties": {"years": 3,
"relationship": "friends"}}::edge, {"id": 281474976710666, "label": "",
"properties": {"age": 6}}::vertex]::path
+ [{"id": 281474976710659, "label": "", "properties": {"age": 3, "name":
"orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id":
281474976710666, "start_id": 281474976710659, "properties": {"years": 4,
"relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "",
"properties": {"age": 6}}::vertex]::path
+(2 rows)
+
+SELECT * FROM cypher('cypher_match', $$ MATCH p=(a {name:a.name})-[u
{relationship: u.relationship}]->(b {age:b.age}) RETURN p $$) as (a agtype);
+
a
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ [{"id": 281474976710661, "label": "", "properties": {"age": 4, "name":
"T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id":
281474976710666, "start_id": 281474976710661, "properties": {"years": 3,
"relationship": "friends"}}::edge, {"id": 281474976710666, "label": "",
"properties": {"age": 6}}::vertex]::path
+ [{"id": 281474976710659, "label": "", "properties": {"age": 3, "name":
"orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id":
281474976710666, "start_id": 281474976710659, "properties": {"years": 4,
"relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "",
"properties": {"age": 6}}::vertex]::path
+(2 rows)
+
+SELECT * FROM cypher('cypher_match', $$ CREATE () WITH * MATCH (x{n0:x.n1})
RETURN 0 $$) as (a agtype);
+ a
+---
+(0 rows)
+
--
-- Clean up
--
diff --git a/regress/sql/cypher_match.sql b/regress/sql/cypher_match.sql
index 2205c9e8..75193576 100644
--- a/regress/sql/cypher_match.sql
+++ b/regress/sql/cypher_match.sql
@@ -842,6 +842,19 @@ SELECT * FROM cypher('cypher_match', $$ MATCH
p=(a)-[b]->()-[b:knows]->(a) RETUR
SELECT * FROM cypher('cypher_match', $$ MATCH
p=(a)-[b:knows]->()-[b:knows]->(a) RETURN p $$)as (p agtype);
SELECT * FROM cypher('cypher_match', $$ MATCH p=(a)-[b:knows]->()-[b]->(a)
RETURN p $$)as (p agtype);
+--
+-- self referencing property constraints (issue #898)
+--
+SELECT * FROM cypher('cypher_match', $$ MATCH (a {name:a.name}) RETURN a $$)
as (a agtype);
+SELECT * FROM cypher('cypher_match', $$ MATCH (a {name:a.name, age:a.age})
RETURN a $$) as (a agtype);
+SELECT * FROM cypher('cypher_match', $$ MATCH (a {name:a.name}) MATCH (a
{age:a.age}) RETURN a $$) as (a agtype);
+
+SELECT * FROM cypher('cypher_match', $$ MATCH p=(a)-[u {relationship:
u.relationship}]->(b) RETURN p $$) as (a agtype);
+SELECT * FROM cypher('cypher_match', $$ MATCH p=(a)-[u {relationship:
u.relationship, years: u.years}]->(b) RETURN p $$) as (a agtype);
+SELECT * FROM cypher('cypher_match', $$ MATCH p=(a {name:a.name})-[u
{relationship: u.relationship}]->(b {age:b.age}) RETURN p $$) as (a agtype);
+
+SELECT * FROM cypher('cypher_match', $$ CREATE () WITH * MATCH (x{n0:x.n1})
RETURN 0 $$) as (a agtype);
+
--
-- Clean up
--
diff --git a/src/backend/parser/cypher_clause.c
b/src/backend/parser/cypher_clause.c
index b6640e8e..285ef318 100644
--- a/src/backend/parser/cypher_clause.c
+++ b/src/backend/parser/cypher_clause.c
@@ -3819,6 +3819,13 @@ static List *transform_match_entities(cypher_parsestate
*cpstate, Query *query,
entity = make_transform_entity(cpstate, ENT_VERTEX, (Node *)node,
expr);
+ /*
+ * We want to add tranformed entity to entities before tranforming
props
+ * so that props referncing currently transformed entity can be
resolved.
+ */
+ cpstate->entities = lappend(cpstate->entities, entity);
+ entities = lappend(entities, entity);
+
/* transform the properties if they exist */
if (node->props)
{
@@ -3886,9 +3893,6 @@ static List *transform_match_entities(cypher_parsestate
*cpstate, Query *query,
lappend(cpstate->property_constraint_quals, n);
}
- cpstate->entities = lappend(cpstate->entities, entity);
- entities = lappend(entities, entity);
-
prev_entity = entity;
}
/* odd increments of i are edges */
@@ -3935,7 +3939,12 @@ static List *transform_match_entities(cypher_parsestate
*cpstate, Query *query,
entity = make_transform_entity(cpstate, ENT_EDGE, (Node *)rel,
expr);
+ /*
+ * We want to add tranformed entity to entities before
tranforming props
+ * so that props referncing currently transformed entity can
be resolved.
+ */
cpstate->entities = lappend(cpstate->entities, entity);
+ entities = lappend(entities, entity);
if (rel->props)
{
@@ -4001,8 +4010,6 @@ static List *transform_match_entities(cypher_parsestate
*cpstate, Query *query,
lappend(cpstate->property_constraint_quals, r);
}
- entities = lappend(entities, entity);
-
prev_entity = entity;
}
/* if we have a VLE edge */