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/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM