本节以实现甲骨文中的add_months函数为例介绍如何通过改造内核实现自定义系统函数。
二,实现步骤
有了上面的基础知识,接下来我们一步一步的实现add_months自定义函数。
<强>
1 .获取函数Oid
强>
PostgreSQL提供了unused_oids工具用于快速检索未使用的Oid,该文件位于src/include/目录目录下
<前>
<代码>
发现- name unused_oids
./src/include/目录/unused_oids
[root@localhost pg11) #。/src/include/目录/unused_oids
2 - 9
3423 - 3436
3996
3998
4001 - 4013
4142 - 4199
4217 - 4565
4572 - 4999
5017 - 5027
5029 - 5999
6015 - 6099
6103
6105
6107 - 6109
6116
6122 - 9999
代码>
>之前
我们选择了Oid=5100
<强>
2 .注册函数
强>
在文件pg_proc.dat中添加add_months函数
<前>
<代码>
# src/include/目录/pg_proc.dat
…
{oid=比;“5100”,备注说明=比;“oracle-like add_months函数”,
proname=比;add_months, provariadic=比;“0”,
proisstrict=比;“f”, prorettype=比;“日期”,proargtypes=比;“int4日期”,
prosrc=https://www.yisu.com/zixun/> add_months},
代码>
>之前
该文件中的条目对应结构体Form_pg_proc
<前> <代码>/* - - - - - - - - - - - - - - - - - * pg_proc定义。cpp这变成 * typedef struct FormData_pg_proc * pg_proc定义 * - - - - - - - - - - - - - - - - - */目录(1255年pg_proc ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID BKI_SCHEMA_MACRO(81年,ProcedureRelation_Rowtype_Id) { *//*程序名称//过程名称 NameData proname;/* OID的命名空间包含这个proc *///系统OID Oid pronamespace BKI_DEFAULT (PGNSP);/*过程所有者*///拥有者所有者 Oid proowner BKI_DEFAULT (PGUID); *//*的OID pg_language条目//实现语言调用接口,pg_language中的OID。//默认为12-internal,其他选项包括13 c语言,14-sql, 13275 - plpgsql Oid prolang BKI_DEFAULT (12); 预计执行成本/* *///估算的执行成本,默认为1 float4 procost BKI_DEFAULT (1);/*估计的行号(如果proretset) *///估算的结果行数,默认为0 float4 prorows BKI_DEFAULT (0);/*可变数组的元素类型,或者0 *///可变数组参数元素类型,默认为0 Oid provariadic BKI_DEFAULT (0) BKI_LOOKUP (pg_type);/*调用转换在规划*///在计划期间的转换调用,默认为0//可通过此列指定的函数来简化 regproc protransform BKI_DEFAULT (0) BKI_LOOKUP (pg_proc);/*见PROKIND_类别*///详见下面的PROKIND_XXX char prokind BKI_DEFAULT (f);/*安全定义者*///安全定义器 bool prosecdef BKI_DEFAULT (f);/*是防泄漏的函数吗?*///弱认证函数?除了返回值,没有关系参数的信息被传播 bool proleakproof BKI_DEFAULT (f);/*严格的关于取消吗?*///取消的处理(严格还是不严格) bool proisstrict BKI_DEFAULT (t);/*返回一组吗?*///返回集合?默认为F bool proretset BKI_DEFAULT (f);/*见PROVOLATILE_类别*///详见下面的PROVOLATILE_XXX char provolatile BKI_DEFAULT(我);/*见PROPARALLEL_类别*///详见下面的PROPARALLEL_XXX char proparallel BKI_DEFAULT(年代);/* */数量的参数/*注意:不需要给出pg_proc.dat;genbki。pl会计算*///参数个数//注意:不需要在pg_proc.dat中指定,genbki.pl会自动计算 int16 pronargs; 用默认值*//*数量的参数//有默认值的参数个数 int16 pronargdefaults BKI_DEFAULT (0); *//* OID的结果类型//结果类型OID Oid prorettype BKI_LOOKUP (pg_type);/* *变长字段从这里开始,但我们允许直接访问 * proargtypes *从这里开始为可变长字段,但我们运行直接访问原型类型 *//*参数类型(不包括params) *///参数类型(剔除出了参数)//只包括输入参数(含INOUT和可变参数 oidvector proargtypes BKI_LOOKUP (pg_type); # ifdef CATALOG_VARLEN/*所有参数类型(NULL如果> 三、参考资料