PostgreSQL 外部动态连接库魔法块的使用

前端之家收集整理的这篇文章主要介绍了PostgreSQL 外部动态连接库魔法块的使用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
最常见的一种方式
CREATE FUNCTION c_overpaid(emp,integer) RETURNS boolean
    AS 'os_libpath','c_funcname'
    LANGUAGE C STRICT;

文档中提到两种调用习惯 V0 和 V1,从代码里边看,V0已经不再支持
这里不去考虑函数定义方法,着重看 MAGIC 定义,相信很多朋友遇到过这个错误

ereport(ERROR,(errmsg("incompatible library \"%s\": missing magic block",libname),errhint("Extension libraries are required to use the PG_MODULE_MAGIC macro.")));


这是没有在外部库里边引入 magic data 引起的,它定义在 fmgr.h 中:

/* The actual data block contents */
#define PG_MODULE_MAGIC_DATA \
{ \
	sizeof(Pg_magic_struct),\
	PG_VERSION_NUM / 100,\
	FUNC_MAX_ARGS,\
	INDEX_MAX_KEYS,\
	NAMEDATALEN,\
	FLOAT4PASSBYVAL,\
	FLOAT8PASSBYVAL \
}

/*
* Declare the module magic function. It needs to be a function as the dlsym
* in the backend is only guaranteed to work on functions,not data
*/
typedef const Pg_magic_struct *(*PGModuleMagicFunction) (void);

#define PG_MAGIC_FUNCTION_NAME Pg_magic_func
#define PG_MAGIC_FUNCTION_NAME_STRING "Pg_magic_func"

#define PG_MODULE_MAGIC \
extern PGDLLEXPORT const Pg_magic_struct *PG_MAGIC_FUNCTION_NAME(void); \
const Pg_magic_struct * \
PG_MAGIC_FUNCTION_NAME(void) \
{ \
 static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA; \
 return &Pg_magic_data; \
} \
extern int no_such_variable
载入外部库时,首先检查有没有 "Pg_magic_func" 函数,如果有将它的返回值与当前数据库内核定义作比较,如果不符合就会报错,具体逻辑请看 src/backend/utils/fmgr/dfmgr.c 中定义的 internal_load_library 函数代码

猜你在找的Postgre SQL相关文章