This is an automated email from the ASF dual-hosted git repository.

jgemignani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/age.git


The following commit(s) were added to refs/heads/master by this push:
     new e22c5ac8 Fix issue #975 Invalid reuse of variables in CREATE clause 
(#977)
e22c5ac8 is described below

commit e22c5ac82c8a25034f8c8bfbdaf4a6d8409693b0
Author: Muhammad Taha Naveed <[email protected]>
AuthorDate: Fri Jun 9 21:22:59 2023 +0500

    Fix issue #975 Invalid reuse of variables in CREATE clause (#977)
    
    - Added checks for invalid use of variables in create clause.
    - Fixed error position of path and node variables.
    - Added regression tests.
---
 regress/expected/cypher_create.out | 144 ++++++++++++++++++++++++++++++++++---
 regress/expected/cypher_match.out  |  30 ++++----
 regress/sql/cypher_create.sql      |  86 ++++++++++++++++++++++
 src/backend/parser/cypher_clause.c |  84 +++++++++++++++++-----
 src/backend/parser/cypher_gram.y   |   3 +-
 5 files changed, 307 insertions(+), 40 deletions(-)

diff --git a/regress/expected/cypher_create.out 
b/regress/expected/cypher_create.out
index 7cac75e3..8bef1d05 100644
--- a/regress/expected/cypher_create.out
+++ b/regress/expected/cypher_create.out
@@ -499,8 +499,8 @@ SELECT * FROM cypher('cypher_create', $$
        CREATE (a {test:1})-[:e_var]->()
 $$) as (a agtype);
 ERROR:  previously declared nodes in a create clause cannot have properties
-LINE 1: SELECT * FROM cypher('cypher_create', $$
-                                               ^
+LINE 4:  CREATE (a {test:1})-[:e_var]->()
+                 ^
 -- Var 'a' cannot change labels
 SELECT * FROM cypher('cypher_create', $$
        MATCH (a:n_var)
@@ -508,16 +508,16 @@ SELECT * FROM cypher('cypher_create', $$
        CREATE (a:new_label)-[:e_var]->()
 $$) as (a agtype);
 ERROR:  previously declared variables cannot have a label
-LINE 1: SELECT * FROM cypher('cypher_create', $$
-                                               ^
+LINE 4:  CREATE (a:new_label)-[:e_var]->()
+                 ^
 SELECT * FROM cypher('cypher_create', $$
        MATCH (a:n_var)-[b]-()
        WHERE a.name = 'Node A'
        CREATE (a)-[b:e_var]->()
 $$) as (a agtype);
 ERROR:  variable b already exists
-LINE 1: SELECT * FROM cypher('cypher_create', $$
-                                               ^
+LINE 4:  CREATE (a)-[b:e_var]->()
+                    ^
 -- A valid single vertex path
 SELECT * FROM cypher('cypher_create', $$
        CREATE p=(a)
@@ -578,7 +578,7 @@ SELECT * FROM cypher('cypher_create', $$
 $$) as (a agtype);
 ERROR:  label existing_elabel is for edges, not vertices
 LINE 2:  CREATE (a:existing_elabel { id: 5})
-                ^
+                 ^
 --
 -- check the cypher CREATE clause inside an INSERT INTO
 --
@@ -641,12 +641,137 @@ SELECT * FROM cypher('cypher_create', $$ MATCH (a:Part) 
RETURN a $$) as (a agtyp
 
 END;
 --
+-- variable reuse
+--
+-- Valid variable reuse
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p)-[a:new]->(p)
+       RETURN p,a,p
+$$) as (n1 agtype, e agtype, n2 agtype);
+                               n1                               |              
                                              e                                 
                            |                               n2                  
             
+----------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------
+ {"id": 281474976710681, "label": "", "properties": {}}::vertex | {"id": 
3940649673949185, "label": "new", "end_id": 281474976710681, "start_id": 
281474976710681, "properties": {}}::edge | {"id": 281474976710681, "label": "", 
"properties": {}}::vertex
+(1 row)
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p:node)-[e:new]->(p)
+       RETURN p,e,p
+$$) as (n1 agtype, e agtype, n2 agtype);
+                                 n1                                  |         
                                                    e                           
                                   |                                 n2         
                         
+---------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------
+ {"id": 4222124650659841, "label": "node", "properties": {}}::vertex | {"id": 
3940649673949186, "label": "new", "end_id": 4222124650659841, "start_id": 
4222124650659841, "properties": {}}::edge | {"id": 4222124650659841, "label": 
"node", "properties": {}}::vertex
+(1 row)
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p)
+       CREATE (p)-[a:new]->(p)
+       RETURN p,a,p
+$$) as (n1 agtype, e agtype, n2 agtype);
+                               n1                               |              
                                              e                                 
                            |                               n2                  
             
+----------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------
+ {"id": 281474976710682, "label": "", "properties": {}}::vertex | {"id": 
3940649673949187, "label": "new", "end_id": 281474976710682, "start_id": 
281474976710682, "properties": {}}::edge | {"id": 281474976710682, "label": "", 
"properties": {}}::vertex
+(1 row)
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p:n1)
+       CREATE (p)-[a:new]->(p)
+       RETURN p,a,p
+$$) as (n1 agtype, e agtype, n2 agtype);
+                                n1                                 |           
                                                  e                             
                                 |                                n2            
                     
+-------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------
+ {"id": 4503599627370497, "label": "n1", "properties": {}}::vertex | {"id": 
3940649673949188, "label": "new", "end_id": 4503599627370497, "start_id": 
4503599627370497, "properties": {}}::edge | {"id": 4503599627370497, "label": 
"n1", "properties": {}}::vertex
+(1 row)
+
+SELECT * FROM cypher('cypher_create', $$
+       MATCH (p:node)
+       CREATE (p)-[a:new]->(p)
+       RETURN p,a,p
+$$) as (n1 agtype, e agtype, n2 agtype);
+                                 n1                                  |         
                                                    e                           
                                   |                                 n2         
                         
+---------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------
+ {"id": 4222124650659841, "label": "node", "properties": {}}::vertex | {"id": 
3940649673949189, "label": "new", "end_id": 4222124650659841, "start_id": 
4222124650659841, "properties": {}}::edge | {"id": 4222124650659841, "label": 
"node", "properties": {}}::vertex
+(1 row)
+
+-- Invalid variable reuse
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p)-[a:new]->(p {n0:'n1'})
+$$) as (a agtype);
+ERROR:  previously declared nodes in a create clause cannot have properties
+LINE 2:  CREATE (p)-[a:new]->(p {n0:'n1'})
+                              ^
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p:n0)-[a:new]->(p:n1)
+$$) as (a agtype);
+ERROR:  previously declared variables cannot have a label
+LINE 2:  CREATE (p:n0)-[a:new]->(p:n1)
+                                 ^
+SELECT * FROM cypher('cypher_create', $$
+       CREATE p=(p)
+$$) as (a agtype);
+ERROR:  variable "p" already exists
+LINE 2:  CREATE p=(p)
+                ^
+SELECT * FROM cypher('cypher_create', $$
+       CREATE p=() CREATE (p)
+$$) as (a agtype);
+ERROR:  agtype must resolve to a vertex
+SELECT * FROM cypher('cypher_create', $$
+       CREATE p=(a)-[p:b]->(a)
+$$) as (a agtype);
+ERROR:  variable "p" already exists
+LINE 2:  CREATE p=(a)-[p:b]->(a)
+                ^
+SELECT * FROM cypher('cypher_create', $$
+       CREATE p=(a)-[:new]->(p)
+$$) as (a agtype);
+ERROR:  variable "p" already exists
+LINE 2:  CREATE p=(a)-[:new]->(p)
+                ^
+SELECT * FROM cypher('cypher_create', $$
+       MATCH (p) CREATE p=()
+$$) as (a agtype);
+ERROR:  variable "p" already exists
+LINE 2:  MATCH (p) CREATE p=()
+                          ^
+SELECT * FROM cypher('cypher_create', $$
+       MATCH (p) CREATE p=(p)
+$$) as (a agtype);
+ERROR:  variable "p" already exists
+LINE 2:  MATCH (p) CREATE p=(p)
+                          ^
+SELECT * FROM cypher('cypher_create', $$
+       MATCH (p) CREATE (a)-[p:b]->(a)
+$$) as (a agtype);
+ERROR:  variable p already exists
+LINE 2:  MATCH (p) CREATE (a)-[p:b]->(a)
+                              ^
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (a)-[e:new]->(p)-[e]->(a)
+$$) as (a agtype);
+ERROR:  relationships must be specify a label in CREATE.
+LINE 2:  CREATE (a)-[e:new]->(p)-[e]->(a)
+                                 ^
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (a)-[e:new]->(p)
+       CREATE (p)-[e:new]->(a)
+$$) as (a agtype);
+ERROR:  variable e already exists
+LINE 3:  CREATE (p)-[e:new]->(a)
+                    ^
+SELECT * FROM cypher('cypher_create', $$
+       MATCH (a)-[e:new]->(p)
+       CREATE (p)-[e:new]->(a)
+$$) as (a agtype);
+ERROR:  variable e already exists
+LINE 3:  CREATE (p)-[e:new]->(a)
+                    ^
+--
 -- Clean up
 --
 DROP TABLE simple_path;
 DROP FUNCTION create_test;
 SELECT drop_graph('cypher_create', true);
-NOTICE:  drop cascades to 13 other objects
+NOTICE:  drop cascades to 16 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
@@ -660,6 +785,9 @@ drop cascades to table cypher_create.existing_vlabel
 drop cascades to table cypher_create.existing_elabel
 drop cascades to table cypher_create.knows
 drop cascades to table cypher_create."Part"
+drop cascades to table cypher_create.new
+drop cascades to table cypher_create.node
+drop cascades to table cypher_create.n1
 NOTICE:  graph "cypher_create" has been dropped
  drop_graph 
 ------------
diff --git a/regress/expected/cypher_match.out 
b/regress/expected/cypher_match.out
index da5e4512..50eebeb4 100644
--- a/regress/expected/cypher_match.out
+++ b/regress/expected/cypher_match.out
@@ -508,43 +508,43 @@ SELECT * FROM cypher('cypher_match', $$
 $$) AS (a agtype);
 ERROR:  multiple labels for variable 'a' are not supported
 LINE 2:  MATCH (a)-[]-()-[]-(a:v1) RETURN a
-                            ^
+                             ^
 SELECT * FROM cypher('cypher_match', $$
        MATCH (a)-[]-(a:v2)-[]-(a) RETURN a
 $$) AS (a agtype);
 ERROR:  multiple labels for variable 'a' are not supported
 LINE 2:  MATCH (a)-[]-(a:v2)-[]-(a) RETURN a
-                      ^
+                       ^
 SELECT * FROM cypher('cypher_match', $$
        MATCH (a)-[]-(a:v1) RETURN a
 $$) AS (a agtype);
 ERROR:  multiple labels for variable 'a' are not supported
 LINE 2:  MATCH (a)-[]-(a:v1) RETURN a
-                      ^
+                       ^
 SELECT * FROM cypher('cypher_match', $$
        MATCH (a)-[]-(a)-[]-(a:v1) RETURN a
 $$) AS (a agtype);
 ERROR:  multiple labels for variable 'a' are not supported
 LINE 2:  MATCH (a)-[]-(a)-[]-(a:v1) RETURN a
-                             ^
+                              ^
 SELECT * FROM cypher('cypher_match', $$
        MATCH (a)-[]-(a)-[]-(a:invalid_label) RETURN a
 $$) AS (a agtype);
 ERROR:  multiple labels for variable 'a' are not supported
 LINE 2:  MATCH (a)-[]-(a)-[]-(a:invalid_label) RETURN a
-                             ^
+                              ^
 SELECT * FROM cypher('cypher_match', $$
        MATCH (a) MATCH (a:v1) RETURN a
 $$) AS (a agtype);
 ERROR:  multiple labels for variable 'a' are not supported
 LINE 2:  MATCH (a) MATCH (a:v1) RETURN a
-                         ^
+                          ^
 SELECT * FROM cypher('cypher_match', $$
        MATCH (a) MATCH (a:invalid_label) RETURN a
 $$) AS (a agtype);
 ERROR:  multiple labels for variable 'a' are not supported
 LINE 2:  MATCH (a) MATCH (a:invalid_label) RETURN a
-                         ^
+                          ^
 SELECT * FROM cypher('cypher_match', $$
        MATCH (a:v1)-[]-()-[a]-() RETURN a
 $$) AS (a agtype);
@@ -718,8 +718,8 @@ SELECT * FROM cypher('cypher_match', $$
          MATCH (r1:invalid)-[]->(r1)-[]->(r1)-[]->(r1:invalids) return r1
 $$) AS (r1 agtype);
 ERROR:  multiple labels for variable 'r1' are not supported
-LINE 2:          MATCH (r1:invalid)-[]->(r1)-[]->(r1)-[]->(r1:invali...
-                                                          ^
+LINE 2: ...        MATCH (r1:invalid)-[]->(r1)-[]->(r1)-[]->(r1:invalid...
+                                                             ^
 SELECT * FROM cypher('cypher_match', $$
          MATCH (r1:invalid)-[]->(r1)-[]->(r1)-[]->(r1)-[r1]->() return r1
 $$) AS (r1 agtype);
@@ -732,25 +732,25 @@ SELECT * FROM cypher('cypher_match', $$
 $$) AS (r1 agtype);
 ERROR:  multiple labels for variable 'r1' are not supported
 LINE 2:          MATCH (r1:e1), (r1:e2) return r1
-                                ^
+                                 ^
 SELECT * FROM cypher('cypher_match', $$
          MATCH (r1:invalid), (r1:e2) return r1
 $$) AS (r1 agtype);
 ERROR:  multiple labels for variable 'r1' are not supported
 LINE 2:          MATCH (r1:invalid), (r1:e2) return r1
-                                     ^
+                                      ^
 SELECT * FROM cypher('cypher_match', $$
          MATCH (r1:e1), (r1:invalid) return r1
 $$) AS (r1 agtype);
 ERROR:  multiple labels for variable 'r1' are not supported
 LINE 2:          MATCH (r1:e1), (r1:invalid) return r1
-                                ^
+                                 ^
 SELECT * FROM cypher('cypher_match', $$
          MATCH (r1:e1), (r1), (r1:invalid) return r1
 $$) AS (r1 agtype);
 ERROR:  multiple labels for variable 'r1' are not supported
 LINE 2:          MATCH (r1:e1), (r1), (r1:invalid) return r1
-                                      ^
+                                       ^
 SELECT * FROM cypher('cypher_match', $$
         MATCH (r0)-[r0]->() MATCH ()-[]->() RETURN r0
 $$) AS (r0 agtype);
@@ -768,7 +768,7 @@ SELECT * FROM cypher('cypher_match', $$
 $$) AS (r0 agtype);
 ERROR:  variable 'r0' is for a edge
 LINE 2:         MATCH ()-[r0]->() MATCH ()-[]->(r0) RETURN r0
-                                               ^
+                                                ^
 SELECT * FROM cypher('cypher_match', $$
         MATCH ()-[r0:e1]->() MATCH ()-[r0:e2]->() RETURN r0
 $$) AS (r0 agtype);
@@ -1083,7 +1083,7 @@ SELECT * FROM cypher('cypher_match',
 AS (u agtype, e agtype, v agtype);
 ERROR:  variable `x` does not exist
 LINE 2:  $$MATCH (u)-[e]->(v) WHERE EXISTS((u)-[e]->(x)) RETURN u, e...
-                                                    ^
+                                                     ^
 --
 -- Tests for EXISTS(property)
 --
diff --git a/regress/sql/cypher_create.sql b/regress/sql/cypher_create.sql
index 5934dcb1..dd950698 100644
--- a/regress/sql/cypher_create.sql
+++ b/regress/sql/cypher_create.sql
@@ -299,6 +299,92 @@ SELECT * FROM cypher('cypher_create', $$ CREATE (a:Part 
{part_num: '673'}) $$) a
 SELECT * FROM cypher('cypher_create', $$ MATCH (a:Part) RETURN a $$) as (a 
agtype);
 END;
 
+--
+-- variable reuse
+--
+
+-- Valid variable reuse
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p)-[a:new]->(p)
+       RETURN p,a,p
+$$) as (n1 agtype, e agtype, n2 agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p:node)-[e:new]->(p)
+       RETURN p,e,p
+$$) as (n1 agtype, e agtype, n2 agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p)
+       CREATE (p)-[a:new]->(p)
+       RETURN p,a,p
+$$) as (n1 agtype, e agtype, n2 agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p:n1)
+       CREATE (p)-[a:new]->(p)
+       RETURN p,a,p
+$$) as (n1 agtype, e agtype, n2 agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       MATCH (p:node)
+       CREATE (p)-[a:new]->(p)
+       RETURN p,a,p
+$$) as (n1 agtype, e agtype, n2 agtype);
+
+-- Invalid variable reuse
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p)-[a:new]->(p {n0:'n1'})
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (p:n0)-[a:new]->(p:n1)
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE p=(p)
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE p=() CREATE (p)
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE p=(a)-[p:b]->(a)
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE p=(a)-[:new]->(p)
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       MATCH (p) CREATE p=()
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       MATCH (p) CREATE p=(p)
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       MATCH (p) CREATE (a)-[p:b]->(a)
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (a)-[e:new]->(p)-[e]->(a)
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       CREATE (a)-[e:new]->(p)
+       CREATE (p)-[e:new]->(a)
+$$) as (a agtype);
+
+SELECT * FROM cypher('cypher_create', $$
+       MATCH (a)-[e:new]->(p)
+       CREATE (p)-[e:new]->(a)
+$$) as (a agtype);
+
 --
 -- Clean up
 --
diff --git a/src/backend/parser/cypher_clause.c 
b/src/backend/parser/cypher_clause.c
index 493206c3..910104bc 100644
--- a/src/backend/parser/cypher_clause.c
+++ b/src/backend/parser/cypher_clause.c
@@ -4893,6 +4893,18 @@ transform_cypher_create_path(cypher_parsestate *cpstate, 
List **target_list,
 
     ccp->path_attr_num = InvalidAttrNumber;
 
+    if (in_path)
+    {
+        if (findTarget(*target_list, path->var_name) != NULL)
+        {
+            ereport(ERROR,
+                   (errcode(ERRCODE_DUPLICATE_ALIAS),
+                    errmsg("variable \"%s\" already exists",
+                            path->var_name),
+                    parser_errposition(pstate, path->location)));
+        }
+    }
+
     foreach (lc, path->path)
     {
         if (is_ag_node(lfirst(lc), cypher_node))
@@ -4904,7 +4916,18 @@ transform_cypher_create_path(cypher_parsestate *cpstate, 
List **target_list,
                 transform_create_cypher_node(cpstate, target_list, node);
 
             if (in_path)
+            {
+                if (node->name && strcmp(node->name, path->var_name) == 0)
+                {
+                    ereport(ERROR,
+                           (errcode(ERRCODE_DUPLICATE_ALIAS),
+                            errmsg("variable \"%s\" already exists",
+                                    path->var_name),
+                            parser_errposition(pstate, path->location)));
+                }
                 rel->flags |= CYPHER_TARGET_NODE_IN_PATH_VAR;
+            }
+                
 
             transformed_path = lappend(transformed_path, rel);
 
@@ -4922,7 +4945,17 @@ transform_cypher_create_path(cypher_parsestate *cpstate, 
List **target_list,
                 transform_create_cypher_edge(cpstate, target_list, edge);
 
             if (in_path)
+            {
+                if (edge->name && strcmp(edge->name, path->var_name) == 0)
+                {
+                    ereport(ERROR,
+                           (errcode(ERRCODE_DUPLICATE_ALIAS),
+                            errmsg("variable \"%s\" already exists",
+                                    path->var_name),
+                            parser_errposition(pstate, path->location)));
+                }
                 rel->flags |= CYPHER_TARGET_NODE_IN_PATH_VAR;
+            }
 
             transformed_path = lappend(transformed_path, rel);
 
@@ -4934,7 +4967,7 @@ transform_cypher_create_path(cypher_parsestate *cpstate, 
List **target_list,
         else
         {
             ereport(ERROR,
-                    (errmsg_internal("unrecognized node in create pattern")));
+                   (errmsg_internal("unrecognized node in create pattern")));
         }
     }
 
@@ -4982,10 +5015,7 @@ transform_create_cypher_edge(cypher_parsestate *cpstate, 
List **target_list,
 
     if (edge->label)
     {
-        label_cache_data *lcd =
-            search_label_name_graph_cache(edge->label, cpstate->graph_oid);
-
-        if (lcd && lcd->kind != LABEL_KIND_EDGE)
+        if (get_label_kind(edge->label, cpstate->graph_oid) == 
LABEL_KIND_VERTEX)
         {
             ereport(ERROR,
                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -5005,11 +5035,16 @@ transform_create_cypher_edge(cypher_parsestate 
*cpstate, List **target_list,
          * Variables can be declared in a CREATE clause, but not used if
          * it already exists.
          */
-        if (variable_exists(cpstate, edge->name))
+        transform_entity *entity;
+
+        entity = find_variable(cpstate, edge->name);
+
+        if ((entity && entity->type != ENT_EDGE) || variable_exists(cpstate, 
edge->name))
         {
-            ereport(ERROR,
-                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                     errmsg("variable %s already exists", edge->name)));
+                ereport(ERROR,
+                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                         errmsg("variable %s already exists", edge->name),
+                         parser_errposition(pstate, edge->location)));
         }
 
         rel->variable_name = edge->name;
@@ -5122,10 +5157,7 @@ transform_create_cypher_node(cypher_parsestate *cpstate, 
List **target_list,
 
     if (node->label)
     {
-        label_cache_data *lcd =
-            search_label_name_graph_cache(node->label, cpstate->graph_oid);
-
-        if (lcd && lcd->kind != LABEL_KIND_VERTEX)
+        if (get_label_kind(node->label, cpstate->graph_oid) == LABEL_KIND_EDGE)
         {
             ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                             errmsg("label %s is for edges, not vertices",
@@ -5142,9 +5174,16 @@ transform_create_cypher_node(cypher_parsestate *cpstate, 
List **target_list,
     {
         transform_entity *entity;
 
+        TargetEntry *te = findTarget(*target_list, node->name);
         entity = find_variable(cpstate, node->name);
 
-        if (entity)
+        /*
+         * If we find an entity as well as a target Entry with same name,
+         * that means that the variable is either vertex, edge or vle.
+         * but if we find a target entry but not an entity that means
+         * that the variable can be other than vertex, edge or vle e.g path.
+         */
+        if (entity && te)
         {
             if (entity->type != ENT_VERTEX)
             {
@@ -5157,6 +5196,16 @@ transform_create_cypher_node(cypher_parsestate *cpstate, 
List **target_list,
             return transform_create_cypher_existing_node(cpstate, target_list,
                                                          
entity->declared_in_current_clause, node);
         }
+        else if (te)
+        {
+            /*
+             * 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
+             * the error if variable was not vertex.
+             */
+            return transform_create_cypher_existing_node(cpstate, target_list,
+                                                         te, node);
+        }
     }
 
     // otherwise transform the target node as a new node
@@ -5197,6 +5246,7 @@ static cypher_target_node 
*transform_create_cypher_existing_node(
     cypher_node *node)
 {
     cypher_target_node *rel = make_ag_node(cypher_target_node);
+    ParseState *pstate = (ParseState *)cpstate;
 
     rel->type = LABEL_KIND_VERTEX;
     rel->flags = CYPHER_TARGET_NODE_FLAG_NONE;
@@ -5208,13 +5258,15 @@ static cypher_target_node 
*transform_create_cypher_existing_node(
     {
         ereport(ERROR,
                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                 errmsg("previously declared nodes in a create clause cannot 
have properties")));
+                 errmsg("previously declared nodes in a create clause cannot 
have properties"),
+                 parser_errposition(pstate, node->location)));
     }
     if (node->label)
     {
         ereport(ERROR,
                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                 errmsg("previously declared variables cannot have a label")));
+                 errmsg("previously declared variables cannot have a label"),
+                 parser_errposition(pstate, node->location)));
     }
     /*
      * When the variable is declared in the same clause this vertex is a part 
of
diff --git a/src/backend/parser/cypher_gram.y b/src/backend/parser/cypher_gram.y
index 4fb599a7..2fd057d6 100644
--- a/src/backend/parser/cypher_gram.y
+++ b/src/backend/parser/cypher_gram.y
@@ -1115,6 +1115,7 @@ path:
 
             p = (cypher_path *)$3;
             p->var_name = $1;
+            p->location = @1;
 
             $$ = (Node *)p;
         }
@@ -1182,7 +1183,7 @@ path_node:
             n->label = $3;
             n->parsed_label = $3;
             n->props = $4;
-            n->location = @1;
+            n->location = @2;
 
             $$ = (Node *)n;
         }

Reply via email to