在Apache AGE源代码中,我们可以看到顶点和边可以继承多个标签。为此,它使用了create_label
、create_table_for_label
以及create_vlabel
和create_elabel
(取决于它是顶点还是边)。所有这些功能都可以在here中找到。create_vlabel
有三个参数:首先是图形名称,然后是标签名称,最后是父标签数组。然后将这些父标签添加到列表中,并将名为is_inheriting
的变量设置为1。
在create_vlabel
函数结束时,它将调用create_label
函数,该函数将调用create_table_for_label
。在这个例子中,它将检查父列表是否不同于零,以及is_inheriting
是否等于0。如果没有进行最后一个比较(is_inheriting
比较),当标签继承自多个标签时,它会抛出一个错误,指出要创建的标签表必须包含一个不同于父标签表的默认值,或者父标签表必须具有一个等于子标签表的默认值。
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()
}
继承工作正常,但输出看起来很奇怪,多次显示消息“* 合并列的多个继承定义。.. *”
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)
如果我可以先创建一个表,然后修改它,使它不显示这些重复的消息,我应该怎么做呢?
1条答案
按热度按时间2nbm6dog1#
在函数定义中,需要检查父列是否已包含在列定义列表中。下面是更新后的代码