Fix apache#1513 - Invalid variable reuse in CREATE and MERGE clause (#1515)
Allow the reuse of a previously declared vertex variable only if the succeeding
CREATE/MERGE vertex has associated edges
i.e CREATE (n) CREATE (n) -- invalid
CREATE (n) CREATE (n)-[:edge]->() -- valid
Fixed another invalid variable reuse where in a CREATE path, edge variable
could be duplicated which resulted in ambiguous reference error
Added regression tests
diff --git a/regress/expected/cypher_create.out b/regress/expected/cypher_create.out
index 91b95d3..2388af8 100644
--- a/regress/expected/cypher_create.out
+++ b/regress/expected/cypher_create.out
@@ -714,7 +714,9 @@
SELECT * FROM cypher('cypher_create', $$
CREATE p=() CREATE (p)
$$) as (a agtype);
-ERROR: agtype must resolve to a vertex
+ERROR: variable p already exists
+LINE 2: CREATE p=() CREATE (p)
+ ^
SELECT * FROM cypher('cypher_create', $$
CREATE p=(a)-[p:b]->(a)
$$) as (a agtype);
@@ -748,7 +750,7 @@
SELECT * FROM cypher('cypher_create', $$
CREATE (a)-[e:new]->(p)-[e]->(a)
$$) as (a agtype);
-ERROR: relationships must be specify a label in CREATE.
+ERROR: variable e already exists
LINE 2: CREATE (a)-[e:new]->(p)-[e]->(a)
^
SELECT * FROM cypher('cypher_create', $$
@@ -794,12 +796,123 @@
(1 row)
--
+-- the following tests should fail due to invalid variable reuse (issue#1513)
+--
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n) CREATE (n) RETURN n
+$$) as (n agtype);
+ERROR: variable n already exists
+LINE 2: CREATE (n) CREATE (n) RETURN n
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n), (n) RETURN n
+$$) as (n agtype);
+ERROR: variable n already exists
+LINE 2: CREATE (n), (n) RETURN n
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ MATCH (n) CREATE (n) RETURN n
+$$) as (n agtype);
+ERROR: variable n already exists
+LINE 2: MATCH (n) CREATE (n) RETURN n
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n), (n)-[:edge]->(n), (n) RETURN n
+$$) as (n agtype);
+ERROR: variable n already exists
+LINE 2: CREATE (n), (n)-[:edge]->(n), (n) RETURN n
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(m) CREATE (n), (m) RETURN n
+$$) as (n agtype);
+ERROR: variable n already exists
+LINE 2: CREATE (n)-[e:edge]->(m) CREATE (n), (m) RETURN n
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(m) CREATE (), (m) RETURN m
+$$) as (m agtype);
+ERROR: variable m already exists
+LINE 2: CREATE (n)-[e:edge]->(m) CREATE (), (m) RETURN m
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(m) CREATE (), (e) RETURN e
+$$) as (e agtype);
+ERROR: variable e already exists
+LINE 2: CREATE (n)-[e:edge]->(m) CREATE (), (e) RETURN e
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(m) CREATE (n)-[e:edge]->(m) RETURN e
+$$) as (e agtype);
+ERROR: variable e already exists
+LINE 2: CREATE (n)-[e:edge]->(m) CREATE (n)-[e:edge]->(m) RETURN e
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ WITH {id: 281474976710657, label: "", properties: {}}::vertex AS n CREATE (n) RETURN n
+$$) as (n agtype);
+ERROR: variable n already exists
+LINE 2: ..., label: "", properties: {}}::vertex AS n CREATE (n) RETURN ...
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(n)-[e:edge]->(n) RETURN e
+$$) as (e agtype);
+ERROR: variable e already exists
+LINE 2: CREATE (n)-[e:edge]->(n)-[e:edge]->(n) RETURN e
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ CREATE ()-[e:edge]->(), (n)-[e:edge]->(n)-[e:edge]->(n) RETURN e
+$$) as (e agtype);
+ERROR: variable e already exists
+LINE 2: CREATE ()-[e:edge]->(), (n)-[e:edge]->(n)-[e:edge]->(n) RET...
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(m) CREATE (e)-[:edge]->() RETURN e
+$$) as (e agtype);
+ERROR: variable e already exists
+LINE 2: CREATE (n)-[e:edge]->(m) CREATE (e)-[:edge]->() RETURN e
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ WITH {id: 1407374883553281, label: "edge", end_id: 281474976710658, start_id: 281474976710657, properties: {}}::edge AS e CREATE ()-[e:edge]->() RETURN e
+$$) as (e agtype);
+ERROR: variable e already exists
+LINE 2: ...74976710657, properties: {}}::edge AS e CREATE ()-[e:edge]->...
+ ^
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n) WITH n AS r CREATE (r) RETURN r
+$$) as (r agtype);
+ERROR: variable r already exists
+LINE 2: CREATE (n) WITH n AS r CREATE (r) RETURN r
+ ^
+-- valid variable reuse
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e1:edge]->(m) CREATE (n)-[e2:edge]->(m)
+$$) as (n agtype);
+ n
+---
+(0 rows)
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n) WITH n AS r CREATE (r)-[e:edge]->() RETURN r
+$$) as (r agtype);
+ r
+----------------------------------------------------------------
+ {"id": 281474976710685, "label": "", "properties": {}}::vertex
+(1 row)
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n), (m) WITH n AS r CREATE (m) RETURN m
+$$) as (m agtype);
+ m
+----------------------------------------------------------------
+ {"id": 281474976710689, "label": "", "properties": {}}::vertex
+(1 row)
+
+--
-- Clean up
--
DROP TABLE simple_path;
DROP FUNCTION create_test;
SELECT drop_graph('cypher_create', true);
-NOTICE: drop cascades to 19 other objects
+NOTICE: drop cascades to 20 other objects
DETAIL: drop cascades to table cypher_create._ag_label_vertex
drop cascades to table cypher_create._ag_label_edge
drop cascades to table cypher_create.v
@@ -819,6 +932,7 @@
drop cascades to table cypher_create."CREATE"
drop cascades to table cypher_create."create"
drop cascades to table cypher_create."CrEaTe"
+drop cascades to table cypher_create.edge
NOTICE: graph "cypher_create" has been dropped
drop_graph
------------
diff --git a/regress/expected/cypher_merge.out b/regress/expected/cypher_merge.out
index 7427c8e..39690e7 100644
--- a/regress/expected/cypher_merge.out
+++ b/regress/expected/cypher_merge.out
@@ -817,7 +817,9 @@
--test query
SELECT * FROM cypher('cypher_merge', $$MATCH (n) OPTIONAL MATCH (n)-[:e]->(m) MERGE (m)$$) AS (a agtype);
-ERROR: Existing variable m cannot be NULL in MERGE clause
+ERROR: variable m already exists
+LINE 1: ..., $$MATCH (n) OPTIONAL MATCH (n)-[:e]->(m) MERGE (m)$$) AS (...
+ ^
-- validate only 1 vertex exits
SELECT * FROM cypher('cypher_merge', $$MATCH (n) RETURN n$$) AS (a agtype);
a
@@ -1182,6 +1184,85 @@
(1 row)
+--
+-- the following tests should fail due to invalid variable reuse (issue#1513)
+--
+SELECT * FROM cypher('cypher_merge', $$
+ MERGE (n) MERGE (n) RETURN n
+$$) as (a agtype);
+ERROR: variable n already exists
+LINE 2: MERGE (n) MERGE (n) RETURN n
+ ^
+SELECT * FROM cypher('cypher_merge', $$
+ MATCH (n) MERGE (n) RETURN n
+$$) as (a agtype);
+ERROR: variable n already exists
+LINE 2: MATCH (n) MERGE (n) RETURN n
+ ^
+SELECT * FROM cypher('cypher_merge', $$
+ CREATE (n) MERGE (n) RETURN n
+$$) as (a agtype);
+ERROR: variable n already exists
+LINE 2: CREATE (n) MERGE (n) RETURN n
+ ^
+SELECT * FROM cypher('cypher_merge', $$
+ MATCH (n) WITH n AS r MERGE (r) RETURN r
+$$) as (a agtype);
+ERROR: variable r already exists
+LINE 2: MATCH (n) WITH n AS r MERGE (r) RETURN r
+ ^
+SELECT * FROM cypher('cypher_merge', $$
+ WITH {id: 281474976710657, label: "", properties: {}}::vertex AS n MERGE (n) RETURN n
+$$) as (a agtype);
+ERROR: variable n already exists
+LINE 2: ...7, label: "", properties: {}}::vertex AS n MERGE (n) RETURN ...
+ ^
+SELECT * FROM cypher('cypher_merge', $$
+ MERGE (n)-[e:edge]->(n)-[e1:edge]->(n) MERGE(n) RETURN e
+$$) as (a agtype);
+ERROR: variable n already exists
+LINE 2: MERGE (n)-[e:edge]->(n)-[e1:edge]->(n) MERGE(n) RETURN e
+ ^
+SELECT * FROM cypher('cypher_merge', $$
+ MERGE (n)-[e:edge]->(m) MERGE (e)-[:edge]->() RETURN e
+$$) as (a agtype);
+ERROR: variable 'e' is for an edge
+LINE 2: MERGE (n)-[e:edge]->(m) MERGE (e)-[:edge]->() RETURN e
+ ^
+SELECT * FROM cypher('cypher_merge', $$
+ WITH {id: 1407374883553281, label: "edge", end_id: 281474976710658, start_id: 281474976710657, properties: {}}::edge AS e MERGE ()-[e:edge]->() RETURN e
+$$) as (a agtype);
+ERROR: variable e already exists
+LINE 2: ...474976710657, properties: {}}::edge AS e MERGE ()-[e:edge]->...
+ ^
+SELECT * FROM cypher('cypher_merge', $$
+ MATCH (n) WITH n AS r MERGE (r) RETURN r
+$$) as (a agtype);
+ERROR: variable r already exists
+LINE 2: MATCH (n) WITH n AS r MERGE (r) RETURN r
+ ^
+-- valid variable reuse
+SELECT * FROM cypher('cypher_merge', $$
+ MERGE (n)-[e1:edge]->(m) MERGE (n)-[e2:edge]->()
+$$) as (n agtype);
+ n
+---
+(0 rows)
+
+SELECT * FROM cypher('cypher_merge', $$
+ MERGE (n) WITH n AS r MERGE (r)-[e:edge]->()
+$$) as (a agtype);
+ a
+---
+(0 rows)
+
+SELECT * FROM cypher('cypher_merge', $$
+ CREATE (n), (m) WITH n AS r MERGE (m)
+$$) as (a agtype);
+ a
+---
+(0 rows)
+
--clean up
SELECT * FROM cypher('cypher_merge', $$MATCH (n) DETACH DELETE n $$) AS (a agtype);
a
@@ -1192,7 +1273,7 @@
* Clean up graph
*/
SELECT drop_graph('cypher_merge', true);
-NOTICE: drop cascades to 18 other objects
+NOTICE: drop cascades to 19 other objects
DETAIL: drop cascades to table cypher_merge._ag_label_vertex
drop cascades to table cypher_merge._ag_label_edge
drop cascades to table cypher_merge.e
@@ -1211,6 +1292,7 @@
drop cascades to table cypher_merge."Q"
drop cascades to table cypher_merge."R"
drop cascades to table cypher_merge."E1"
+drop cascades to table cypher_merge.edge
NOTICE: graph "cypher_merge" has been dropped
drop_graph
------------
diff --git a/regress/sql/cypher_create.sql b/regress/sql/cypher_create.sql
index 8c9ac89..0093dc4 100644
--- a/regress/sql/cypher_create.sql
+++ b/regress/sql/cypher_create.sql
@@ -404,6 +404,78 @@
$$) as (a agtype);
--
+-- the following tests should fail due to invalid variable reuse (issue#1513)
+--
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n) CREATE (n) RETURN n
+$$) as (n agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n), (n) RETURN n
+$$) as (n agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ MATCH (n) CREATE (n) RETURN n
+$$) as (n agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n), (n)-[:edge]->(n), (n) RETURN n
+$$) as (n agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(m) CREATE (n), (m) RETURN n
+$$) as (n agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(m) CREATE (), (m) RETURN m
+$$) as (m agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(m) CREATE (), (e) RETURN e
+$$) as (e agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(m) CREATE (n)-[e:edge]->(m) RETURN e
+$$) as (e agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ WITH {id: 281474976710657, label: "", properties: {}}::vertex AS n CREATE (n) RETURN n
+$$) as (n agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(n)-[e:edge]->(n) RETURN e
+$$) as (e agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE ()-[e:edge]->(), (n)-[e:edge]->(n)-[e:edge]->(n) RETURN e
+$$) as (e agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e:edge]->(m) CREATE (e)-[:edge]->() RETURN e
+$$) as (e agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ WITH {id: 1407374883553281, label: "edge", end_id: 281474976710658, start_id: 281474976710657, properties: {}}::edge AS e CREATE ()-[e:edge]->() RETURN e
+$$) as (e agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n) WITH n AS r CREATE (r) RETURN r
+$$) as (r agtype);
+
+-- valid variable reuse
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n)-[e1:edge]->(m) CREATE (n)-[e2:edge]->(m)
+$$) as (n agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n) WITH n AS r CREATE (r)-[e:edge]->() RETURN r
+$$) as (r agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+ CREATE (n), (m) WITH n AS r CREATE (m) RETURN m
+$$) as (m agtype);
+
+--
-- Clean up
--
DROP TABLE simple_path;
diff --git a/regress/sql/cypher_merge.sql b/regress/sql/cypher_merge.sql
index 81d965a..f6aceea 100644
--- a/regress/sql/cypher_merge.sql
+++ b/regress/sql/cypher_merge.sql
@@ -554,6 +554,58 @@
SELECT * FROM cypher('issue_1219', $$ MATCH ()-[e]->() RETURN e $$) as (result agtype);
SELECT drop_graph('issue_1219', true);
+--
+-- the following tests should fail due to invalid variable reuse (issue#1513)
+--
+SELECT * FROM cypher('cypher_merge', $$
+ MERGE (n) MERGE (n) RETURN n
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_merge', $$
+ MATCH (n) MERGE (n) RETURN n
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_merge', $$
+ CREATE (n) MERGE (n) RETURN n
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_merge', $$
+ MATCH (n) WITH n AS r MERGE (r) RETURN r
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_merge', $$
+ WITH {id: 281474976710657, label: "", properties: {}}::vertex AS n MERGE (n) RETURN n
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_merge', $$
+ MERGE (n)-[e:edge]->(n)-[e1:edge]->(n) MERGE(n) RETURN e
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_merge', $$
+ MERGE (n)-[e:edge]->(m) MERGE (e)-[:edge]->() RETURN e
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_merge', $$
+ WITH {id: 1407374883553281, label: "edge", end_id: 281474976710658, start_id: 281474976710657, properties: {}}::edge AS e MERGE ()-[e:edge]->() RETURN e
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_merge', $$
+ MATCH (n) WITH n AS r MERGE (r) RETURN r
+$$) as (a agtype);
+
+-- valid variable reuse
+SELECT * FROM cypher('cypher_merge', $$
+ MERGE (n)-[e1:edge]->(m) MERGE (n)-[e2:edge]->()
+$$) as (n agtype);
+
+SELECT * FROM cypher('cypher_merge', $$
+ MERGE (n) WITH n AS r MERGE (r)-[e:edge]->()
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_merge', $$
+ CREATE (n), (m) WITH n AS r MERGE (m)
+$$) as (a agtype);
+
--clean up
SELECT * FROM cypher('cypher_merge', $$MATCH (n) DETACH DELETE n $$) AS (a agtype);
diff --git a/src/backend/parser/cypher_clause.c b/src/backend/parser/cypher_clause.c
index 212cd26..c164e19 100644
--- a/src/backend/parser/cypher_clause.c
+++ b/src/backend/parser/cypher_clause.c
@@ -181,7 +181,7 @@
cypher_path *cp);
static cypher_target_node *
transform_create_cypher_node(cypher_parsestate *cpstate, List **target_list,
- cypher_node *node);
+ cypher_node *node, bool has_edge);
static cypher_target_node *
transform_create_cypher_new_node(cypher_parsestate *cpstate,
List **target_list, cypher_node *node);
@@ -255,7 +255,7 @@
cypher_relationship *edge);
static cypher_target_node *
transform_merge_cypher_node(cypher_parsestate *cpstate, List **target_list,
- cypher_node *node);
+ cypher_node *node, bool has_edge);
static Node *transform_clause_for_join(cypher_parsestate *cpstate,
cypher_clause *clause,
RangeTblEntry **rte,
@@ -5336,7 +5336,7 @@
cypher_path *path)
{
ParseState *pstate = (ParseState *)cpstate;
- ListCell *lc;
+ ListCell *lc, *prev_node = NULL;
List *transformed_path = NIL;
cypher_create_path *ccp = make_ag_node(cypher_create_path);
bool in_path = path->var_name != NULL;
@@ -5361,9 +5361,11 @@
{
cypher_node *node = lfirst(lc);
transform_entity *entity;
+ ListCell *next_node = lnext(path->path, lc);
cypher_target_node *rel =
- transform_create_cypher_node(cpstate, target_list, node);
+ transform_create_cypher_node(cpstate, target_list, node,
+ (next_node || prev_node));
if (in_path)
{
@@ -5418,6 +5420,7 @@
ereport(ERROR,
(errmsg_internal("unrecognized node in create pattern")));
}
+ prev_node = lc;
}
ccp->target_nodes = transformed_path;
@@ -5489,7 +5492,7 @@
entity = find_variable(cpstate, edge->name);
- if ((entity && entity->type != ENT_EDGE) || variable_exists(cpstate, edge->name))
+ if (entity || variable_exists(cpstate, edge->name))
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -5602,7 +5605,7 @@
// transform nodes, check to see if the variable name already exists.
static cypher_target_node *
transform_create_cypher_node(cypher_parsestate *cpstate, List **target_list,
- cypher_node *node)
+ cypher_node *node, bool has_edge)
{
ParseState *pstate = (ParseState *)cpstate;
@@ -5636,7 +5639,7 @@
*/
if (entity && te)
{
- if (entity->type != ENT_VERTEX)
+ if (entity->type != ENT_VERTEX || !has_edge)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -5649,6 +5652,13 @@
}
else if (te)
{
+ if (!has_edge)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("variable %s already exists", node->name),
+ parser_errposition(pstate, node->location)));
+ }
/*
* Here we are not sure if the te is a vertex, path or something
* else. So we will let it pass and the execution stage will catch
@@ -6682,7 +6692,7 @@
cypher_path *path)
{
ParseState *pstate = (ParseState *)cpstate;
- ListCell *lc;
+ ListCell *lc, *prev_node = NULL;
List *transformed_path = NIL;
cypher_create_path *ccp = make_ag_node(cypher_create_path);
bool in_path = path->var_name != NULL;
@@ -6695,6 +6705,7 @@
{
cypher_node *node = lfirst(lc);
cypher_target_node *rel = NULL;
+ ListCell *next_node = lnext(path->path, lc);
if (path->var_name != NULL && node->name != NULL &&
strcmp(path->var_name, node->name) == 0)
@@ -6716,7 +6727,8 @@
/* if there wasn't a transformed variable, transform the node */
if (rel == NULL)
{
- rel = transform_merge_cypher_node(cpstate, target_list, node);
+ rel = transform_merge_cypher_node(cpstate, target_list, node,
+ (next_node || prev_node));
}
if (in_path)
@@ -6772,6 +6784,7 @@
ereport(ERROR,
(errmsg_internal("unrecognized node in create pattern")));
}
+ prev_node = lc;
}
// store the path's variable name
@@ -6807,7 +6820,7 @@
ENT_EDGE);
// We found a variable with this variable name, throw an error.
- if (entity != NULL)
+ if (entity || variable_exists(cpstate, edge->name))
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -6906,8 +6919,9 @@
*/
static cypher_target_node *
transform_merge_cypher_node(cypher_parsestate *cpstate, List **target_list,
- cypher_node *node)
+ cypher_node *node, bool has_edge)
{
+ ParseState *pstate = (ParseState *)cpstate;
cypher_target_node *rel = make_ag_node(cypher_target_node);
Relation label_relation;
RangeVar *rv;
@@ -6918,19 +6932,35 @@
{
transform_entity *entity = find_transform_entity(cpstate, node->name,
ENT_VERTEX);
+ bool var_exists = variable_exists(cpstate, node->name);
/*
* the vertex was previously declared, we do not need to do any setup
* to create the node.
*/
- if (entity != NULL)
+ if (entity && var_exists)
{
- rel->type = LABEL_KIND_VERTEX;
- rel->tuple_position = InvalidAttrNumber;
- rel->variable_name = node->name;
- rel->resultRelInfo = NULL;
+ if (!has_edge)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("variable %s already exists", node->name),
+ parser_errposition(pstate, node->location)));
+ }
- rel->flags |= CYPHER_TARGET_NODE_MERGE_EXISTS;
- return rel;
+ rel->type = LABEL_KIND_VERTEX;
+ rel->tuple_position = InvalidAttrNumber;
+ rel->variable_name = node->name;
+ rel->resultRelInfo = NULL;
+
+ rel->flags |= CYPHER_TARGET_NODE_MERGE_EXISTS;
+ return rel;
+ }
+ else if (var_exists && !has_edge)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("variable %s already exists", node->name),
+ parser_errposition(pstate, node->location)));
}
rel->flags |= CYPHER_TARGET_NODE_IS_VAR;
}