#author("2017-06-13T23:47:25+09:00","default:haikikyou","haikikyou")
[[PostgreSQL/開発]]

&size(12){&color(white,red){ ただいま作成中・・・ };};

#contents

* 概要 [#t03f8105]

- 関数マネージャと関数呼び出しインターフェースの定義ファイル

#ref(./fmgr_overview.png,70%)
* 定義 [#m6ff2469]

** 変数,エイリアス [#r6993c38]

** マクロ [#n3bffc31]

** 列挙型 [#jc93a4e3]

** 構造体 [#cb54ce43]

*** FmgrInfo [#dbdc9d3a]

|~番号|~データ型|~フィールド|~説明|h
|1|PGFunction|fn_addr|実行される関数のポインタ|
|2|Oid|fn_oid|関数のOID|
|3|short|fn_nargs|関数の引数の数|
|4|bool|fn_strict|関数がstrictモードが否か。&br;true:strictモード,false:strictモードでない|
|5|bool|fn_retset|setを返す関数か否か。&br;true:setを返す,false:setを返さない|
|6|unsigned char|fn_stats|関数が統計情報を収集するか。この値より大きな値の場合に収集する。&br;&size(12){&color(white,orange){ 参考 };}; [[enum TrackFunctionsLevel>https://doxygen.postgresql.org/pgstat_8h.html#a8674d83a2e7ca33c720348e4b328ab4c]] - on doxygen.postgresql.org|
|7|void*|fn_extra|関数で利用可能な領域|
|8|MemoryContext|fn_mcxt|fn_extraを格納するためのメモリコンテキスト|
|9|fmNodePtr|fn_expr|パースツリーのノード表現|

システムカタログの関数情報を保持する。

&size(12){&color(white,#00afcc){ サンプル };};
#geshi(c){{{
// 指定されたOIDの関数情報を取得する。
FmgrInfo *fmgr = palloc(sizeof(FmgrInfo));
fmgr_info((Oid)1396, fmgr); // abs(int64)の情報を構造体に格納する
}}}
*** FunctionCallInfoData [#vd0ca3c7]

|~番号|~データ型|~フィールド|~説明|h
|1|FmgrInfo*|flinfo|関数情報を保持する構造体のポインタ|
|2|fmNodePtr|context|関数呼び出しのコンテキスト。&br;例:TriggerData,AggState,WindowAggState|
|3|fmNodePtr|resultinfo|実行結果に関する情報。&br;例:ReturnSetInfo|
|4|Oid|fncollation|collation|
|5|bool|isnull|結果がNULLを返すか否か。&br;true:返す,false:返さない|
|6|short|nargs|関数の引数の数|
|7|Datum|arg[FUNC_MAX_ARGS]|引数|
|8|bool|argnull[FUNC_MAX_ARGS]|arg[i]がNULLであるか否か&br;true:NULL,false:NULLでない|

関数呼び出しに関する情報を保持する構造体。

&size(12){&color(white,orange){ 参考 };}; [[FunctionCallInfoData>https://doxygen.postgresql.org/structFunctionCallInfoData.html]] - on doxygen.postgresql.org

&size(12){&color(white,#00afcc){ サンプル };};
#geshi(c){{{
void test_invoke()
{
    Datum result;
    FunctionCallInfoData fcinfo;

    FmgrInfo *fmgr = palloc(sizeof(FmgrInfo));
    fmgr_info((Oid)1396, fmgr); // abs(int64);

    // Basic way
    int64 arg0 = -100;

    InitFunctionCallInfoData(fcinfo, fmgr, 1, 0, NULL, NULL);
    fcinfo.isnull = false;
    fcinfo.argnull[0] = false;
    fcinfo.arg[0] = Int64GetDatum(arg0);

    result = FunctionCallInvoke(&fcinfo);
    elog(INFO, "abs(-100) = %ld", DatumGetInt64(result));
}

/* Output is the following:
------------------------------
INFO:  abs(-100) = 100
*/
}}}


*** Pg_finfo_record [#jb9501fe]

|~番号|~データ型|~フィールド|~説明|h
|1|int|api_version|apiのバージョン|

関数インターフェースのバージョンを示す情報を格納する。独自の拡張機能や関数を作成するときに,以下のサンプルのようにマクロを使った際に展開され定義される。

&size(12){&color(white,#00afcc){ サンプル };};
#geshi(c){{{
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

PG_FUNCTION_INFO_V1(test_fdw_handler);
/* これは以下のように展開される
extern Datum test_fdw_handler(FunctionCallInfo fcinfo);
extern const Pg_finfo_record * pg_finfo_test_fdw_handler(void);
const Pg_finfo_record * pg_finfo_test_fdw_handler(void)
{
	static const Pg_finfo_record my_finfo = { 1 };
	return &my_finfo;
}
extern int no_such_variable;
/*
}}}
** 関数 [#ydff81f8]

*** fmgr_info [#v3a0be5f]

#geshi(c){{{
// 引数1:関数のOid
// 引数2:FmgrInfo構造体のポインタ
extern void fmgr_info(Oid functionId, FmgrInfo *finfo);
}}}

- 指定されたfunctionIdの関数情報を探索し,finfoに設定する。

&size(12){&color(white,orange){ 参考 };}; [[fmgr_info()>https://doxygen.postgresql.org/fmgr_8c.html#a4aaf89400b4741012e4ee1b715dae0e4]] - on doxygen.postgresql.org

&size(12){&color(white,#00afcc){ サンプル };};
#geshi(c){{{
FmgrInfo flinfo;
fmgr_info(functionId, &flinfo); // fill flinfo
}}}
*** fmgr_info_cxt [#pb3ac2bc]

#geshi(c){{{
// 引数1:関数のOid
// 引数2:FmgrInfo構造体のポインタ
// 引数3:fx_extraを使用する際のメモリコンテキスト
extern void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo,  MemoryContext mcxt);
}}}

- 指定されたfunctionIdの関数情報を探索し,finfoに設定する。
- fn_extraで使用されるスペースを指定されたメモリコンテキストから割り当てるよう設定する。
* サンプルプログラム [#xcd4fcab]

#geshi(c){{
// 関数呼び出しのサンプル
void test_func_invoke()
{
    FmgrInfo *fmgr = palloc(sizeof(FmgrInfo));
    FunctionCallInfoData fcinfo;

    // ここでは,サンプルのため決め打ちで関数のOidを指定している
    fmgr_info((Oid)1396, fmgr); // abs(int64); 
    int64 arg0 = -100; // 引数

    InitFunctionCallInfoData(fcinfo, fmgr, 1, 0, NULL, NULL);
    fcinfo.isnull = false;     // 結果はnullでない
    fcinfo.argnull[0] = false; // 引数なnullでない
    fcinfo.arg[0] = Int64GetDatum(arg0); // 引数を設定

    // 関数の実行 No.1) fmgr_infoで実際に呼び出される関数ポインタがfcinfoにセットされている
    Datum result = FunctionCallInvoke(&fcinfo);

    // 結果Datumから値を取り出す
    elog(INFO, "abs(-100) = %ld", DatumGetInt64(result));

    // 関数の実行 No.2) 上の手続きを簡略化してくれるもっと便利な関数を使って実行してみる
    FunctionCall1Coll(fmgr, 0, Int64GetDatum(arg0));
    result = FunctionCallInvoke(&fcinfo);
    elog(INFO, "abs(-100) = %ld", DatumGetInt64(result));

    // 関数の実行 No.3) 更に上の手続きをもっと簡略化してくれるもっと便利な関数を使って実行してみる
    result = OidFunctionCall1Coll(1396, 0, Int64GetDatum(arg0));
    elog(INFO, "abs(-100) = %ld", DatumGetInt64(result));
}

/* Output is the following:
------------------------------
INFO:  abs(-100) = 100
INFO:  abs(-100) = 100
INFO:  abs(-100) = 100
*/
}}
* 参考・関連 [#hbd36355]

- [[fmgr.h>https://doxygen.postgresql.org/fmgr_8h.html]] - on doxygen.postgresql.org
- [[fmgr.c>https://doxygen.postgresql.org/fmgr_8c.html]] - on doxygen.postgresql.org
- [[fmgrtab.h>https://doxygen.postgresql.org/fmgrtab_8h.html]] - on doxygen.postgresql.org
- [[CREATE FUNCTION>https://www.postgresql.jp/document/9.5/html/sql-createfunction.html]] - PostgreSQL 9.5文書
- [[49.37. pg_proc>https://www.postgresql.jp/document/9.5/html/catalog-pg-proc.html]] - PostgreSQL 9.5文書

&size(12){&color(white,orange){ 関連 };};

#related
* コメント [#cd6bf6cf]

#comment

トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
目次
ダブルクリックで閉じるTOP | 閉じる
GO TO TOP