关于在AGE源码中创建可用于openCypher语法的函数的技术问询
关于在AGE源码中创建可用于openCypher语法的函数的技术问询
嘿,看起来你已经深入扒过AGE源码里新增函数的提交记录了,这可是个很棒的切入点!咱们来一步步理清你的疑问:
一、新增openCypher可用函数需要修改哪些文件?
从你提到的isEmpty()和reverse()两个例子来看,通常需要修改以下几类文件,个别情况可能会有差异:
agtype.c:这是核心必改文件,所有基于C实现的AGE函数都要在这里写具体的逻辑。你看到的age_isempty()的函数体、PG_FUNCTION_INFO_V1(age_isempty)宏定义都在这里,reverse()的实现也一样。- 版本迁移SQL文件(比如
age--1.2.0.sql):需要在这里添加SQL层面的函数声明,也就是你贴出来的这段:
这段代码的作用是在PostgreSQL中注册这个函数,让数据库能识别并调用它。你说CREATE FUNCTION ag_catalog.age_isempty(agtype) RETURNS boolean LANGUAGE c IMMUTABLE RETURNS NULL ON NULL INPUT PARALLEL SAFE AS 'MODULE_PATHNAME';reverse()的提交里没加这个,大概率是它被放到了其他版本的迁移文件或者统一的初始化脚本里,毕竟每个函数都需要在PG层面注册才能用。 - Cypher函数映射文件:比如
src/backend/cypher/functions/cypher_functions.c这类文件,这里是实现openCypher函数名到PG函数名映射的关键。举个例子,就是在这里把Cypher里的isEmpty()关联到PG里的ag_catalog.age_isempty(),让AGE的解析器能正确识别并转换。 - 测试SQL文件(比如
cypher_match.sql):如果要保证函数功能正常,还需要添加对应的测试用例,就像你看到的isEmpty()的测试代码那样,验证函数在Cypher查询里的使用效果。
二、为什么Cypher里调用isEmpty()而不是age_isempty()?
这其实是AGE做的一层语法映射:
AGE需要兼容openCypher的标准语法,所以会把Cypher里的标准函数名(比如驼峰式的isEmpty),通过内部的映射逻辑转换成PostgreSQL中注册的带前缀的函数名(比如ag_catalog.age_isempty)。
这个映射逻辑就写在刚才提到的Cypher函数映射文件里,AGE的解析器在处理Cypher查询时,会自动把isEmpty()替换成ag_catalog.age_isempty()去执行,这样既符合openCypher的用户习惯,又能在PG环境下正常运行。
总结一下,新增一个Cypher可用的AGE函数,核心就是实现逻辑、注册函数、做语法映射这三步,再加上测试用例就更完整啦。要是还有拿不准的地方,不妨对比下reverse()的映射配置,就能找到对应的规律了!
备注:内容来源于stack exchange,提问作者Matheus Farias




