概要
PostgreSQL從設計上是可擴展的,從用戶的角度可以通過四種方式對PostgresSQL進行擴展
- query language functions (functions written in SQL)
- procedural language functions (functions written in, for example, PL/pgSQL or PL/Tcl)
- internal functions
- C-language functions
本文重點介紹C-language functions,即函數通過contrib模塊進行擴展。
- 用戶定義函數簡介
用戶定義函數(User-defined functions),可以是使用C(或者與C兼容的開發語言,比如C++)編寫,這樣函數可以被編譯成動態庫,并被PostgreSQL服務進程加載。用戶定義函數與internal functions內部函數本質上是一樣的,只不過內部函數是需要重新編譯PostgresSQL內核的。編寫上也可以參考內部函數的源碼,可以給我們提供了豐富的例子。
實例
-
PostgreSQL開發環境搭建
參考上一篇文章源碼編譯安裝postgresql -
編寫代碼
1.進入postgres目錄,會看到contrib目錄,如下圖

[root@10 postgres]# cd contrib/
進入目錄后會看到好多文件夾,每一文件夾就代表一個用戶定義模塊,里面可能包括一個或多個用戶定義函數。
2.創建用戶定義函數的目錄
[root@10 contrib]# mkdir pginvoke
3.C范例程序pginvoke.c
#include "postgres.h"
#include "fmgr.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(pgEuropean);
Datum pgEuropean(PG_FUNCTION_ARGS)
{
float ret,a,b;
a=PG_GETARG_FLOAT4(0);
b=PG_GETARG_FLOAT4(1);
ret = a / b;
PG_RETURN_FLOAT4(ret);
}
4.編寫sql文件pginvoke–1.0.sql
/* contrib/pginvoke/pginvoke--1.0.sql */
--complain if script is sourced in psql rather than via ALTER EXTENSION
\echo Use "CRAETE EXTENSION test_tabble" to load this file. \quit
CREATE TABLE pg_invoke(para1 float4,para12 float4, ret float);/* 創建一個表格 */
CREATE FUNCTION pgEuropean(float4,float4)/* 創建一個函數 */
RETURNS float4
AS 'MODULE_PATHNAME' , 'pgEuropean'
LANGUAGE C STRICT PARALLEL RESTRICTED;
5.編寫控制文件pginvoke.control
# pginvoke extension
comment = 'only pginvoke publication'
default_version = '1.0'
module_pathname = '$libdir/pginvoke'
relocatable = true
6.編寫Makefile
# contrib/pginvoke/Makefile
MODULES = pginvoke
EXTENSION = pginvoke
DATA = pginvoke--1.0.sql
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/pginvoke
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
編譯
1.完成后目錄結構如下
[root@10 pginvoke]# pwd [root@10 pginvoke]# pwd /root/git/postgres/contrib/pginvoke [root@10 pginvoke]# ll total 16 -rw-r--r-- 1 root root 334 Feb 17 20:52 Makefile -rw-r--r-- 1 root root 296 Feb 17 20:51 pginvoke--1.0.sql -rw-r--r-- 1 root root 265 Feb 17 20:50 pginvoke.c -rw-r--r-- 1 root root 136 Feb 17 20:51 pginvoke.control
2.在上級目錄下修改Makefile
[root@10 pginvoke]# cd ../
[root@10 contrib]# pwd
/root/git/postgres/contrib
[root@10 contrib]# vi Makefile
###
51 unaccent \
52 vacuumlo \
53 test \
54 pginvoke
3.編譯
[root@10 contrib]# cd /root/git/postgres/contrib/ [root@10 contrib]# make ..... [root@10 contrib]# cd pginvoke/ [root@10 pginvoke]# pwd /root/git/postgres/contrib/pginvoke [root@10 pginvoke]# ll total 36 -rw-r--r-- 1 root root 334 Feb 17 21:11 Makefile -rw-r--r-- 1 root root 381 Feb 17 21:11 pginvoke--1.0.sql -rw-r--r-- 1 root root 267 Feb 17 21:12 pginvoke.c -rw-r--r-- 1 root root 144 Feb 17 21:12 pginvoke.control -rw-r--r-- 1 root root 1800 Feb 17 21:12 pginvoke.o -rwxr-xr-x 1 root root 16320 Feb 17 21:12 pginvoke.so
可以看到在pginvoke目錄下回生成pginvoke.so
安裝
1.自動安裝
直接執行make install
2.手動安裝
copy 下面3個文件到postgres的安裝目錄
cp pginvoke.control /usr/local/pgsql/share/extension cp pginvoke--1.0.sql /usr/local/pgsql/share/extension/ cp pginvoke.so '/usr/local/pgsql/lib/
驗證
1.查看已安裝的用戶定義函數,目前并沒有我們創建的函數。
su[root@10 ~]# su - postgres Last login: Thu Feb 17 15:21:04 CST 2022 from 10.0.2.2 on pts/1 [postgres@10 ~]$ psql psql (15devel) Type "help" for help. postgres=# \d List of relations Schema | Name | Type | Owner --------+-------------------------+-------+---------- public | pg_stat_statements | view | postgres public | pg_stat_statements_info | view | postgres public | test_table | table | postgres (3 rows)
2.查看可安裝的函數,可以看到pginvoke
postgres=# select name from pg_available_extensions; name -------------------- plpgsql ..... pg_trgm pginvoke (44 rows) postgres=#
3.創建擴展模塊pginvoke
postgres=# create extension pginvoke;
CREATE EXTENSION
4.再次查看已安裝模塊

已經創建成功。
5.查看函數創建腳本
postgres=# \sf
function name is required
postgres=# \sf pgEuropean
CREATE OR REPLACE FUNCTION public.pgeuropean(real, real)
RETURNS real
LANGUAGE c
PARALLEL RESTRICTED STRICT
AS '$libdir/pginvoke', $function$pgEuropean$function$
6.調用函數
postgres=# select pgEuropean(10.0,3.0);
pgeuropean
------------
3.3333333
(1 row)
7.移除用戶擴展函數
postgres=# drop extension pginvoke;
DROP EXTENSION
postgres=# \d
List of relations
Schema | Name | Type | Owner
--------+-------------------------+-------+----------
public | pg_stat_statements | view | postgres
public | pg_stat_statements_info | view | postgres
public | test_table | table | postgres
(3 rows)
最后修改時間:2022-04-09 10:16:14
「喜歡這篇文章,您的關注和贊賞是給作者最好的鼓勵」
關注作者
【版權聲明】本文為墨天輪用戶原創內容,轉載時必須標注文章的來源(墨天輪),文章鏈接,文章作者等基本信息,否則作者和墨天輪有權追究責任。如果您發現墨天輪中有涉嫌抄襲或者侵權的內容,歡迎發送郵件至:contact@modb.pro進行舉報,并提供相關證據,一經查實,墨天輪將立刻刪除相關內容。




