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,
