diff --git a/regress/expected/cypher_vle.out b/regress/expected/cypher_vle.out index 74d392e47..b3cada60a 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 20fecf0e0..5835627cc 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 dfd3fedfd..7e21266d8 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 499c9528e..e1ca63936 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)