In Apache AGE source code, we can see that vertices and edges can inherit from multiple labels. For this, it uses functions called create_label
, create_table_for_label
and, depending if it is a vertex or an edge, create_vlabel
and create_elabel
. All these functions can be found here.
The create_vlabel
has three arguments: first the graph name, then the label name, and then an array of parent labels. Then it is going to add each of these parent labels in a list and set a variable called is_inheriting
to 1.
At the end of the create_vlabel
function, it is going to call create_label
function, which calls create_table_for_label
. In this one, it is going to check if the list of parents is different than zero and if is_inheriting
is equal to 0. If this last comparison is not made (the is_inheriting
comparison), when the label inherits from multiple it throws an error stating that the label table to be created must contain a default value different from the parents or the parents' label tables must have a default value equal to the child's.
static void create_table_for_label(char *graph_name, char *label_name,
char *schema_name, char *rel_name,
char *seq_name, char label_type,
List *parents, int is_inheriting)
{
CreateStmt *create_stmt;
PlannedStmt *wrapper;
create_stmt = makeNode(CreateStmt);
// relpersistence is set to RELPERSISTENCE_PERMANENT by makeRangeVar()
create_stmt->relation = makeRangeVar(schema_name, rel_name, -1);
/*
* When a new table has parents, do not create a column definition list.
* Use the parents' column definition list instead, via Postgres'
* inheritance system.
*/
if (list_length(parents) != 0 && is_inheriting == 0)
create_stmt->tableElts = NIL;
else if (label_type == LABEL_TYPE_EDGE)
create_stmt->tableElts = create_edge_table_elements(
graph_name, label_name, schema_name, rel_name, seq_name);
else if (label_type == LABEL_TYPE_VERTEX)
create_stmt->tableElts = create_vertex_table_elements(
graph_name, label_name, schema_name, rel_name, seq_name);
else
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
errmsg("undefined label type \'%c\'", label_type)));
create_stmt->inhRelations = parents;
create_stmt->partbound = NULL;
create_stmt->ofTypename = NULL;
create_stmt->constraints = NIL;
create_stmt->options = NIL;
create_stmt->oncommit = ONCOMMIT_NOOP;
create_stmt->tablespacename = NULL;
create_stmt->if_not_exists = false;
wrapper = makeNode(PlannedStmt);
wrapper->commandType = CMD_UTILITY;
wrapper->canSetTag = false;
wrapper->utilityStmt = (Node *)create_stmt;
wrapper->stmt_location = -1;
wrapper->stmt_len = 0;
ProcessUtility(wrapper, "(generated CREATE TABLE command)",
PROCESS_UTILITY_SUBCOMMAND, NULL, NULL, None_Receiver,
NULL);
// CommandCounterIncrement() is called in ProcessUtility()
}
Inheriting works fine, but the output looks strange with multiple times showing the message "merging multiple inherited definitions of column..."
SELECT create_vlabel('cypher_create', 'child_vlabel_three', ARRAY['parent_vlabel', 'child_vlabel_one', 'child_vlabel_two']);
NOTICE: VLabel child_vlabel_three will inherit from parent_vlabel
NOTICE: VLabel child_vlabel_three will inherit from child_vlabel_one
NOTICE: VLabel child_vlabel_three will inherit from child_vlabel_two
NOTICE: merging multiple inherited definitions of column "id"
NOTICE: merging multiple inherited definitions of column "properties"
NOTICE: merging multiple inherited definitions of column "id"
NOTICE: merging multiple inherited definitions of column "properties"
NOTICE: merging column "id" with inherited definition
NOTICE: merging column "properties" with inherited definition
NOTICE: VLabel "child_vlabel_three" has been created
create_vlabel
---------------
(1 row)
If I could first create the table and then alter it so that it didn't show these repeated messages, how should I do it?