第 11 課 PostgreSQL 增加一個內(nèi)核C函數(shù)

第一步 實現(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ù)自己的需要纳像,選擇目錄和文件:


image.png

我需要實現(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版)》万俗,點開鏈接可以聽聽湾笛,有點意思。

更多IT有聲課程闰歪,點我發(fā)現(xiàn)更多

第 0 課 PostgreSQL 系列文章列表

其他相關(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

親路捧,記得點贊、留言传黄、打賞額=苌ā!膘掰!

上一課
下一課

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末章姓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子识埋,更是在濱河造成了極大的恐慌凡伊,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窒舟,死亡現(xiàn)場離奇詭異系忙,居然都是意外死亡,警方通過查閱死者的電腦和手機惠豺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門银还,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洁墙,你說我怎么就攤上這事蛹疯。” “怎么了扫俺?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵苍苞,是天一觀的道長。 經(jīng)常有香客問我,道長羹呵,這世上最難降的妖魔是什么骂际? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮冈欢,結(jié)果婚禮上歉铝,老公的妹妹穿的比我還像新娘。我一直安慰自己凑耻,他們只是感情好太示,可當我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著香浩,像睡著了一般类缤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上邻吭,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天餐弱,我揣著相機與錄音,去河邊找鬼囱晴。 笑死膏蚓,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的畸写。 我是一名探鬼主播驮瞧,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼枯芬!你這毒婦竟也來了论笔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤破停,失蹤者是張志新(化名)和其女友劉穎翅楼,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體真慢,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡毅臊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了黑界。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片管嬉。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖朗鸠,靈堂內(nèi)的尸體忽然破棺而出蚯撩,到底是詐尸還是另有隱情,我是刑警寧澤烛占,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布胎挎,位于F島的核電站沟启,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏犹菇。R本人自食惡果不足惜德迹,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望揭芍。 院中可真熱鬧胳搞,春花似錦、人聲如沸称杨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姑原。三九已至悬而,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間页衙,已是汗流浹背摊滔。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工店乐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人眨八。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓左电,卻偏偏與公主長得像廉侧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子篓足,可洞房花燭夜當晚...
    茶點故事閱讀 45,747評論 2 361