在make_edge_expr函数中使用PNSI(ParseNamespaceItem)替换RTE(RangeTblEntry)

xam8gpfp  于 2023-06-21  发布在  其他
关注(0)|答案(1)|浏览(79)

目前,我作为一个团队的一部分,正在努力将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 *rteParseNamespaceItem *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?有没有其他有效的方法,我可以遵循,以实现我的目标?

参考资料

5n0oy7gb

5n0oy7gb1#

你不能在PostgreSQL函数中使用malloc()。PostgreSQL在C之上构建了自己的内存管理系统。因此,您应该在适当的内存上下文中palloc()内存,并且它将在适当的时间(当语句或事务结束时)自动释放。
使用ParseNamespaceItem是否是一个好主意是一个问题,你必须与编写Apache AGE的人讨论。

相关问题