温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

PostgreSQL中怎么载入外部C语言函数

发布时间:2021-06-21 15:39:05 来源:亿速云 阅读:290 作者:Leah 栏目:大数据

这期内容当中小编将会给大家带来有关PostgreSQL中怎么载入外部C语言函数,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

quanzl-mac:postgresql.builtin_pool quanzl$ nm lib/plpgsql.so 
...
0000000000007e10 T _pg_finfo_plpgsql_call_handler
000000000001c888 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);

Datum
plpgsql_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);

Datum
geo_distance(PG_FUNCTION_ARGS)
{
...
  PG_RETURN_FLOAT8(result);
}

SQL定义

CREATE FUNCTION geo_distance (point, point)
RETURNS float8
LANGUAGE 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_distance
0000000000000dd0 T _pg_finfo_geo_distance
0000000000000fb0 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语言函数了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI