#author("2017-08-17T20:20:04+09:00","default:haikikyou","haikikyou")
#author("2017-08-17T20:22:09+09:00","default:haikikyou","haikikyou")
[[PostgreSQL/開発/フック]]

#contents

* フック [#a19d1805]

|~Hookインターフェース|~説明|h
|void ExplainOneQuery_hook(Query *query, IntoClause *into, ExplainState *es, const char *queryString, ParamListInfo params)|Explainコマンド実行時に呼ばれる。このプラグインでフックが定義されている場合は、プラグインに制御が渡される。|
|char* explain_get_index_name_hook(Oid indexId)|Explainコマンドでインデックス名を取得する関数の中で呼ばれる。プラグインはフックを利用してインデックス名を制御することができる。|


&size(12){&color(white,orange){ 参考 };}; [[commands/explain.c>https://doxygen.postgresql.org/explain_8c.html]] - &size(11){&color(gray){on [[doxygen.postgresql.org>https://doxygen.postgresql.org]]};};
* サンプル [#v8fbedc1]

&size(12){&color(white,#00afcc){ サンプル };};
&size(12){&color(white,#800080){ 実験 };};

''myext.c''

#geshi(c){{{
#include "postgres.h"
#include "fmgr.h"
#include "commands/explain.h"
#include "lib/stringinfo.h"
#include "tcop/tcopprot.h"

PG_MODULE_MAGIC;

extern void _PG_init(void);


extern ExplainOneQuery_hook_type ExplainOneQuery_hook;
extern explain_get_index_name_hook_type explain_get_index_name_hook;


static void my_ExplainOneQuery_hook(Query *query,
                                    IntoClause *into,
                                    ExplainState *es,
                                    const char *queryString,
                                    ParamListInfo params);

static const char* my_explain_get_index_name(Oid indexId);

// フックの初期化
void _PG_init(void)
{
    ExplainOneQuery_hook = my_ExplainOneQuery_hook;
    explain_get_index_name_hook = my_explain_get_index_name;
}

// ExplainOneQuery_hook
static void my_ExplainOneQuery_hook(Query *query,
                                    IntoClause *into,
                                    ExplainState *es,
                                    const char *queryString,
                                    ParamListInfo params)
{
    PlannedStmt *plan;
    instr_time	planstart, planduration;

    elog(INFO, "*** my_ExplainOneQuery_hook ***");
    appendStringInfo(es->str, "%s\n\n", "[Explain by my_ExplainOneQuery_hook]");

    
    INSTR_TIME_SET_CURRENT(planstart);

    plan = pg_plan_query(query, into ? 0 : CURSOR_OPT_PARALLEL_OK, params);

    INSTR_TIME_SET_CURRENT(planduration);
    INSTR_TIME_SUBTRACT(planduration, planstart);
    
    ExplainOnePlan(plan, into, es, queryString, params, &planduration);
}

// explain_get_index_name_hook
static const char * my_explain_get_index_name(Oid indexId)
{
    // 適当に固定値を返してみる
    return "MyIndex";
}
}}}

''postgresql.conf''

#geshi{{{
shared_preload_libraries = 'my ext'
}}}

''実行例''

#geshi(sql){{{
postgres=# explain select id, name from foo where id = 5 order by id desc;
INFO:  *** my_ExplainOneQuery_hook ***
                             QUERY PLAN                             
--------------------------------------------------------------------
 [Explain by my_ExplainOneQuery_hook]
 
 Index Scan using MyIndex on foo  (cost=0.28..8.29 rows=1 width=10)
   Index Cond: (id = 5)
(4 rows)
}}}

* 参考リンク [#qa8d09f7]

- [[commands/explain.c>https://doxygen.postgresql.org/explain_8c.html]] - &size(11){&color(gray){on [[doxygen.postgresql.org>https://doxygen.postgresql.org]]};};
* コメント [#vd0ac8e1]

#comment

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