PostgreSQL插件开发1

PostgreSQL的扩展性十分强大,不仅可以自定义操作符、索引等,还可以允许用户安装需求来安装contrib模块,即扩展(extension)。
比较常见的一些extension有pg_pathman(分区表)、citus(分布式)等等,那么我们该怎么通过编写扩展向pg中增加想要的功能呢?

首先,我们想要安装extension必需要在contrib目录下编写两个必要的文件:
extension_name.control 控制文件,声明该扩展的基础信息。
extension–version.sql 加载扩展所需要执行的SQL文件。

今天学习了一些扩展开发的基础知识,下面我自己写了个简单的extension来测试。这里编写一个extension来代替pg中的to_char函数,弥补to_char函数不能作为函数索引的缺陷(因为系统自带的to_char不是immutable函数)。

例子:
1、创建控制文件
在contrib目录下一个my_tochar文件夹,在该文件夹下面创建my_tochar.control文件,内容如下:

# my_tochar extension
comment = 'my_tochar auth by wuc'
default_version = '0.0.1'
relocatable = true

2、创建Makefile文件

EXTENSION = my_tochar        # 扩展的名称
DATA = my_tochar--0.0.1.sql  # 扩展安装的SQL文件
# 以下是 PostgreSQL 构建扩展相关的命令,保留就可以
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
 include $(PGXS)

3、创建sql文件
我们想要实现的功能需要在sql文件里面编写函数:

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION my_tochar" to load this file. \quit
create or replace function my_tochar(some_time timestamp) returns text as $$
        select to_char($1, 'yyyy-mm-dd'); 
        $$ language sql  immutable;

4、安装扩展
接下来我们就可以编译文件然后将扩展添加到数据库中了。
编译安装:

pg12@oracle-> make&make install
[1] 12702
make: Nothing to be done for `all'.
/bin/mkdir -p '/home/pg12/pgsql12.4/share/extension'
/bin/mkdir -p '/home/pg12/pgsql12.4/share/extension'
/bin/install -c -m 644 .//my_tochar.control '/home/pg12/pgsql12.4/share/extension/'
/bin/install -c -m 644 .//my_tochar--0.0.1.sql  '/home/pg12/pgsql12.4/share/extension/'
[1]+  Done                    make

去数据库里面添加扩展:

bill=# create extension my_tochar ;
CREATE EXTENSION
bill=# \dx my_tochar 
              List of installed extensions
   Name    | Version | Schema |       Description       
-----------+---------+--------+-------------------------
 my_tochar | 0.0.1   | public | my_tochar author by wuc
(1 row)

验证:

bill=# select my_tochar('now()');
 my_tochar  
------------
 2019-11-21
(1 row)

到这里我们就已经成功的完成了这个简单的extension的编写。但是还有一点不足之处,万一我们的extension有错该如何测试呢?上面我们没有通过测试就直接将extension添加进去了,万一这个extension对数据库影响很大怎么办,我们该怎么先进行测试呢?这里推荐make installcheck的方式来测试。

5、测试
首先,我们把测试写成一个 SQL 文件,保存为sql/my_tochar_test.sql。我们把之前用于测试的 SQL 写入到这个文件中,并且在开头添加加载扩展的语句(如果没有,在运行测试时就会返回错误)。

CREATE EXTENSION my_tochar;

select my_tochar('2019-11-20 23:36:48.996747+08');
然后在Makefile中增加测试命令REGRESS:
EXTENSION = my_tochar        # 扩展的名称
DATA = my_tochar--0.0.1.sql  # 扩展安装的SQL文件
REGRESS = my_tochar_test
# 以下是 PostgreSQL 构建扩展相关的命令,保留就可以
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
 include $(PGXS)

我们运行make installcheck看看会发生什么。
pg12@oracle-> make installcheck
/home/pg12/pgsql12.4/lib/pgxs/src/makefiles/…/…/src/test/regress/pg_regress --inputdir=./ --bindir=’/home/pg12/pgsql12.4/bin’ --dbname=contrib_regression my_tochar_test
(using postmaster on /home/pg12/pgdata, port 2019)
============== dropping database “contrib_regression” ==============
NOTICE: database “contrib_regression” does not exist, skipping
DROP DATABASE
============== creating database “contrib_regression” ==============
CREATE DATABASE
ALTER DATABASE
============== running regression test queries ==============
test my_tochar_test … diff: /home/pg12/postgresql-12beta4/contrib/my_tochar/expected/my_tochar_test.out: No such file or directory
diff command failed with status 512: diff “/home/pg12/postgresql-12beta4/contrib/my_tochar/expected/my_tochar_test.out” “/home/pg12/postgresql-12beta4/contrib/my_tochar/results/my_tochar_test.out” > “/home/pg12/postgresql-12beta4/contrib/my_tochar/results/my_tochar_test.out.diff”
make: *** [installcheck] Error 2
检查错误可以发现,缺少两个目录results和expected。我们要将期望的结果写入expected/array_ext_test.out,执行测试 SQL 输出的结果会写入results/array_ext_test.out。这样,通过 diff 这两个文件的内容差异,就能验证结果是否符合预期。
pg12@oracle-> mkdir -p expected/
pg12@oracle-> mkdir -p results/
pg12@oracle-> touch expected/my_tochar_test.out

继续测试:

pg12@oracle-> make installcheck
/home/pg12/pgsql12.4/lib/pgxs/src/makefiles/../../src/test/regress/pg_regress --inputdir=./ --bindir='/home/pg12/pgsql12.4/bin'    --dbname=contrib_regression my_tochar_test
(using postmaster on /home/pg12/pgdata, port 2019)
============== dropping database "contrib_regression" ==============
DROP DATABASE
============== creating database "contrib_regression" ==============
CREATE DATABASE
ALTER DATABASE
============== running regression test queries        ==============
test my_tochar_test               ... ok           11 ms

=====================
 All 1 tests passed. 
=====================

提示成功!

以上就是一个简单开发一个 PostgreSQL 扩展的所需的基本方法。

发布了70 篇原创文章 · 获赞 5 · 访问量 3146

猜你喜欢

转载自blog.csdn.net/weixin_39540651/article/details/103260604