From 7da324aa04fa3a4637e3094343878257a8d85121 Mon Sep 17 00:00:00 2001 From: MuhammadTahaNaveed Date: Wed, 1 Mar 2023 02:13:48 +0500 Subject: [PATCH] Fix Issue #693 - server termination from return exists(path) - Updated assert to pass EXPR_KIND_SELECT_TARGET. - Added regression tests. --- regress/expected/cypher_match.out | 96 ++++++++++++++++++++++++++++++ regress/sql/cypher_match.sql | 23 +++++++ src/backend/parser/cypher_clause.c | 1 + 3 files changed, 120 insertions(+) diff --git a/regress/expected/cypher_match.out b/regress/expected/cypher_match.out index 9ec4112d6..8f325cbe6 100644 --- a/regress/expected/cypher_match.out +++ b/regress/expected/cypher_match.out @@ -720,6 +720,57 @@ AS (u agtype, e agtype, v agtype); {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex | {"id": 3096224743817217, "label": "self", "end_id": 2814749767106561, "start_id": 2814749767106561, "properties": {}}::edge | {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex (1 row) +-- Return exists(pattern) +SELECT * FROM cypher('cypher_match', + $$MATCH (u) RETURN EXISTS((u)-[]->()) $$) +AS (exists agtype); + exists +-------- + false + false + false + false + false + true + true + false + false + true + false + true + false + true + true +(15 rows) + +SELECT * FROM cypher('cypher_match', + $$MATCH p=(u)-[e]->(v) RETURN EXISTS((p)) $$) +AS (exists agtype); + exists +-------- + true + true + true + true + true + true + true +(7 rows) + +SELECT * FROM cypher('cypher_match', + $$MATCH (u)-[e]->(v) RETURN EXISTS((u)-[e]->(v)-[e]->(u))$$) +AS (exists agtype); + exists +-------- + false + false + false + false + false + false + false +(7 rows) + -- These should error -- Bad pattern SELECT * FROM cypher('cypher_match', @@ -809,6 +860,51 @@ AS (u agtype); {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex (1 row) +-- Return exists(property) +SELECT * FROM cypher('cypher_match', + $$MATCH (u) RETURN EXISTS(u.id), properties(u) $$) +AS (exists agtype, properties agtype); + exists | properties +--------+------------------------------------------------------------------------------------------------------------- + false | {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"} + false | {"lst": [1, null, 3.14, "string", {"key": "value"}, []]} + false | {} + false | {"i": 0} + false | {"i": 1} + true | {"id": "initial"} + true | {"id": "middle"} + true | {"id": "end"} + true | {"id": "initial"} + true | {"id": "middle"} + true | {"id": "end"} + true | {"id": "initial"} + true | {"id": "middle"} + true | {"id": "end"} + true | {"id": "initial"} +(15 rows) + +SELECT * FROM cypher('cypher_match', + $$MATCH (u) RETURN EXISTS(u.name), properties(u) $$) +AS (exists agtype, properties agtype); + exists | properties +--------+------------------------------------------------------------------------------------------------------------- + false | {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"} + false | {"lst": [1, null, 3.14, "string", {"key": "value"}, []]} + false | {} + false | {"i": 0} + false | {"i": 1} + false | {"id": "initial"} + false | {"id": "middle"} + false | {"id": "end"} + false | {"id": "initial"} + false | {"id": "middle"} + false | {"id": "end"} + false | {"id": "initial"} + false | {"id": "middle"} + false | {"id": "end"} + false | {"id": "initial"} +(15 rows) + -- should give an error SELECT * FROM cypher('cypher_match', $$MATCH (u) WHERE EXISTS(u) RETURN u$$) diff --git a/regress/sql/cypher_match.sql b/regress/sql/cypher_match.sql index aeed9f386..70f638df2 100644 --- a/regress/sql/cypher_match.sql +++ b/regress/sql/cypher_match.sql @@ -372,6 +372,20 @@ SELECT * FROM cypher('cypher_match', $$MATCH (u)-[e]->(v) WHERE EXISTS((u)-[e]->(u)) AND EXISTS((v)-[e]->(v)) RETURN u, e, v $$) AS (u agtype, e agtype, v agtype); +-- Return exists(pattern) + +SELECT * FROM cypher('cypher_match', + $$MATCH (u) RETURN EXISTS((u)-[]->()) $$) +AS (exists agtype); + +SELECT * FROM cypher('cypher_match', + $$MATCH p=(u)-[e]->(v) RETURN EXISTS((p)) $$) +AS (exists agtype); + +SELECT * FROM cypher('cypher_match', + $$MATCH (u)-[e]->(v) RETURN EXISTS((u)-[e]->(v)-[e]->(u))$$) +AS (exists agtype); + -- These should error -- Bad pattern SELECT * FROM cypher('cypher_match', @@ -410,6 +424,15 @@ SELECT * FROM cypher('cypher_match', $$MATCH (u) WHERE EXISTS(u.id) AND EXISTS((u)-[]->(u)) RETURN u$$) AS (u agtype); +-- Return exists(property) +SELECT * FROM cypher('cypher_match', + $$MATCH (u) RETURN EXISTS(u.id), properties(u) $$) +AS (exists agtype, properties agtype); + +SELECT * FROM cypher('cypher_match', + $$MATCH (u) RETURN EXISTS(u.name), properties(u) $$) +AS (exists agtype, properties agtype); + -- should give an error SELECT * FROM cypher('cypher_match', $$MATCH (u) WHERE EXISTS(u) RETURN u$$) diff --git a/src/backend/parser/cypher_clause.c b/src/backend/parser/cypher_clause.c index 380eef92b..e1e6c94be 100644 --- a/src/backend/parser/cypher_clause.c +++ b/src/backend/parser/cypher_clause.c @@ -5142,6 +5142,7 @@ transform_cypher_clause_as_subquery(cypher_parsestate *cpstate, Assert(pstate->p_expr_kind == EXPR_KIND_NONE || pstate->p_expr_kind == EXPR_KIND_OTHER || pstate->p_expr_kind == EXPR_KIND_WHERE || + pstate->p_expr_kind == EXPR_KIND_SELECT_TARGET || pstate->p_expr_kind == EXPR_KIND_FROM_SUBSELECT); /*