第一步 實現(xiàn)函數(shù)
增加的函數(shù)都放在src/backend/utils目錄下霎挟,我要實現(xiàn)的函數(shù)是從服務(wù)器查詢道批,并返回給調(diào)用者。
C函數(shù)原型:
char * sys_test(const uint32 id, const uint32 age)
開發(fā)者需要根據(jù)自己的需要纳像,選擇目錄和文件:
我需要實現(xiàn)的功能在現(xiàn)有的文件中不存在相關(guān)性拙泽,我在adt目錄下自己創(chuàng)建了一個文件:test.c淌山,文件內(nèi)容如下:
#include "postgres.h"
#include <sys/file.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include "access/heapam.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "postmaster/syslogger.h"
#include "storage/fd.h"
#include "utils/builtins.h"
/*
* Read a page, returning it as binary
*/
Datum
sys_test(PG_FUNCTION_ARGS)
{
uint32 id = PG_GETARG_INT32(0);
uint32 age = PG_GETARG_INT32(1);
printf("111111111111111111111\n");
strcpy(buf, "xxxxxxxxxxxxxxxxxx");
SET_VARSIZE(buf, nbytes + VARHDRSZ);
PG_RETURN_TEXT_P(buf);
}
實際功能還需要實現(xiàn),我就打個樣奔滑。
修改Makefile艾岂,使其可以被編譯。打開文件adt/Makefile朋其,增加文件test
如果你實現(xiàn)的函數(shù)王浴,在現(xiàn)有的文件中實現(xiàn),就不需要修改Makefile梅猿。
第二步 支持外部訪問
打開文件:src/include/utils/builtins.h氓辣,在文件尾部增加自己的函數(shù)。
extern Datum sys_test(PG_FUNCTION_ARGS);
第三步 注冊到名字空間
打開:src/include/catalog/pg_proc.h袱蚓,找一個合適的位置增加自己的函數(shù)定義:
DATA(insert OID = 13624 ( sys_test PGNSP 0 PGUID 12 t f f f t f v 2 17 17 i f i f f "23 23" _null_ _null_ _null_ _null_ _null_ _null_ sys_read_page 2D _null_ ));
DESCR("sys_test");
其中的OID钞啸,不可重復(fù),自己YY喇潘。
在模板庫中插入記錄体斩,使任何庫一創(chuàng)建就有。對于系統(tǒng)表來說颖低,在它的頭文件里有對這個系統(tǒng)表的詳細定義說明絮吵,在這個頭文件下面能按格式預(yù)置一些記錄,這些記錄在initdb時會插入到模板庫的對應(yīng)系統(tǒng)表中忱屑。具體來說蹬敲,這些預(yù)置的記錄,在編譯過程中莺戒,會被perl腳本轉(zhuǎn)換到postgres.bki中伴嗡,這個bki文件在安裝目錄的share文件夾,當initdb時从铲,會加載這個bki并解析成一條條sql運行瘪校,創(chuàng)建出一個個系統(tǒng)表,插入初始記錄食店,把初始的信息準備好渣淤。有興趣者可以看看initdb模塊中 bootstrap_template1函數(shù)赏寇,初始化模塊時第1件事就是加載postgres.bki文件翻譯解析執(zhí)行吉嫩。
第四步 編譯和驗證函數(shù)可用
重新編譯代碼价认,使其修改重新編譯。
make && make install
這種函數(shù)如果修改了pg_proc.h就必須要重新初始化數(shù)據(jù)庫自娩,不然不會生效:
./initdb ../data
在bin目錄下啟動服務(wù)進程:
./postgres
使用isql連接服務(wù)器:
./psql postgres
查詢函數(shù)定義:
postgres-# \df+ SYS_TEST
功能列表
Schema | Name | Result data type | Argument data types | Owner | Language | Source code | Description
-------------+---------------+------------------+----------------------+--------+----------+---------------+-------------
SYS_CATALOG | SYS_TEST | BYTEA | TEXT, BIGINT, BIGINT | SYSTEM | INTERNAL | sys_test |
我們仔細看用踩,函數(shù)參數(shù)“TEXT, BIGINT, BIGINT”,其實是錯誤的忙迁,與我們的函數(shù)定義:
char * sys_test(const uint32 id, const uint32 age)
是不一樣的脐彩,參數(shù)列表錯誤,下面我們要找到原因姊扔,并修改惠奸。
關(guān)于參數(shù)設(shè)置可以參考:https://blog.csdn.net/postgres20/article/details/53446231
在pg_proc.h中插入的記錄是什么含義?
以第一行為例詳細說明如下:
DATA(insert OID = 13624 ( sys_read_page PGNSP 0 PGUID 12 t f f f t f v 2 17 17 i f i f f "25 20 20" null null null null null null sys_read_page 2D null ));
13624–OID使用內(nèi)核中未使用的OID即可(src/include/catalog下unused_oids恰梢,可以顯示未使用的oid) postgres內(nèi)部預(yù)留了1W多個oid給系統(tǒng)用佛南,選一個沒有的就行,如果不知道哪些可用嵌言,在\src\include\catalog\ 下有個腳本文件unused_oids嗅回,運行一下就能找出哪些oid可用,但要這是一個linux腳本摧茴,需要在linux下運行绵载。
PGNSP–函數(shù)所屬的名字空間的OID,PGNSP即pg_catalog(oid=11)苛白,內(nèi)置函數(shù)添加此值固定
PGUID–函數(shù)的擁有者OID娃豹,PGUID及initdb時指定用戶(oid=10),內(nèi)置函數(shù)添加此值固定
12–實現(xiàn)語言或該函數(shù)的調(diào)用接口购裙,內(nèi)置函數(shù)使用12(internal)懂版,SQL用14
t–函數(shù)是否為一個聚集函數(shù)
f–函數(shù)是否為一個窗口函數(shù)
f–函數(shù)是一個安全性定義者(即,一個”setuid”函數(shù))
f–該函數(shù)沒有副作用缓窜。除了通過返回值定续,沒有關(guān)于參數(shù)的信息被傳播。任何會拋出基于其參數(shù)值的錯誤信息的函數(shù)都不是泄露驗證的禾锤。
t–當任意調(diào)用函數(shù)為空時私股,函數(shù)是否會返回空值。在那種情況下函數(shù)實際上根本不會被調(diào)用恩掷。非”strict”函數(shù)必須準備好處理空值輸入倡鲸。
f–函數(shù)是否返回一個集合(即,指定數(shù)據(jù)類型的多個值)
v–未知
2–輸入?yún)?shù)的個數(shù)黄娘,對應(yīng)后面的""25 20 20""兩個參數(shù)峭状,明顯我們這里寫錯了克滴,找到了原因,我們修改為我們對應(yīng)的參數(shù)個數(shù)和類型:
"25 20 20" 改為 “23 23”,
23表示int4优床,繼續(xù)往下看劝赔,有說明。
17–具有默認值的參數(shù)個數(shù)
17–返回值的數(shù)據(jù)類型
“25 20 20”–函數(shù)參數(shù)的數(shù)據(jù)類型的數(shù)組胆敞,這只包括輸入?yún)?shù)(含INOUT和VARIADIC參數(shù))着帽,因此也表現(xiàn)了函數(shù)的調(diào)用特征 重載函數(shù)也憑這區(qū)別,如果有多個移层,參數(shù)肯定不同仍翰,這個不同即可以是數(shù)量不同,也可以是類型不同观话,25 20 20 就是代表類型予借,如下:
TEST=# select oid,typname from pg_type where oid in (1082,23,1114,1184,17,25);
OID | TYPNAME
------+-------------
17 | BYTEA
23 | INT4
25 | TEXT
1082 | DATE
1114 | TIMESTAMP
1184 | TIMESTAMPTZ
null–函數(shù)參數(shù)的數(shù)據(jù)類型的數(shù)組,這包括所有參數(shù)(含OUT和INOUT參數(shù))频蛔。但是灵迫,如果所有參數(shù)都是IN參數(shù),這個域?qū)榭彰毖薄W⒁庀聵耸菑?開始 龟再,然而由于歷史原因proargtypes的下標是從0開始
null–函數(shù)參數(shù)的模式的數(shù)組。編碼為: i表示IN參數(shù) 尼变, o表示OUT參數(shù)利凑, b表示INOUT參數(shù), v表示VARIADIC參數(shù)嫌术, t表示TABLE參數(shù)哀澈。 如果所有的參數(shù)都是IN參數(shù),這個域為空度气。注意這里的下標對應(yīng)著proallargtypes而不是proargtypes中的位置
null–函數(shù)參數(shù)的名字的數(shù)組割按。沒有名字的參數(shù)在數(shù)組中設(shè)置為空字符串。如果沒有一個參數(shù)有名字磷籍,這個域為空适荣。注意這里的下標對應(yīng)著proallargtypes而不是proargtypes中的位置
null–默認值的表達式樹(按照nodeToString()的表現(xiàn)方式)。這是一個pronargdefaults元素的列表院领,對應(yīng)于最后N個input參數(shù)(即最后N個proargtypes位置)弛矛。如果沒有一個參數(shù)具有默認值,這個域為空
null–數(shù)據(jù)類型OID為了應(yīng)用轉(zhuǎn)換
我們再次來看看比然,是不是都對了
postgres=# \df sys_test
功能列表
Schema | Name | Result data type | Argument data types
-------------+---------------+------------------+---------------------
SYS_CATALOG | SYS_TEST | BYTEA | INTEGER, INTEGER
第五步 調(diào)用函數(shù)
postgres=# select SYS_TEST(1,2);
其他可用輸出參數(shù):
信息報告
\d [NAME] 描述表, 索引, 序列, 或者視圖
\d{t|i|s|v|S} [PATTERN] (附加 "+" 獲取更多信息)
列出表/索引/序列/視圖/系統(tǒng)表
\da [PATTERN] 列出聚集函數(shù)
\db [PATTERN] 列出表空間(附加 "+" 獲取更多信息)
\dc [PATTERN] 列出編碼轉(zhuǎn)換
\dC 列出定義的轉(zhuǎn)換
\dd [PATTERN] 列出對象的注釋
\dD [PATTERN] 列出域
\df [PATTERN] 列出函數(shù)(附加 "+" 獲得更多信息)
\dF [PATTERN] 列出全文搜索配置(附加 "+" 獲得更多信息)
\dFd [PATTERN] 列出全文搜索詞典(附加 "+" 獲得更多信息)
\dFt [PATTERN] 列出全文搜索模板
\dFp [PATTERN] 列出全文搜索分析器(附加 "+" 獲得更多信息)
\dm[S+] [PATTERN] list materialized views
\dn [PATTERN] 列出模式(附加 "+" 獲得更多信息)
\do [NAME] 列出操作符
\dp [PATTERN] 列出表, 視圖, 及序列的訪問權(quán)限
\dP [PATTERN] 列出包(附加 "+" 獲得更多信息)
\dr [PATTERN] 列出角色
\dT [PATTERN] 列出數(shù)據(jù)類型(附加 "+" 獲得更多信息)
\du [PATTERN] 列出用戶
\l 列出所有數(shù)據(jù)庫(附加 "+" 獲得更多信息)
\ll [PATTERN] 列出鎖
\llc 列出鎖總數(shù)
\lx 列出xid最大值
\lredolog 列出當前的重做日志
\lc [PATTERN] 列出所有連接
\lac [PATTERN] 列出活動連接
\lfc [PATTERN] 列出空閑連接
\lwc [PATTERN] 列出等待連接
\lmc 列出最大連接數(shù)
\lstatdb [PATTERN] 列出數(shù)據(jù)庫統(tǒng)計信息
\lstatidx [PATTERN] 列出索引統(tǒng)計信息
\lstatseq [PATTERN] 列出序列統(tǒng)計信息
\lstattable [PATTERN] 列出表格統(tǒng)計信息
發(fā)現(xiàn)更多寶藏
我在喜馬拉雅上分享聲音
《PostgreSQL數(shù)據(jù)庫內(nèi)核分析》丈氓,點開鏈接可以聽聽,有點意思。
《數(shù)據(jù)庫系統(tǒng)概論(第4版)》万俗,點開鏈接可以聽聽湾笛,有點意思。
其他相關(guān)文章分享列表:
第 23 課 PostgreSQL 創(chuàng)建自己的數(shù)據(jù)庫嚎研、模式、用戶
第 22 課 PostgreSQL 控制文件
第 21 課 PostgreSQL 日志系統(tǒng)
第 16 課 查詢過程源碼分析
第 15 課 PostgreSQL 系統(tǒng)參數(shù)配置
第 14 課 PostgreSQL 數(shù)據(jù)存儲結(jié)構(gòu)
第 13 課 PostgreSQL 存儲之Page(頁面)源碼分析
第 12 課 PostgreSQL 認證方式
第 11 課 PostgreSQL 增加一個內(nèi)核C函數(shù)
第 10 課 PostgreSQL 在內(nèi)核增加一個配置參數(shù)
第 09 課 PostgreSQL 4種進程啟動方式
第 08 課 PostgreSQL 事務(wù)介紹
第 07 課 PostgreSQL 數(shù)據(jù)庫课竣、模式嘉赎、表置媳、空間于樟、用戶間的關(guān)系
第 06 課 PostgreSQL 系統(tǒng)表介紹
第 05 課 PostgreSQL 編譯源代碼進行開發(fā)
第 04 課 PostgreSQL 安裝最新的版本
第 03 課 PostgreSQL 代碼結(jié)構(gòu)
第 02 課 PostgreSQL 的特性、應(yīng)用拇囊、安裝
第 01 課 PostgreSQL 簡介及發(fā)展歷程
上面文章都在專輯中:PostgreSQL專輯鏈接迂曲,點我查看
如果有用,可以收藏這篇文件寥袭,隨時在更新....
更多交流加群: PostgreSQL內(nèi)核開發(fā)群 876673220
親路捧,記得點贊、留言传黄、打賞額=苌ā!膘掰!