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

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

commit 9fefd3659ed1d29445d009d094013e9179299400
Author: Muhammad Taha Naveed <[email protected]>
AuthorDate: Tue Mar 7 03:26:44 2023 +0500

    Fix issue #733 - create_complete_graph() terminates the server (#734)
    
    - A vertex and  an edge cannot have the same label within the same
      graph, so added a check for that.
    
    - insert_simple_vertex() and insert_simple_edge() functions were not
      checking for the kind of label. Since a vertex cannot be
      inserted into a label relation of edge and vice versa, this was
      causing the server termination. Added a check for that.
    
    - Added regression tests.
    
    Conflicts:
            src/backend/utils/graph_generation.c
            src/include/catalog/ag_label.h
    
    Co-authored-by: John Gemignani <[email protected]>
---
 regress/expected/graph_generation.out |  8 ++++++++
 regress/sql/graph_generation.sql      |  8 ++++++++
 src/backend/catalog/ag_label.c        | 15 +++++++++++++++
 src/backend/utils/graph_generation.c  | 15 +++++++++++++--
 src/backend/utils/load/age_load.c     | 15 ++++++++++++++-
 src/include/catalog/ag_label.h        |  2 ++
 6 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/regress/expected/graph_generation.out 
b/regress/expected/graph_generation.out
index b9ed65b1..235052a0 100644
--- a/regress/expected/graph_generation.out
+++ b/regress/expected/graph_generation.out
@@ -80,12 +80,17 @@ NOTICE:  ELabel "edges" has been created
  
 (1 row)
 
+-- SHOULD FAIL
 SELECT * FROM create_complete_graph('gp3',5, NULL);
 ERROR:  edge label can not be NULL
 SELECT * FROM create_complete_graph('gp4',NULL,NULL);
 ERROR:  number of nodes can not be NULL
 SELECT * FROM create_complete_graph(NULL,NULL,NULL);
 ERROR:  graph name can not be NULL
+-- Should error out because same labels are used for both vertices and edges
+SELECT * FROM create_complete_graph('gp5',5,'label','label');
+ERROR:  vertex and edge label can not be same
+-- DROPPING GRAPHS
 SELECT drop_graph('gp1', true);
 NOTICE:  drop cascades to 4 other objects
 DETAIL:  drop cascades to table gp1._ag_label_vertex
@@ -195,6 +200,9 @@ SELECT * FROM 
age_create_barbell_graph('gp4',NULL,0,'vertices',NULL,'edges',NULL
 ERROR:  Graph size cannot be NULL or lower than 3
 SELECT * FROM age_create_barbell_graph('gp5',5,0,'vertices',NULL,NULL,NULL);
 ERROR:  edge label can not be NULL
+-- Should error out because same labels are used for both vertices and edges
+SELECT * FROM age_create_barbell_graph('gp6',5,10,'label',NULL,'label',NULL);
+ERROR:  vertex and edge label can not be same
 -- DROPPING GRAPHS
 SELECT drop_graph('gp1', true);
 NOTICE:  drop cascades to 4 other objects
diff --git a/regress/sql/graph_generation.sql b/regress/sql/graph_generation.sql
index 32fa56dd..e9ee8ea8 100644
--- a/regress/sql/graph_generation.sql
+++ b/regress/sql/graph_generation.sql
@@ -36,12 +36,17 @@ SELECT COUNT(*) FROM gp1."vertices";
 
 SELECT * FROM create_complete_graph('gp2',5,'edges');
 
+-- SHOULD FAIL
 SELECT * FROM create_complete_graph('gp3',5, NULL);
 
 SELECT * FROM create_complete_graph('gp4',NULL,NULL);
 
 SELECT * FROM create_complete_graph(NULL,NULL,NULL);
 
+-- Should error out because same labels are used for both vertices and edges
+SELECT * FROM create_complete_graph('gp5',5,'label','label');
+
+-- DROPPING GRAPHS
 SELECT drop_graph('gp1', true);
 SELECT drop_graph('gp2', true);
 
@@ -68,6 +73,9 @@ SELECT * FROM 
age_create_barbell_graph('gp3',5,NULL,'vertices',NULL,'edges',NULL
 SELECT * FROM 
age_create_barbell_graph('gp4',NULL,0,'vertices',NULL,'edges',NULL);
 SELECT * FROM age_create_barbell_graph('gp5',5,0,'vertices',NULL,NULL,NULL);
 
+-- Should error out because same labels are used for both vertices and edges
+SELECT * FROM age_create_barbell_graph('gp6',5,10,'label',NULL,'label',NULL);
+
 -- DROPPING GRAPHS
 SELECT drop_graph('gp1', true);
 SELECT drop_graph('gp2', true);
diff --git a/src/backend/catalog/ag_label.c b/src/backend/catalog/ag_label.c
index 768d63d2..9cd89235 100644
--- a/src/backend/catalog/ag_label.c
+++ b/src/backend/catalog/ag_label.c
@@ -159,6 +159,21 @@ char *get_label_relation_name(const char *label_name, Oid 
graph_oid)
     return get_rel_name(get_label_relation(label_name, graph_oid));
 }
 
+char get_label_kind(const char *label_name, Oid label_graph)
+{
+    label_cache_data *cache_data;
+
+    cache_data = search_label_name_graph_cache(label_name, label_graph);
+    if (cache_data)
+    {
+        return cache_data->kind;
+    }
+    else
+    {
+        return INVALID_LABEL_ID;
+    }
+}
+
 PG_FUNCTION_INFO_V1(_label_name);
 
 /*
diff --git a/src/backend/utils/graph_generation.c 
b/src/backend/utils/graph_generation.c
index e4672ea2..ca12e9c5 100644
--- a/src/backend/utils/graph_generation.c
+++ b/src/backend/utils/graph_generation.c
@@ -141,6 +141,19 @@ Datum create_complete_graph(PG_FUNCTION_ARGS)
     vtx_name_str = AG_DEFAULT_LABEL_VERTEX;
     edge_name_str = NameStr(*edge_label_name);
 
+    if (!PG_ARGISNULL(3))
+    {
+        vtx_label_name = PG_GETARG_NAME(3);
+        vtx_name_str = NameStr(*vtx_label_name);
+
+        // Check if vertex and edge label are same
+        if (strcmp(vtx_name_str, edge_name_str) == 0)
+        {
+            ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                    errmsg("vertex and edge label can not be same")));
+        }
+    }
+
     if (!graph_exists(graph_name_str))
     {
         DirectFunctionCall1(create_graph, CStringGetDatum(graph_name));
@@ -150,8 +163,6 @@ Datum create_complete_graph(PG_FUNCTION_ARGS)
 
     if (!PG_ARGISNULL(3))
     {
-        vtx_label_name = PG_GETARG_NAME(3);
-        vtx_name_str = NameStr(*vtx_label_name);
         // Check if label with the input name already exists
         if (!label_exists(vtx_name_str, graph_id))
         {
diff --git a/src/backend/utils/load/age_load.c 
b/src/backend/utils/load/age_load.c
index ff64e1fa..bc64db32 100644
--- a/src/backend/utils/load/age_load.c
+++ b/src/backend/utils/load/age_load.c
@@ -127,6 +127,12 @@ void insert_edge_simple(Oid graph_oid, char *label_name, 
graphid edge_id,
     Relation label_relation;
     HeapTuple tuple;
 
+    // Check if label provided exists as vertex label, then throw error
+    if (get_label_kind(label_name, graph_oid) == LABEL_KIND_VERTEX)
+    {
+        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                        errmsg("label %s already exists as vertex label", 
label_name)));
+    }
 
     values[0] = GRAPHID_GET_DATUM(edge_id);
     values[1] = GRAPHID_GET_DATUM(start_id);
@@ -153,6 +159,13 @@ void insert_vertex_simple(Oid graph_oid, char *label_name, 
graphid vertex_id,
     Relation label_relation;
     HeapTuple tuple;
 
+    // Check if label provided exists as edge label, then throw error
+    if (get_label_kind(label_name, graph_oid) == LABEL_KIND_EDGE)
+    {
+        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                        errmsg("label %s already exists as edge label", 
label_name)));
+    }
+
     values[0] = GRAPHID_GET_DATUM(vertex_id);
     values[1] = AGTYPE_P_GET_DATUM((vertex_properties));
 
@@ -262,4 +275,4 @@ Datum load_edges_from_file(PG_FUNCTION_ARGS)
                                label_name_str, label_id);
     PG_RETURN_VOID();
 
-}
\ No newline at end of file
+}
diff --git a/src/include/catalog/ag_label.h b/src/include/catalog/ag_label.h
index 90a4ef84..e1e90f3f 100644
--- a/src/include/catalog/ag_label.h
+++ b/src/include/catalog/ag_label.h
@@ -76,6 +76,8 @@ void delete_label(Oid relation);
 int32 get_label_id(const char *label_name, Oid graph_oid);
 Oid get_label_relation(const char *label_name, Oid graph_oid);
 char *get_label_relation_name(const char *label_name, Oid graph_oid);
+Oid get_label_oid(const char *label_name, Oid label_graph);
+char get_label_kind(const char *label_name, Oid label_graph);
 
 bool label_id_exists(Oid graph_oid, int32 label_id);
 RangeVar *get_label_range_var(char *graph_name, Oid graph_oid,

Reply via email to