skip to Main Content

I changed a function so that it receives three arguments instead of only two. In the age--1.2.0.sql file, it was set before as:

CREATE FUNCTION ag_catalog.create_vlabel(graph_name name, label_name name)
    RETURNS void
    LANGUAGE c
AS 'MODULE_PATHNAME';

And then I changed to:

CREATE FUNCTION ag_catalog.create_vlabel(graph_name name, label_name name, parent_list name[])
    RETURNS void
    LANGUAGE c
AS 'MODULE_PATHNAME';

After this, I modified the same function in label_commands.c file so that it checks if the third argument is null. If it is not, it iterates through the list, adds the parent labels to a List *parent, and then creates the label inheriting from the parent labels. Here is the block of code where I add this functionality:

    // [...]
    
    // Added these variables:
    
    ArrayType *list_parents;
    Datum *elements_parent_names;
    Name parent_name;
    char *parent_name_str;
    int num_parents;
    
    // [...]
    
    //Create the default label tables
    graph = graph_name->data;
    label = label_name->data;

    rv = get_label_range_var(graph, graph_oid, AG_DEFAULT_LABEL_VERTEX);
    parent = list_make1(rv);

    // checking if user has provided the parent's name list.
    if (!PG_ARGISNULL(2)) {

        // Get the content from the third argument - which is an array.
        list_parents = PG_GETARG_ARRAYTYPE_P(2);
        num_parents = ArrayGetNItems(ARR_NDIM(list_parents), ARR_DIMS(list_parents));
        elements_parent_names = (Datum *) ARR_DATA_PTR(list_parents);
        
        // Check for each parent in the list.
        for (int i = 0; i < num_parents; i++) {
            
            parent_name = DatumGetName(elements_parent_names[i]);
            parent_name_str = NameStr(*parent_name);

            // Check if parent label does not exist
            if (!label_exists(parent_name_str, graph_oid)) {
                ereport(ERROR,
                        (errcode(ERRCODE_UNDEFINED_SCHEMA),
                                errmsg("parent label "%s" does not exist.", parent_name_str)));
            }

            rv = get_label_range_var(graph, graph_oid, parent_name->data);

            lappend(parent, rv);
        }
    }

    create_label(graph, label, LABEL_TYPE_VERTEX, parent);

You guys can view the original code here.

After this, I tried calling the function like this:

--(this works)

SELECT * FROM ag_catalog.create_vlabel('demo', 'Book');
NOTICE:  VLabel "Book" has been created
 create_vlabel 
---------------
 
(1 row)

But then if I call like this:

--(I get an error)

SELECT * FROM ag_catalog.create_vlabel('demo', 'Fantasy', ARRAY['Book']);
ERROR:  function ag_catalog.create_vlabel(unknown, unknown, text[]) does not exist
LINE 1: SELECT * FROM ag_catalog.create_vlabel('demo', 'Fantasy', ARRAY...
                      ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

How can I fix this so that it successfully gets all the elements from the passed array?

3

Answers


  1. Try dropping the extension, and then re-creating it.

    DROP EXTENSION age CASCADE;
    CREATE EXTENSION age;
    LOAD age;
    
    Login or Signup to reply.
  2. You should run the make command in age folder again:

    sudo make PG_CONFIG=/path/to/postgres/bin/pg_config install
    

    Then drop the extension, and re-create it as told by Rafsun.

    Then you should add the following code:

    if (!PG_ARGISNULL(2))
    {
        //check if the third argument is a string
        ArrayType  *keys = PG_GETARG_ARRAYTYPE_P(2);
        int elem_count=0;
    
        Datum *parents_datums;
        bool *parent_nulls;
        int i;
    
        
        // elem_count = ArrayGetNItems(ARR_NDIM(keys), ARR_DIMS(keys));
    
        //get the elements in the array and parents data
        deconstruct_array(keys, NAMEOID, 63, false, 'i', &parents_datums, &parent_nulls, &elem_count);
    
        for (i=0;i<elem_count;i++){
            elog(NOTICE, "Value at the %d index: %s", i, DatumGetCString(parents_datums[i]));
        }
    
        //print the value at the first index
        elog(NOTICE, "Value at the first index: %d", keys[0].elemtype);
    
    
        //print the number  of elements in the array
        elog(NOTICE, "Number of elements in the array: %d", elem_count);
    
    } 
    
    Login or Signup to reply.
  3. It’s a good thing to drop the extension as mentioned by Rafsun. If even that doesn’t work, I see that you’ve used ArrayType for list_parents. I’ve observed whenever ArrayType was used in source code, deconstruct_array() has been used. Maybe that’s the reason it’s unable to access the memory of parent_name and parent_name_str. We might have to process the array into something and then use those.

    Refer this image for details on how to use deconstruct_array

    deconstruct_array_example

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search