You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@age.apache.org by jg...@apache.org on 2021/09/28 19:25:54 UTC

[incubator-age] branch master updated: Labels creation functions (#115)

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/incubator-age.git


The following commit(s) were added to refs/heads/master by this push:
     new 277707a  Labels creation functions (#115)
277707a is described below

commit 277707ad16dd31c83211009042898fb32aadd4c8
Author: Shoaib <mu...@gmail.com>
AuthorDate: Tue Sep 28 21:25:50 2021 +0200

    Labels creation functions (#115)
    
    Two more functions create_vlabel and create_elabel have been added.
    
    User can call these functions to create blank labels.
    
    Usage as following:
    
    SELECT create_vlabel('cypher', 'vlabel_1');
    SELECT create_elabel('cypher', 'elabel_1');
    
    modified makefile to support UTF.
    
    Added regression tests and comments
    
    Make badges on the README page dynamic (#116)
    
    This way, the release badge doesn't need to be updated each release
    
    Co-authored-by: Pieterjan De Potter <pi...@ugent.be>
---
 Makefile                              |   6 +-
 age--0.6.0.sql                        |  10 +++
 regress/expected/catalog.out          |  91 ++++++++++++++++++++++
 regress/sql/catalog.sql               |  41 ++++++++++
 src/backend/commands/label_commands.c | 140 ++++++++++++++++++++++++++++++++++
 5 files changed, 287 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 2bbe1c7..1f97aab 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,8 @@
 
 MODULE_big = age
 
+
+
 OBJS = src/backend/age.o \
        src/backend/catalog/ag_catalog.o \
        src/backend/catalog/ag_graph.o \
@@ -77,8 +79,10 @@ REGRESS = scan \
           cypher_vle \
           drop
 
+srcdir=`pwd`
+
 ag_regress_dir = $(srcdir)/regress
-REGRESS_OPTS = --load-extension=age --inputdir=$(ag_regress_dir) --outputdir=$(ag_regress_dir) --temp-instance=$(ag_regress_dir)/instance --port=61958
+REGRESS_OPTS = --load-extension=age --inputdir=$(ag_regress_dir) --outputdir=$(ag_regress_dir) --temp-instance=$(ag_regress_dir)/instance --port=61958 --encoding=UTF-8
 
 ag_regress_out = instance/ log/ results/ regression.*
 EXTRA_CLEAN = $(addprefix $(ag_regress_dir)/, $(ag_regress_out)) src/backend/parser/cypher_gram.c src/include/parser/cypher_gram_def.h
diff --git a/age--0.6.0.sql b/age--0.6.0.sql
index b5d363d..a6a9db3 100644
--- a/age--0.6.0.sql
+++ b/age--0.6.0.sql
@@ -87,6 +87,16 @@ RETURNS void
 LANGUAGE c
 AS 'MODULE_PATHNAME';
 
+CREATE FUNCTION ag_catalog.create_vlabel(graph_name name, label_name name)
+    RETURNS void
+    LANGUAGE c
+AS 'MODULE_PATHNAME';
+
+CREATE FUNCTION ag_catalog.create_elabel(graph_name name, label_name name)
+    RETURNS void
+    LANGUAGE c
+AS 'MODULE_PATHNAME';
+
 CREATE FUNCTION ag_catalog.alter_graph(graph_name name, operation cstring, new_value name)
 RETURNS void
 LANGUAGE c
diff --git a/regress/expected/catalog.out b/regress/expected/catalog.out
index 7ae3725..d1b9db6 100644
--- a/regress/expected/catalog.out
+++ b/regress/expected/catalog.out
@@ -311,3 +311,94 @@ NOTICE:  graph "g" has been dropped
  
 (1 row)
 
+-- create labels
+SELECT create_graph('g');
+NOTICE:  graph "g" has been created
+ create_graph 
+--------------
+ 
+(1 row)
+
+SELECT create_vlabel('g', 'n');
+NOTICE:  VLabel "n" has been created
+ create_vlabel 
+---------------
+ 
+(1 row)
+
+SELECT create_elabel('g', 'r');
+NOTICE:  ELabel "r" has been created
+ create_elabel 
+---------------
+ 
+(1 row)
+
+-- check if labels have been created or not
+SELECT * FROM ag_label;
+       name       | graph | id | kind |      relation      
+------------------+-------+----+------+--------------------
+ _ag_label_vertex | 17621 |  1 | v    | g._ag_label_vertex
+ _ag_label_edge   | 17621 |  2 | e    | g._ag_label_edge
+ n                | 17621 |  3 | v    | g.n
+ r                | 17621 |  4 | e    | g.r
+(4 rows)
+
+-- try to create duplicate labels
+SELECT create_vlabel('g', 'n');
+ERROR:  label "n" already exists
+SELECT create_elabel('g', 'r');
+ERROR:  label "r" already exists
+-- remove the labels that have been created
+SELECT drop_label('g', 'n', false);
+NOTICE:  label "g"."n" has been dropped
+ drop_label 
+------------
+ 
+(1 row)
+
+SELECT drop_label('g', 'r', false);
+NOTICE:  label "g"."r" has been dropped
+ drop_label 
+------------
+ 
+(1 row)
+
+-- check if labels have been deleted or not
+SELECT * FROM ag_label;
+       name       | graph | id | kind |      relation      
+------------------+-------+----+------+--------------------
+ _ag_label_vertex | 17621 |  1 | v    | g._ag_label_vertex
+ _ag_label_edge   | 17621 |  2 | e    | g._ag_label_edge
+(2 rows)
+
+-- try to remove labels that is not there
+SELECT drop_label('g', 'n');
+ERROR:  label "n" does not exist
+SELECT drop_label('g', 'r');
+ERROR:  label "r" does not exist
+-- Trying to call the functions with label null
+SELECT create_vlabel('g', NULL);
+ERROR:  label name must not be NULL
+SELECT create_elabel('g', NULL);
+ERROR:  label name must not be NULL
+-- Trying to call the functions with graph null
+SELECT create_vlabel(NULL, 'n');
+ERROR:  graph name must not be NULL
+SELECT create_elabel(NULL, 'r');
+ERROR:  graph name must not be NULL
+-- Trying to call the functions with both null
+SELECT create_vlabel(NULL, NULL);
+ERROR:  graph name must not be NULL
+SELECT create_elabel(NULL, NULL);
+ERROR:  graph name must not be NULL
+-- dropping the graph
+SELECT drop_graph('g', true);
+NOTICE:  drop cascades to 2 other objects
+DETAIL:  drop cascades to table g._ag_label_vertex
+drop cascades to table g._ag_label_edge
+NOTICE:  graph "g" has been dropped
+ drop_graph 
+------------
+ 
+(1 row)
+
diff --git a/regress/sql/catalog.sql b/regress/sql/catalog.sql
index 7c0564c..37648a0 100644
--- a/regress/sql/catalog.sql
+++ b/regress/sql/catalog.sql
@@ -129,3 +129,44 @@ SELECT * FROM cypher('g', $$CREATE (:v2)$$) as r(a agtype);
 SELECT name, id, kind, relation FROM ag_label;
 
 SELECT drop_graph('g', true);
+
+
+-- create labels
+SELECT create_graph('g');
+SELECT create_vlabel('g', 'n');
+SELECT create_elabel('g', 'r');
+
+-- check if labels have been created or not
+SELECT * FROM ag_label;
+
+-- try to create duplicate labels
+SELECT create_vlabel('g', 'n');
+SELECT create_elabel('g', 'r');
+
+-- remove the labels that have been created
+SELECT drop_label('g', 'n', false);
+SELECT drop_label('g', 'r', false);
+
+-- check if labels have been deleted or not
+SELECT * FROM ag_label;
+
+-- try to remove labels that is not there
+SELECT drop_label('g', 'n');
+SELECT drop_label('g', 'r');
+
+-- Trying to call the functions with label null
+SELECT create_vlabel('g', NULL);
+SELECT create_elabel('g', NULL);
+
+-- Trying to call the functions with graph null
+SELECT create_vlabel(NULL, 'n');
+SELECT create_elabel(NULL, 'r');
+
+-- Trying to call the functions with both null
+SELECT create_vlabel(NULL, NULL);
+SELECT create_elabel(NULL, NULL);
+
+-- dropping the graph
+SELECT drop_graph('g', true);
+
+
diff --git a/src/backend/commands/label_commands.c b/src/backend/commands/label_commands.c
index 729e7a5..f291354 100644
--- a/src/backend/commands/label_commands.c
+++ b/src/backend/commands/label_commands.c
@@ -93,6 +93,146 @@ static void range_var_callback_for_remove_relation(const RangeVar *rel,
                                                    Oid odl_rel_oid,
                                                    void *arg);
 
+
+
+PG_FUNCTION_INFO_V1(create_vlabel);
+
+/*
+ * This is a callback function
+ * This function will be called when the user will call SELECT create_vlabel.
+ * The function takes two parameters
+ * 1. Graph name
+ * 2. Label Name
+ * Function will create a vertex label
+ * Function returns an error if graph or label names or not provided
+*/
+
+Datum create_vlabel(PG_FUNCTION_ARGS)
+{
+    char *graph;
+    Name graph_name;
+    char *graph_name_str;
+
+    char *label;
+    Name label_name;
+    char *label_name_str;
+
+    // checking if user has not provided the graph name
+    if (PG_ARGISNULL(0))
+    {
+        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("graph name must not be NULL")));
+    }
+
+    // checking if user has not provided the label name
+    if (PG_ARGISNULL(1))
+    {
+        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("label name must not be NULL")));
+    }
+
+    graph_name = PG_GETARG_NAME(0);
+    label_name = PG_GETARG_NAME(1);
+
+    graph_name_str = NameStr(*graph_name);
+    label_name_str = NameStr(*label_name);
+
+    // Check if graph does not exist
+    if (!graph_exists(graph_name_str))
+    {
+        ereport(ERROR,
+                (errcode(ERRCODE_UNDEFINED_SCHEMA),
+                        errmsg("graph \"%s\" does not exist.", graph_name_str)));
+    }
+
+    // Check if label with the input name already exists
+    if (label_exists(label_name_str, get_graph_oid(graph_name_str)))
+    {
+        ereport(ERROR,
+                (errcode(ERRCODE_UNDEFINED_SCHEMA),
+                        errmsg("label \"%s\" already exists", label_name_str)));
+    }
+
+    //Create the default label tables
+    graph = graph_name->data;
+    label = label_name->data;
+    create_label(graph, label, LABEL_TYPE_VERTEX, NIL);
+
+    ereport(NOTICE,
+            (errmsg("VLabel \"%s\" has been created", NameStr(*label_name))));
+
+    PG_RETURN_VOID();
+}
+
+PG_FUNCTION_INFO_V1(create_elabel);
+
+/*
+ * This is a callback function
+ * This function will be called when the user will call SELECT create_elabel.
+ * The function takes two parameters
+ * 1. Graph name
+ * 2. Label Name
+ * Function will create an edge label
+ * Function returns an error if graph or label names or not provided
+*/
+
+Datum create_elabel(PG_FUNCTION_ARGS)
+{
+    char *graph;
+    Name graph_name;
+    char *graph_name_str;
+
+    char *label;
+    Name label_name;
+    char *label_name_str;
+
+    // checking if user has not provided the graph name
+    if (PG_ARGISNULL(0))
+    {
+        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("graph name must not be NULL")));
+    }
+
+    // checking if user has not provided the label name
+    if (PG_ARGISNULL(1))
+    {
+        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("label name must not be NULL")));
+    }
+
+    graph_name = PG_GETARG_NAME(0);
+    label_name = PG_GETARG_NAME(1);
+
+    graph_name_str = NameStr(*graph_name);
+    label_name_str = NameStr(*label_name);
+
+    // Check if graph does not exist
+    if (!graph_exists(graph_name_str))
+    {
+        ereport(ERROR,
+                (errcode(ERRCODE_UNDEFINED_SCHEMA),
+                        errmsg("graph \"%s\" does not exist.", graph_name_str)));
+    }
+
+    // Check if label with the input name already exists
+    if (label_exists(label_name_str, get_graph_oid(graph_name_str)))
+    {
+        ereport(ERROR,
+                (errcode(ERRCODE_UNDEFINED_SCHEMA),
+                        errmsg("label \"%s\" already exists", label_name_str)));
+    }
+
+    //Create the default label tables
+    graph = graph_name->data;
+    label = label_name->data;
+    create_label(graph, label, LABEL_TYPE_EDGE, NIL);
+
+    ereport(NOTICE,
+            (errmsg("ELabel \"%s\" has been created", NameStr(*label_name))));
+
+    PG_RETURN_VOID();
+}
+
 /*
  * For the new label, create an entry in ag_catalog.ag_label, create a
  * new table and sequence. Returns the oid from the new tuple in