DEV Community

Mohamed Mokhtar
Mohamed Mokhtar

Posted on

Under the hood of create_graph at Apache AGE

Introduction

The following article I am going to let you know more about what is going inside the Apache AGE back-end from the perspective of PostgreSQL and give you a brief introduction about the graph creation on PostgreSQL using Apache AGE.
under-the-hood

Let's

Prerequisites

  • PostgreSQL
  • Apache AGE

if you don't have them visit my blogs and you will learn how to install them

The beginning

Mostly everything in Apache AGE is a function that is written in C and being loaded to PostgreSQL as any PL/SQL function

So, create_graph is a function and it is defined on age--1.3.0.sql for example (varies based on version being used)

That how does it look like

CREATE FUNCTION ag_catalog.create_graph(graph_name name)
RETURNS void
LANGUAGE c
AS 'MODULE_PATHNAME';
Enter fullscreen mode Exit fullscreen mode

How it is implemented?


PG_FUNCTION_INFO_V1(create_graph);

/* function that is evoked for creating a graph */
Datum create_graph(PG_FUNCTION_ARGS)
{
    char *graph;
    Name graph_name;
    char *graph_name_str;
    Oid nsp_id;

    //if no argument is passed with the function, graph name cannot be null
    if (PG_ARGISNULL(0))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("graph name can not be NULL")));
    }

    //gets graph name as function argument
    graph_name = PG_GETARG_NAME(0);  

    graph_name_str = NameStr(*graph_name);

    //checking if the name of the graph falls under the pre-decided graph naming conventions(regex)
    if (!is_valid_graph_name(graph_name_str))
    {
        ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                        errmsg("graph name is invalid")));
    }

    //graph name must be unique, a graph with the same name should not exist
    if (graph_exists(graph_name_str))
    {
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_SCHEMA),
                 errmsg("graph \"%s\" already exists", graph_name_str)));
    }

    nsp_id = create_schema_for_graph(graph_name);

    //inserts the graph info into the relation which has all the other existing graphs info
    insert_graph(graph_name, nsp_id);  

    //Increment the Command counter before create the generic labels.
    CommandCounterIncrement();

    //Create the default label tables
    graph = graph_name->data;
    create_label(graph, AG_DEFAULT_LABEL_VERTEX, LABEL_TYPE_VERTEX, NIL);
    create_label(graph, AG_DEFAULT_LABEL_EDGE, LABEL_TYPE_EDGE, NIL);

    ereport(NOTICE,
            (errmsg("graph \"%s\" has been created", NameStr(*graph_name))));

    //according to postgres specification of c-language functions if function returns void this is the syntax
    PG_RETURN_VOID(); 
}
Enter fullscreen mode Exit fullscreen mode

What are the most interesting parts

  • Creating a namespace (schema) for that graph
    /*
     * This is the same with running the following SQL statement.
     *
     * CREATE SCHEMA `graph_name`
     *   CREATE SEQUENCE `LABEL_ID_SEQ_NAME`
     *     AS integer
     *     MAXVALUE `LABEL_ID_MAX`
     *     CYCLE
     * The sequence will be used to assign a unique id to a label in the graph.
     *
     * schemaname doesn't have to be graph_name but the same name is used so
     * that users can find the backed schema for a graph only by its name.
     *
     * ProcessUtilityContext of this command is PROCESS_UTILITY_SUBCOMMAND
     * so the event trigger will not be fired.
     */

    nsp_id = create_schema_for_graph(graph_name);
Enter fullscreen mode Exit fullscreen mode
  • Creates new entry on the ag_catalog at the graphs table
// INSERT INTO ag_catalog.ag_graph VALUES (graph_name, nsp_id)
// = 
    insert_graph(graph_name, nsp_id);  
Enter fullscreen mode Exit fullscreen mode
  • The following statements creates a table for holding the labels of (vertex and edges)
    graph = graph_name->data;
    create_label(graph, AG_DEFAULT_LABEL_VERTEX, LABEL_TYPE_VERTEX, NIL);
    create_label(graph, AG_DEFAULT_LABEL_EDGE, LABEL_TYPE_EDGE, NIL);
Enter fullscreen mode Exit fullscreen mode

Conclusion

  • Create namespace (schema)
  • Insert into ag_catalog graphs table a new entry for it
  • Create Vertex labels table inside the create namespace
  • Create Edge labels table inside the create namespace

See you in next AGE statement under the hood

Resources and References

Top comments (0)