PostgreSQL源码解读》(180)——内核研发# 4(如何实现自定义系统函数)

  

  本节以实现甲骨文中的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如果>            三、参考资料   

PostgreSQL源码解读》(180)——内核研发# 4(如何实现自定义系统函数)