PostgreSQL中怎么载入外部C语言函数
这期内容当中小编将会给大家带来有关PostgreSQL中怎么载入外部C语言函数,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
quanzl-mac:postgresql.builtin_pool quanzl$ nm lib/plpgsql.so ...0000000000007e10 T _pg_finfo_plpgsql_call_handler000000000001c888 s _pg_finfo_plpgsql_call_handler.my_finfo...0000000000007e20 T _plpgsql_call_handler...
这是怎么来的?直接看函数定义(src/pl/plpgsql/src/pl_handler.c):
...PG_FUNCTION_INFO_V1(plpgsql_call_handler);Datumplpgsql_call_handler(PG_FUNCTION_ARGS){...所有外挂模块中的函数都是这种形式定义,返回值必须是Datum,参数必须使用预处理符 PG_FUNCTION_ARGS。plpgsql_call_handler是定义在pg_language中的存储过程处理入口,调用方式与可以在SQL中使用的函数有所不同,所以它直接使用return方式返回值。而一般的SQL函数比如earthdistance模块中的geo_distance
...PG_FUNCTION_INFO_V1(geo_distance);Datumgeo_distance(PG_FUNCTION_ARGS){... PG_RETURN_FLOAT8(result);}SQL定义
CREATE FUNCTION geo_distance (point, point)RETURNS float8LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE AS 'MODULE_PATHNAME';
它必须使用 PG_RETURN_xxx 系列预处理符来返回。
返回值的使用可以参考DirectFunctionCalln(n为数字,表是参数个数)定义去理解,有必要的话另文再写,这里简单一提,主要还是讲预处理符PG_FUNCTION_INFO_V1,下边是它的定义:
#define PG_FUNCTION_INFO_V1(funcname) \extern Datum funcname(PG_FUNCTION_ARGS); \extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \const Pg_finfo_record * \CppConcat(pg_finfo_,funcname) (void) \{ \ static const Pg_finfo_record my_finfo = { 1 }; \ return &my_finfo; \} \extern int no_such_variable再看earthdistance.so的symbol:
0000000000000de0 T _geo_distance0000000000000dd0 T _pg_finfo_geo_distance0000000000000fb0 s _pg_finfo_geo_distance.my_finfo
CppConcat(pg_finfo_,funcname)新定义一个前缀 pg_finfo_ 的函数,pg_finfo_geo_distance就是这么来的,它很简单,返回结构体 Pg_finfo_record,其成员 api_version 为 1。
强大的PG已经为今后扩展做好准备。
函数加载部分(src/backend/utils/fmgr/fmgr.c)的检查 fetch_finfo_record:
const Pg_finfo_record *inforec; infofuncname = psprintf("pg_finfo_%s", funcname); /* Try to look up the info function */ infofunc = (PGFInfoFunction) lookup_external_function(filehandle, infofuncname);... inforec = (*infofunc) ();...上述就是小编为大家分享的PostgreSQL中怎么载入外部C语言函数了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。