您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)PostgreSQL中怎么載入外部C語(yǔ)言函數(shù),文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
quanzl-mac:postgresql.builtin_pool quanzl$ nm lib/plpgsql.so ... 0000000000007e10 T _pg_finfo_plpgsql_call_handler 000000000001c888 s _pg_finfo_plpgsql_call_handler.my_finfo ... 0000000000007e20 T _plpgsql_call_handler ...
這是怎么來(lái)的?直接看函數(shù)定義(src/pl/plpgsql/src/pl_handler.c):
... PG_FUNCTION_INFO_V1(plpgsql_call_handler); Datum plpgsql_call_handler(PG_FUNCTION_ARGS) { ...
所有外掛模塊中的函數(shù)都是這種形式定義,返回值必須是Datum,參數(shù)必須使用預(yù)處理符 PG_FUNCTION_ARGS。plpgsql_call_handler是定義在pg_language中的存儲(chǔ)過(guò)程處理入口,調(diào)用方式與可以在SQL中使用的函數(shù)有所不同,所以它直接使用return方式返回值。而一般的SQL函數(shù)比如earthdistance模塊中的geo_distance
... PG_FUNCTION_INFO_V1(geo_distance); Datum geo_distance(PG_FUNCTION_ARGS) { ... PG_RETURN_FLOAT8(result); }
SQL定義
CREATE FUNCTION geo_distance (point, point) RETURNS float8 LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE AS 'MODULE_PATHNAME';
它必須使用 PG_RETURN_xxx 系列預(yù)處理符來(lái)返回。
返回值的使用可以參考DirectFunctionCalln(n為數(shù)字,表是參數(shù)個(gè)數(shù))定義去理解,有必要的話另文再寫,這里簡(jiǎn)單一提,主要還是講預(yù)處理符PG_FUNCTION_INFO_V1,下邊是它的定義:
#define PG_FUNCTION_INFO_V1(funcname) \ extern Datum funcname(PG_FUNCTION_ARGS); \ extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \ const Pg_finfo_record * \ CppConcat(pg_finfo_,funcname) (void) \ { \ static const Pg_finfo_record my_finfo = { 1 }; \ return &my_finfo; \ } \ extern int no_such_variable
再看earthdistance.so的symbol:
0000000000000de0 T _geo_distance 0000000000000dd0 T _pg_finfo_geo_distance 0000000000000fb0 s _pg_finfo_geo_distance.my_finfo
CppConcat(pg_finfo_,funcname)新定義一個(gè)前綴 pg_finfo_ 的函數(shù),pg_finfo_geo_distance就是這么來(lái)的,它很簡(jiǎn)單,返回結(jié)構(gòu)體 Pg_finfo_record,其成員 api_version 為 1。
強(qiáng)大的PG已經(jīng)為今后擴(kuò)展做好準(zhǔn)備。
函數(shù)加載部分(src/backend/utils/fmgr/fmgr.c)的檢查 fetch_finfo_record:
const Pg_finfo_record *inforec; infofuncname = psprintf("pg_finfo_%s", funcname); /* Try to look up the info function */ infofunc = (PGFInfoFunction) lookup_external_function(filehandle, infofuncname); ... inforec = (*infofunc) (); ...
上述就是小編為大家分享的PostgreSQL中怎么載入外部C語(yǔ)言函數(shù)了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。