PostgreSQL创建扩展简明流程

一.创建sql文件

这里建议大家从sql开始入手,一方面这里的逻辑比较清晰,也易于理解;另一方面sql文件只需要引用c函数就能写进数据库中。

CREATE OR REPLACE FUNCTION rv_sum(INTEGER,INTEGER) RETURNS INTEGER

  AS  '$libdir/demo'

  LANGUAGE 'c' IMMUTABLE STRICT;

本例使用的是直接引用文件的方法,在这个方法中,要创建的sql函数名称必须与c文件中的函数名称一致。

如果c文件中有多个函数,可以通过以下方式声明:

AS '$libdir/demo',’rv_sum’
…

当然,对于一些大型项目,这里的“$libdir/”为方便维护,可以替换成需要的变量写在sql.in里面(就像PostGIS那样)。

 

二.创建c函数

#include "postgres.h"
#include "fmgr.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

PG_FUNCTION_INFO_V1(rv_sum);

Datum rv_sum(PG_FUNCTION_ARGS);

Datum rv_sum(PG_FUNCTION_ARGS)
{
    int sum,a,b;

    a = PG_GETARG_INT32(0);
    b = PG_GETARG_INT32(1);

    sum = a + b;
    PG_RETURN_INT32(sum);
}

在PG中使用c函数进行扩展遵循简单的“三步走”原则:

1. PG_MODULE_MAGIC

在创建扩展时,为了确保不会错误加载共享库文件,PostgreSQL 会检查那个文件的"magic block",来让服务器检查明显的不兼容性。

注意,如果扩展中包含多个c文件,PG_MODULE_MAGIC不需要重复定义。

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

2.声明函数

PG中需要使用PG_FUNCTION_INFO_V1()来声明函数名称,例如:

PG_FUNCTION_INFO_V1(rv_sum);

3.include头文件fmgr.h

本例在第一次测试时没有加fmgr.h,在创建扩展时会报could not load library: undefined symbol的错误。

 

三.编辑Makefile

MODULE_big = demo

IBASE_VERSION = 1.0

OBJS = demo.o
EXTENSION = demo
DATA = demo--1.0.sql

SHLIB_LINK += $(filter -lm,$(LIBS))
USE_PGXS = 1
ifdef USE_PGXS
PG_CONFIG = /opt/PostgreSQL/bin/pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/demo
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif

这里主要涉及两个变量:PG_CONFIG和PGXS,本例为简单起见直接设置了绝对路径,请读者注意。

 

四.编辑control文件

.control主要用于扩展的版本控制,主要版本号要与sql文件的版本号相同。

# demo extension
comment = 'test'
default_version = '1.0'
relocatable = true

 

五.测试

[root@msharvest 11-RV_Media]# make && make install
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fPIC -I. -I./ -I/opt/PostgreSQL/include/postgresql/server -I/opt/PostgreSQL/include/postgresql/internal  -D_GNU_SOURCE   -c -o demo.o demo.c
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fPIC -shared -o demo.so demo.o -L/opt/PostgreSQL/lib    -Wl,--as-needed -Wl,-rpath,'/opt/PostgreSQL/lib',--enable-new-dtags  -lm 
/usr/bin/mkdir -p '/opt/PostgreSQL/lib/postgresql'
/usr/bin/mkdir -p '/opt/PostgreSQL/share/postgresql/extension'
/usr/bin/mkdir -p '/opt/PostgreSQL/share/postgresql/extension'
/usr/bin/install -c -m 755  demo.so '/opt/PostgreSQL/lib/postgresql/demo.so'
/usr/bin/install -c -m 644 .//demo.control '/opt/PostgreSQL/share/postgresql/extension/'
/usr/bin/install -c -m 644 .//demo--1.0.sql  '/opt/PostgreSQL/share/postgresql/extension/'

进入PG,创建扩展

postgres=# CREATE EXTENSION demo;

CREATE EXTENSION    

 

六.参考资料

PostgreSQL 扩展开发基础教程:

http://joshuais.me/postgresql-extension-develop/

 

posted on 2020-05-07 22:40  MsHarvest  阅读(1361)  评论(0编辑  收藏  举报