中甲

使用C语言写PostgreSQL函数

2019-10-09 21:32:12来源:励志吧0次阅读

  引言:使用C语言写PostgreSQL中的函数可以很方便的扩展PostgreSQL数据库的功能。由C语言写的函数,使用方法与PostgreSQL中内置的函数基本没有差别,性能基本也没有什么差别。本文一步一步教你如何使用C语言写PostgreSQL函数:

  1. 先根据一个简单函数的生成一个动态库,看PostgreSQL能否使用源文件为cfunc.c,内容如下:

  #include postgres.h int add_one(int arg) { return arg + 1; } 然后我们编译生成,并把此文件拷贝到PostgreSQL的库路径下:

  gcc -I`pg_config --includedir-server` -c cfunc.c gcc -shared -o cfunc.o cp `pg_config --libdir`/. 我们来测试一下:

  osdba@osdba-laptop:~/src/ctest/pgfunc$ psql psql (9.3.2) Type help for help. osdba=# load ''; ERROR: incompatible library /home/osdba/pgsql9.3.2/lib/: missing magic block HINT: Extension libraries are required to use the PG_MODULE_MAGIC macro. 发现报missing magic block的错误。那么什么是magic block呢? PostgreSQL使用的动态库中要求打上一个特殊的标记,当PostgreSQL装载这个动态库时,会检查这个标记,如果没有发现这个标记或发现这个标记与需求的标记不同(如版本不对上)则会报上面这个错误。

  2. 在动态库中加上PostgreSQL的magic block那么如何在动态库中增加这个magic block标记呢?方法是在源代码中加下面两行:

  #include postgres.h #include fmgr.h #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif 这样之后,我们的源代码最终如下:

  #include postgres.h #include fmgr.h #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif int add_one(int arg) { return arg + 1; } 再编译一下:

  osdba@osdba-laptop:~/src/ctest/pgfunc$ gcc -I`pg_config --includedir-server` -c cfunc.c osdba@osdba-laptop:~/src/ctest/pgfunc$ gcc -shared -o cfunc.o /usr/bin/ld: cfunc.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC cfunc.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status 根据报错信息,我们知道在编译时,需要加-fPIC的参数,再重试一下:

  osdba@osdba-laptop:~/src/ctest/pgfunc$ gcc -I`pg_config --includedir-server` -fPIC -c cfunc.c osdba@osdba-laptop:~/src/ctest/pgfunc$ gcc -shared -o cfunc.o osdba@osdba-laptop:~/src/ctest/pgfunc$ cp `pg_config --libdir`/. 编译通过,我们再重试一下:

  osdba@osdba-laptop:~/src/ctest/pgfunc$ psql psql (9.3.2) Type help for help. osdba=# load ''; LOAD osdba=# 装载成功了,我们来使用一下这个动态库,使用之前需要先创建addone函数,创建语句如下:

  CREATE FUNCTION add_one(integer) RETURNS integer AS '$libdir/cfunc1', 'add_one' LANGUAGE C STRICT; 执行情况如下:

  osdba=# CREATE FUNCTION add_one(integer) RETURNS integer AS '$libdir/cfunc', 'add_one' LANGUAGE C STRICT; CREATE FUNCTION osdba=# 创建成功了,使用一下:

  osdba=# select add_one(1); add_one --------- 2 (1 row) osdba=# select add_one(23); add_one --------- 24 (1 row) 3. 总结注意事项总结一下:

  程序中的源代码中要加宏PG_MODULE_MAGIC; 程序中要加#include fmgr.h 编译时要加-fPIC选项。如果没有注意到以上三点,load动态库时,都可能报missing magic block错误。

  4. 结尾实际上面描述的是一个最简单的使用C语言写PostgreSQL函数的方法。为了让写出来函数能更好的与数据库之间交互,PostgreSQL搞了一个更高级的调用规则,前面的方法为Version 0 Calling Conventions,更高级的调用规则称之为Version 1 Calling Conventions,这个调用规则下,函数的声明都有统一的如下形式:

  Datum funcname(PG_FUNCTION_ARGS) 同时为了告诉PostgreSQL使用的是版本1的调用规则,需要加函数:

  PG_FUNCTION_INFO_V1(funcname); 具体的使用方法见PostgreSQL官方文件,我在这里只做抛砖引玉。

知识产权
旅游攻略
南昌汽车资讯网
分享到: