PostgreSQL插件开发2——C函数

在前面的例子中,我们使用sql函数来实现了一个简单的插件开发,但是在实际应用中,我们开发插件基本都是使用C函数,其效率要远远高得多。
下面我们使用C函数来创建一个简单的插件,用来实现16进制的转换。
例子:
1、创建控制文件
在contrib目录下一个base16_encode文件夹,在该文件夹下面创建base16.control文件,内容如下:

# base16 extension
comment = 'base16 datatype auth by bill'
default_version = '0.0.1'
relocatable = true

2、创建Makefile文件
其中MODULES参数指是我们要创建的c函数文件。

EXTENSION = base16        # the extensions name
DATA = base16--0.0.1.sql  # script files to install
REGRESS = base16_test     # our test script file (without extension)
MODULES = base16          # our c module file to build

# postgres build stuff
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs) 
 include $(PGXS)

3、创建sql文件
因为我们的功能C函数中实现,所以这里创建language是C的函数。

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION base16" to load this file. \quit
CREATE FUNCTION base16_encode(integer) RETURNS text
AS '$libdir/base16'
LANGUAGE C IMMUTABLE STRICT;

4、创建C函数
接着我们要创建C函数来实现我们需要实现的功能了,内容如下:

#include "postgres.h"
#include "fmgr.h"
#include "utils/builtins.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(base16_encode);
Datum
base16_encode(PG_FUNCTION_ARGS)
{
    int32 arg = PG_GETARG_INT32(0);
    if (arg < 0)
        ereport(ERROR,
            (
             errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
             errmsg("negative values are not allowed"),
             errdetail("value %d is negative", arg),
             errhint("make it positive")
            )
        );
    char base16[16] = "0123456789ABCDEF";

    /* max 6 char + '\0' */
    char *buffer = palloc(7 * sizeof(char));
    unsigned int offset = sizeof(buffer);
    buffer[--offset] = '\0';

    do {
        buffer[--offset] = base16[arg % 16];
    } while (arg /= 16);


    PG_RETURN_TEXT_P(cstring_to_text(&buffer[offset]));
}

#include“ postgres.h”包括与Postgres接口所需的大多数基本内容。此行需要包含在每个声明Postgres函数的C文件中。

#include“ fmgr.h”包含需要使用PG_GETARG_XXX和PG_RETURN_XXX宏。

#include“ utils / builtins.h”定义了Postgres内置数据类型的某些操作。

PG_MODULE_MAGIC是为了确保动态载入对象文件不会被载入到一个不兼容的服务器, PostgreSQL会检查该文件是否包含一个 带有合适内容的“magic block”。

Datum是每个C语言Postgres函数的返回类型,可以是任何数据类型。

5、创建测试模块
通过前面的例子,我们知道了需要一个测试模块用来检验插件能否正常使用。
–创建sql文件夹,在其目录下创建测试sql文件

pg12@oracle-> makir -p sql/
pg12@oracle-> vi base16_test.sql 
CREATE EXTENSION base16;
SELECT base16_encode(0);
SELECT base16_encode(1);
SELECT base16_encode(10);
SELECT base16_encode(35);
SELECT base16_encode(16);
SELECT base16_encode(123456789);

然后我们还需要创建results和expected两个目录,接着就可以进行测试了:
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 base16_test     
  sing 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 base16_test                  ... ok            6 ms

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

6、安装插件
编译安装
pg12@oracle-> make&make install
[1] 21993
/bin/mkdir -p ‘/home/pg12/pgsql12.4/share/extension’
make: Nothing to be done for `all’.
/bin/mkdir -p ‘/home/pg12/pgsql12.4/share/extension’
/bin/mkdir -p ‘/home/pg12/pgsql12.4/lib’
/bin/install -c -m 644 .//base16.control ‘/home/pg12/pgsql12.4/share/extension/’
/bin/install -c -m 644 .//base16–0.0.1.sql ‘/home/pg12/pgsql12.4/share/extension/’
/bin/install -c -m 755 base16.so ‘/home/pg12/pgsql12.4/lib/’
[1]+ Done make
在数据库中创建插件

bill=# create extension base16 ;
CREATE EXTENSION
bill=# \dx+ base16 
  Objects in extension "base16"
       Object description        
---------------------------------
 function base16_encode(integer)
(1 row)

7、验证是否可用

bill=# select base16_encode(16);
 base16_encode 
---------------
 10
(1 row)
bill=# select base16_encode(0);  
 base16_encode 
---------------
 0
(1 row)
bill=# select base16_encode(-1);
ERROR:  negative values are not allowed
DETAIL:  value -1 is negative
HINT:  make it positive

可以正常使用!

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

猜你喜欢

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