目前,我作为一个团队的一部分,正在努力将RTE从apache-age源代码替换为PNSI,以便版本在代码方面变得或统一。
我已经检查了Apache AGE for PostgreSQL v12使用的代码,它包含一个函数,我的目标是像v13上的那个一样改变它。
这是AGE_PG13中函数的定义
static Node *make_vertex_expr(cypher_parsestate *cpstate,
ParseNamespaceItem *pnsi,
char *label);
这就是AGE_PG12上的内容
static Node *make_vertex_expr(cypher_parsestate *cpstate, RangeTblEntry *rte,
char *label);
我们可以注意到这里的变化发生在参数RangeTblEntry *rte和ParseNamespaceItem *pnsi这是我的目标
我已经更新了功能中所需的所有更改。
对于那些不知道的人:PNSI是RTE的一个容器,所以RTE是PNSI的属性,这让我们觉得如果我们已经将使用RTE的每个需要的部分替换为PNSI->RTE,那就没问题了。
以下是AGE_PG12上发生的更改
更改@src/backend/parser/cypher_clause.c
@@ -4574,20 +4575,22 @@ static Expr *transform_cypher_node(cypher_parsestate *cpstate,
label_range_var = makeRangeVar(schema_name, rel_name, -1);
alias = makeAlias(node->name, NIL);
-
- rte = addRangeTableEntry(pstate, label_range_var, alias,
+ pnsi = malloc(sizeof(ParseNamespaceItem));
+ pnsi->p_rte = addRangeTableEntry(pstate, label_range_var, alias,
label_range_var->inh, true);
+
+ Assert(pnsi != NULL);
/*
* relation is visible (r.a in expression works) but attributes in the
* relation are not visible (a in expression doesn't work)
*/
- addRTEtoQuery(pstate, rte, true, true, true);
+ addRTEtoQuery(pstate, pnsi->p_rte, true, true, true);
resno = pstate->p_next_resno++;
if (valid_label)
{
- expr = (Expr *)make_vertex_expr(cpstate, rte, node->label);
+ expr = (Expr *)make_vertex_expr(cpstate, pnsi, node->label);
}
else
{
@@ -4650,7 +4653,7 @@ static Node *make_edge_expr(cypher_parsestate *cpstate, RangeTblEntry *rte,
return (Node *)func_expr;
}
-static Node *make_vertex_expr(cypher_parsestate *cpstate, RangeTblEntry *rte,
+static Node *make_vertex_expr(cypher_parsestate *cpstate, ParseNamespaceItem *pnsi,
char *label)
{
@@ -4666,7 +4669,7 @@ static Node *make_vertex_expr(cypher_parsestate *cpstate, RangeTblEntry *rte,
func_oid = get_ag_func_oid("_agtype_build_vertex", 3, GRAPHIDOID,
CSTRINGOID, AGTYPEOID);
- id = scanRTEForColumn(pstate, rte, AG_VERTEX_COLNAME_ID, -1, 0, NULL);
+ id = scanRTEForColumn(pstate, pnsi->p_rte, AG_VERTEX_COLNAME_ID, -1, 0, NULL);
@@ -4682,9 +4685,8 @@ static Node *make_vertex_expr(cypher_parsestate *cpstate, RangeTblEntry *rte,
InvalidOid, COERCE_EXPLICIT_CALL);
label_name_func_expr->location = -1;
- props = scanRTEForColumn(pstate, rte, AG_VERTEX_COLNAME_PROPERTIES, -1, 0,
+ props = scanRTEForColumn(pstate, pnsi->p_rte, AG_VERTEX_COLNAME_PROPERTIES, -1, 0,
NULL);
问题在这里;我看到这是一种内存浪费,因为对于使用RTE的每个示例,我都需要将其替换为大小为PNSI(更大)的分配内存,以便能够在该PNSI中使用RTE?有没有其他有效的方法,我可以遵循,以实现我的目标?
参考资料
- Gist包含RTE和PNSI的定义结构
- RTE
- PNSI
- Postgresql PNSI
- AGE parser using RTE (PG12)
- AGE parser using PNSI (PG13)
- Apache AGE
1条答案
按热度按时间5n0oy7gb1#
你不能在PostgreSQL函数中使用
malloc()
。PostgreSQL在C之上构建了自己的内存管理系统。因此,您应该在适当的内存上下文中palloc()
内存,并且它将在适当的时间(当语句或事务结束时)自动释放。使用
ParseNamespaceItem
是否是一个好主意是一个问题,你必须与编写Apache AGE的人讨论。