| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #include "postgres.h" |
| |
| #include "access/xact.h" |
| #include "access/genam.h" |
| #include "access/heapam.h" |
| #include "catalog/dependency.h" |
| #include "catalog/objectaddress.h" |
| #include "commands/defrem.h" |
| #include "commands/schemacmds.h" |
| #include "commands/tablecmds.h" |
| #include "fmgr.h" |
| #include "miscadmin.h" |
| #include "nodes/makefuncs.h" |
| #include "nodes/nodes.h" |
| #include "nodes/parsenodes.h" |
| #include "nodes/pg_list.h" |
| #include "nodes/value.h" |
| #include "parser/parser.h" |
| #include "utils/fmgroids.h" |
| #include "utils/relcache.h" |
| #include "utils/rel.h" |
| |
| #include "catalog/ag_graph.h" |
| #include "catalog/ag_label.h" |
| #include "commands/label_commands.h" |
| #include "utils/graphid.h" |
| #include "commands/graph_commands.h" |
| #include "utils/load/age_load.h" |
| #include "utils/load/ag_load_edges.h" |
| #include "utils/load/ag_load_labels.h" |
| |
| |
| PG_FUNCTION_INFO_V1(create_complete_graph); |
| |
| /* |
| * SELECT * FROM ag_catalog.create_complete_graph('graph_name',no_of_nodes, 'edge_label', 'node_label'=NULL); |
| */ |
| |
| Datum create_complete_graph(PG_FUNCTION_ARGS) |
| { |
| Oid graph_id; |
| Name graph_name; |
| |
| int64 no_vertices; |
| int64 i,j,vid = 1, eid, start_vid, end_vid; |
| |
| Name vtx_label_name = NULL; |
| Name edge_label_name; |
| int32 vtx_label_id; |
| int32 edge_label_id; |
| |
| agtype *props = NULL; |
| graphid object_graph_id; |
| graphid start_vertex_graph_id; |
| graphid end_vertex_graph_id; |
| |
| Oid vtx_seq_id; |
| Oid edge_seq_id; |
| |
| char* graph_name_str; |
| char* vtx_name_str; |
| char* edge_name_str; |
| |
| graph_cache_data *graph_cache; |
| label_cache_data *vertex_cache; |
| label_cache_data *edge_cache; |
| |
| Oid nsp_id; |
| Name vtx_seq_name; |
| char *vtx_seq_name_str; |
| |
| Name edge_seq_name; |
| char *edge_seq_name_str; |
| |
| int64 lid; |
| |
| if (PG_ARGISNULL(0)) |
| { |
| ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| errmsg("graph name can not be NULL"))); |
| } |
| |
| if (PG_ARGISNULL(1)) |
| { |
| ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| errmsg("number of nodes can not be NULL"))); |
| } |
| |
| if (PG_ARGISNULL(2)) |
| { |
| ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| errmsg("edge label can not be NULL"))); |
| } |
| |
| |
| graph_name = PG_GETARG_NAME(0); |
| no_vertices = (int64) PG_GETARG_INT64(1); |
| edge_label_name = PG_GETARG_NAME(2); |
| namestrcpy(vtx_label_name, AG_DEFAULT_LABEL_VERTEX); |
| |
| graph_name_str = NameStr(*graph_name); |
| vtx_name_str = AG_DEFAULT_LABEL_VERTEX; |
| edge_name_str = NameStr(*edge_label_name); |
| |
| |
| if (!graph_exists(graph_name_str)) |
| { |
| DirectFunctionCall1(create_graph, CStringGetDatum(graph_name)); |
| |
| } |
| |
| graph_id = get_graph_oid(graph_name_str); |
| |
| |
| |
| 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)) |
| { |
| DirectFunctionCall2(create_vlabel, CStringGetDatum(graph_name), CStringGetDatum(vtx_label_name)); |
| } |
| } |
| |
| if (!label_exists(edge_name_str, graph_id)) |
| { |
| DirectFunctionCall2(create_elabel, CStringGetDatum(graph_name), CStringGetDatum(edge_label_name)); |
| } |
| |
| vtx_label_id = get_label_id(vtx_name_str, graph_id); |
| edge_label_id = get_label_id(edge_name_str, graph_id); |
| |
| graph_cache = search_graph_name_cache(graph_name_str); |
| vertex_cache = search_label_name_graph_cache(vtx_name_str,graph_id); |
| edge_cache = search_label_name_graph_cache(edge_name_str,graph_id); |
| |
| nsp_id = graph_cache->namespace; |
| vtx_seq_name = &(vertex_cache->seq_name); |
| vtx_seq_name_str = NameStr(*vtx_seq_name); |
| |
| edge_seq_name = &(edge_cache->seq_name); |
| edge_seq_name_str = NameStr(*edge_seq_name); |
| |
| vtx_seq_id = get_relname_relid(vtx_seq_name_str, nsp_id); |
| edge_seq_id = get_relname_relid(edge_seq_name_str, nsp_id); |
| |
| /* Creating vertices*/ |
| for (i=(int64)1;i<=no_vertices;i++) |
| { |
| vid = nextval_internal(vtx_seq_id, true); |
| object_graph_id = make_graphid(vtx_label_id, vid); |
| props = create_empty_agtype(); |
| insert_vertex_simple(graph_id,vtx_name_str,object_graph_id,props); |
| } |
| |
| lid = vid; |
| |
| /* Creating edges*/ |
| for (i = 1;i<=no_vertices-1;i++) |
| { |
| start_vid = lid-no_vertices+i; |
| for(j=i+1;j<=no_vertices;j++) |
| { |
| end_vid = lid-no_vertices+j; |
| eid = nextval_internal(edge_seq_id, true); |
| object_graph_id = make_graphid(edge_label_id, eid); |
| |
| start_vertex_graph_id = make_graphid(vtx_label_id, start_vid); |
| end_vertex_graph_id = make_graphid(vtx_label_id, end_vid); |
| |
| props = create_empty_agtype(); |
| |
| insert_edge_simple(graph_id, edge_name_str, |
| object_graph_id, start_vertex_graph_id, |
| end_vertex_graph_id, props); |
| |
| } |
| } |
| |
| PG_RETURN_VOID(); |
| } |
| |