Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions regress/expected/cypher_match.out
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,25 @@ SELECT * FROM cypher('cypher_match', $$
"nobody" | | | "anybody" | |
(12 rows)

-- Tests to catch match following optional match logic
-- this syntax is invalid in cypher
SELECT * FROM cypher('cypher_match', $$
OPTIONAL MATCH (n)
MATCH (m)
RETURN n,m
$$) AS (n agtype, m agtype);
ERROR: MATCH cannot follow OPTIONAL MATCH
LINE 1: SELECT * FROM cypher('cypher_match', $$
^
SELECT * FROM cypher('cypher_match', $$
MATCH (n)
OPTIONAL MATCH (m)
MATCH (o)
RETURN n,m
$$) AS (n agtype, m agtype);
ERROR: MATCH cannot follow OPTIONAL MATCH
LINE 1: SELECT * FROM cypher('cypher_match', $$
^
--
-- Tests retrieving Var from some parent's cpstate during transformation
--
Expand Down
14 changes: 14 additions & 0 deletions regress/sql/cypher_match.sql
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,20 @@ SELECT * FROM cypher('cypher_match', $$
ORDER BY n, p, m, q
$$) AS (n agtype, r agtype, p agtype, m agtype, s agtype, q agtype);

-- Tests to catch match following optional match logic
-- this syntax is invalid in cypher
SELECT * FROM cypher('cypher_match', $$
OPTIONAL MATCH (n)
MATCH (m)
RETURN n,m
$$) AS (n agtype, m agtype);

SELECT * FROM cypher('cypher_match', $$
MATCH (n)
OPTIONAL MATCH (m)
MATCH (o)
RETURN n,m
$$) AS (n agtype, m agtype);

--
-- Tests retrieving Var from some parent's cpstate during transformation
Expand Down
17 changes: 17 additions & 0 deletions src/backend/parser/cypher_clause.c
Original file line number Diff line number Diff line change
Expand Up @@ -2508,6 +2508,23 @@ static Query *transform_cypher_match_pattern(cypher_parsestate *cpstate,
query = makeNode(Query);
query->commandType = CMD_SELECT;

if(self->optional == true && clause->next)
{
cypher_clause *next = clause->next;
if (is_ag_node(next->self, cypher_match))
{
cypher_match *next_self = (cypher_match *)next->self;
if (!next_self->optional)
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("MATCH cannot follow OPTIONAL MATCH"),
parser_errposition(pstate,
exprLocation((Node *) next_self))));
}
}
}

// If there is no previous clause, transform to a general MATCH clause.
if (self->optional == true && clause->prev != NULL)
{
Expand Down