in src/backend/utils/graph_generation.c [231:351]
Datum age_create_barbell_graph(PG_FUNCTION_ARGS)
{
FunctionCallInfo arguments;
Oid graph_oid;
Name graph_name;
char* graph_name_str;
int64 start_node_index, end_node_index, nextval;
Name node_label_name = NULL;
int32 node_label_id;
char* node_label_str;
Name edge_label_name;
int32 edge_label_id;
char* edge_label_str;
graphid object_graph_id;
graphid start_node_graph_id;
graphid end_node_graph_id;
graph_cache_data* graph_cache;
label_cache_data* edge_cache;
agtype* properties = NULL;
arguments = fcinfo;
/* Checking for possible NULL arguments */
/* Name graph_name */
if (PG_ARGISNULL(0))
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("Graph name cannot be NULL")));
}
graph_name = PG_GETARG_NAME(0);
graph_name_str = NameStr(*graph_name);
/* int graph size (number of nodes in each complete graph) */
if (PG_ARGISNULL(1) && PG_GETARG_INT32(1) < 3)
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("Graph size cannot be NULL or lower than 3")));
}
/*
* int64 bridge_size: currently only stays at zero.
* to do: implement bridge with variable number of nodes.
*/
if (PG_ARGISNULL(2) || PG_GETARG_INT32(2) < 0 )
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("Bridge size cannot be NULL or lower than 0")));
}
/* node label: if null, gets default label, which is "_ag_label_vertex" */
if (PG_ARGISNULL(3))
{
namestrcpy(node_label_name, AG_DEFAULT_LABEL_VERTEX);
}
else
{
node_label_name = PG_GETARG_NAME(3);
}
node_label_str = NameStr(*node_label_name);
/* Name edge_label */
if (PG_ARGISNULL(5))
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("edge label can not be NULL")));
}
edge_label_name = PG_GETARG_NAME(5);
edge_label_str = NameStr(*edge_label_name);
/* create two separate complete graphs */
DirectFunctionCall4(create_complete_graph, arguments->args[0].value,
arguments->args[1].value,
arguments->args[5].value,
arguments->args[3].value);
DirectFunctionCall4(create_complete_graph, arguments->args[0].value,
arguments->args[1].value,
arguments->args[5].value,
arguments->args[3].value);
graph_oid = get_graph_oid(graph_name_str);
node_label_id = get_label_id(node_label_str, graph_oid);
edge_label_id = get_label_id(edge_label_str, graph_oid);
/*
* Fetching caches to get next values for graph id's, and access nodes
* to be connected with edges.
*/
graph_cache = search_graph_name_cache(graph_name_str);
edge_cache = search_label_name_graph_cache(edge_label_str,graph_oid);
/* connect a node from each graph */
/* first created node, from the first complete graph */
start_node_index = 1;
/* last created node, second graph */
end_node_index = arguments->args[1].value*2;
/* next index to be assigned to a node or edge */
nextval = get_nextval_internal(graph_cache, edge_cache);
/* build the graph id's of the edge to be created */
object_graph_id = make_graphid(edge_label_id, nextval);
start_node_graph_id = make_graphid(node_label_id, start_node_index);
end_node_graph_id = make_graphid(node_label_id, end_node_index);
properties = create_empty_agtype();
/* connect two nodes */
insert_edge_simple(graph_oid, edge_label_str,
object_graph_id, start_node_graph_id,
end_node_graph_id, properties);
PG_RETURN_VOID();
}