You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@age.apache.org by jo...@apache.org on 2022/03/23 22:43:40 UTC
[incubator-age] branch master updated: Fix Simple Undirected MATCH Case
This is an automated email from the ASF dual-hosted git repository.
joshinnis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-age.git
The following commit(s) were added to refs/heads/master by this push:
new 6df5efb Fix Simple Undirected MATCH Case
6df5efb is described below
commit 6df5efb628b3eac83d3d16c3877e991d66dff20f
Author: Josh Innis <Jo...@gmail.com>
AuthorDate: Wed Mar 23 15:39:59 2022 -0700
Fix Simple Undirected MATCH Case
When a MATCH has two vertices and an undirected edge, where no
information was referenced in the two vertices, such as:
MATCH ()-[e]-() RETURN e;
Only half the number of rows were returned from what was expected.
Every edge should be included twice, once for each direction.
---
regress/expected/cypher_match.out | 11 +++++++++++
regress/expected/cypher_remove.out | 6 ++++--
regress/expected/expr.out | 39 ++++++++++++++++++++++++++++----------
regress/sql/cypher_match.sql | 4 ++++
src/backend/parser/cypher_clause.c | 36 +++++++++++++++++++++++++++++++++--
5 files changed, 82 insertions(+), 14 deletions(-)
diff --git a/regress/expected/cypher_match.out b/regress/expected/cypher_match.out
index d2d387c..cf9ff79 100644
--- a/regress/expected/cypher_match.out
+++ b/regress/expected/cypher_match.out
@@ -127,6 +127,17 @@ $$) AS (a agtype);
{"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
(1 row)
+SELECT * FROM cypher('cypher_match', $$
+ MATCH p=()-[e]-() RETURN e
+$$) AS (a agtype);
+ a
+---------------------------------------------------------------------------------------------------------------------------
+ {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
+ {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
+ {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+ {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+(4 rows)
+
-- Right Path Test
SELECT * FROM cypher('cypher_match', $$
MATCH (a:v1)-[:e1]->(b:v1)-[:e1]->(c:v1) RETURN a, b, c
diff --git a/regress/expected/cypher_remove.out b/regress/expected/cypher_remove.out
index 8129cad..ca2b94a 100644
--- a/regress/expected/cypher_remove.out
+++ b/regress/expected/cypher_remove.out
@@ -447,13 +447,15 @@ SELECT * FROM cypher('cypher_remove', $$MATCH ()-[e:edge_multi_property]-() RETU
a
---------------------------------------------------------------------------------------------------------------------------------------------------------
{"id": 3659174697238529, "label": "edge_multi_property", "end_id": 281474976710664, "start_id": 281474976710663, "properties": {"i": 5, "j": 20}}::edge
-(1 row)
+ {"id": 3659174697238529, "label": "edge_multi_property", "end_id": 281474976710664, "start_id": 281474976710663, "properties": {"i": 5, "j": 20}}::edge
+(2 rows)
SELECT * FROM cypher('cypher_remove', $$MATCH ()-[e:edge_multi_property]-() REMOVE e.i, e.j RETURN e$$) AS (a agtype);
a
------------------------------------------------------------------------------------------------------------------------------------------
{"id": 3659174697238529, "label": "edge_multi_property", "end_id": 281474976710664, "start_id": 281474976710663, "properties": {}}::edge
-(1 row)
+ {"id": 3659174697238529, "label": "edge_multi_property", "end_id": 281474976710664, "start_id": 281474976710663, "properties": {}}::edge
+(2 rows)
--Errors
SELECT * FROM cypher('cypher_remove', $$REMOVE n.i$$) AS (a agtype);
diff --git a/regress/expected/expr.out b/regress/expected/expr.out
index aac5b29..f4fdc4b 100644
--- a/regress/expected/expr.out
+++ b/regress/expected/expr.out
@@ -1664,8 +1664,10 @@ SELECT * FROM cypher('expr', $$ MATCH ()-[e]-() RETURN e $$) AS (expression agty
expression
---------------------------------------------------------------------------------------------------------------------------
{"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
+ {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge
{"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
-(2 rows)
+ {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge
+(4 rows)
-- id()
SELECT * FROM cypher('expr', $$
@@ -1674,8 +1676,10 @@ $$) AS (id agtype);
id
------------------
1407374883553281
+ 1407374883553281
1407374883553282
-(2 rows)
+ 1407374883553282
+(4 rows)
SELECT * FROM cypher('expr', $$
MATCH (v) RETURN id(v)
@@ -1714,8 +1718,10 @@ $$) AS (start_id agtype);
start_id
------------------
1125899906842626
+ 1125899906842626
1125899906842625
-(2 rows)
+ 1125899906842625
+(4 rows)
-- should return null
SELECT * FROM cypher('expr', $$
@@ -1745,8 +1751,10 @@ $$) AS (end_id agtype);
end_id
------------------
1125899906842627
+ 1125899906842627
1125899906842626
-(2 rows)
+ 1125899906842626
+(4 rows)
-- should return null
SELECT * FROM cypher('expr', $$
@@ -1776,8 +1784,10 @@ $$) AS (id agtype, start_id agtype, startNode agtype);
id | start_id | startnode
------------------+------------------+----------------------------------------------------------------------------------
1407374883553281 | 1125899906842626 | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
+ 1407374883553281 | 1125899906842626 | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
1407374883553282 | 1125899906842625 | {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex
-(2 rows)
+ 1407374883553282 | 1125899906842625 | {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex
+(4 rows)
-- should return null
SELECT * FROM cypher('expr', $$
@@ -1807,8 +1817,10 @@ $$) AS (id agtype, end_id agtype, endNode agtype);
id | end_id | endnode
------------------+------------------+---------------------------------------------------------------------------------
1407374883553281 | 1125899906842627 | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
+ 1407374883553281 | 1125899906842627 | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex
1407374883553282 | 1125899906842626 | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
-(2 rows)
+ 1407374883553282 | 1125899906842626 | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex
+(4 rows)
-- should return null
SELECT * FROM cypher('expr', $$
@@ -1839,7 +1851,9 @@ $$) AS (type agtype);
------
"e1"
"e1"
-(2 rows)
+ "e1"
+ "e1"
+(4 rows)
-- should return null
SELECT * FROM cypher('expr', $$
@@ -2094,7 +2108,9 @@ $$) AS (properties agtype);
------------
{}
{}
-(2 rows)
+ {}
+ {}
+(4 rows)
-- should return null
SELECT * FROM cypher('expr', $$
@@ -5641,10 +5657,13 @@ SELECT * FROM cypher('keys', $$MATCH (v) RETURN keys(v)$$) AS (vertex_keys agtyp
SELECT * FROM cypher('keys', $$MATCH ()-[e]-() RETURN keys(e)$$) AS (edge_keys agtype);
edge_keys
-----------
+ []
+ []
["song"]
["song"]
- []
-(3 rows)
+ ["song"]
+ ["song"]
+(6 rows)
SELECT * FROM cypher('keys', $$RETURN keys({a:1,b:'two',c:[1,2,3]})$$) AS (keys agtype);
keys
diff --git a/regress/sql/cypher_match.sql b/regress/sql/cypher_match.sql
index 1ccc316..057e27a 100644
--- a/regress/sql/cypher_match.sql
+++ b/regress/sql/cypher_match.sql
@@ -64,6 +64,10 @@ SELECT * FROM cypher('cypher_match', $$
MATCH (a:v1)-[]->(), ()-[]->(a) RETURN a
$$) AS (a agtype);
+SELECT * FROM cypher('cypher_match', $$
+ MATCH p=()-[e]-() RETURN e
+$$) AS (a agtype);
+
-- Right Path Test
SELECT * FROM cypher('cypher_match', $$
MATCH (a:v1)-[:e1]->(b:v1)-[:e1]->(c:v1) RETURN a, b, c
diff --git a/src/backend/parser/cypher_clause.c b/src/backend/parser/cypher_clause.c
index 2eb738d..92d049d 100644
--- a/src/backend/parser/cypher_clause.c
+++ b/src/backend/parser/cypher_clause.c
@@ -3413,6 +3413,7 @@ static List *transform_match_entities(cypher_parsestate *cpstate, Query *query,
List *entities = NIL;
int i = 0;
bool node_declared_in_prev_clause = false;
+ transform_entity *prev_entity = NULL;
/*
* Iterate through every node in the path, construct the expr node
@@ -3466,11 +3467,14 @@ static List *transform_match_entities(cypher_parsestate *cpstate, Query *query,
n = create_property_constraint_function(cpstate, entity,
node->props);
- cpstate->property_constraint_quals = lappend(cpstate->property_constraint_quals, n);
+ cpstate->property_constraint_quals =
+ 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 */
else
@@ -3487,6 +3491,29 @@ static List *transform_match_entities(cypher_parsestate *cpstate, Query *query,
/* if it is a regular edge */
if (rel->varlen == NULL)
{
+ /*
+ * In the case where the MATCH is one edge and two vertices, the
+ * edge is bidirectional, and neither vertex is included in the
+ * join tree, we need to force one of the vertices into the join
+ * tree to ensure the output is generated correctly.
+ */
+ if (list_length(path->path) == 3 &&
+ rel->dir == CYPHER_REL_DIR_NONE &&
+ !prev_entity->in_join_tree)
+ {
+ cypher_node *node = (cypher_node *)lfirst(lnext(lc));
+
+ if (!INCLUDE_NODE_IN_JOIN_TREE(path, node))
+ {
+ /*
+ * Assigning a variable name here will ensure that when
+ * the next vertex is processed, the vertex will be
+ * included in the join tree.
+ */
+ node->name = get_next_default_alias(cpstate);
+ }
+ }
+
expr = transform_cypher_edge(cpstate, rel, &query->targetList);
entity = make_transform_entity(cpstate, ENT_EDGE, (Node *)rel,
@@ -3499,10 +3526,13 @@ static List *transform_match_entities(cypher_parsestate *cpstate, Query *query,
Node *n = create_property_constraint_function(cpstate,
entity,
rel->props);
- cpstate->property_constraint_quals = lappend(cpstate->property_constraint_quals, n);
+ cpstate->property_constraint_quals =
+ lappend(cpstate->property_constraint_quals, n);
}
entities = lappend(entities, entity);
+
+ prev_entity = entity;
}
/* if we have a VLE edge */
else
@@ -3534,6 +3564,8 @@ static List *transform_match_entities(cypher_parsestate *cpstate, Query *query,
/* add the entity in */
cpstate->entities = lappend(cpstate->entities, vle_entity);
entities = lappend(entities, vle_entity);
+
+ prev_entity = entity;
}
node_declared_in_prev_clause = false;