フック †
Hookインターフェース | 説明 |
---|---|
void ExplainOneQuery_hook(Query *query, IntoClause *into, ExplainState *es, const char *queryString, ParamListInfo params) | Explainコマンド実行時に呼ばれる。このプラグインでフックが定義されている場合は、プラグインに制御が渡される。 |
char* explain_get_index_name_hook(Oid indexId) | Explainコマンドでインデックス名を取得する関数の中で呼ばれる。プラグインはフックを利用してインデックス名を制御することができる。 |
参考 commands/explain.c - on doxygen.postgresql.org
サンプル †
実験
myext.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
shared_preload_libraries = 'my ext'
実行例
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)