- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- PostgreSQL/解析/拡張機能の構築基盤 へ行く。
- 1 (2017-06-24 (土) 00:33:32)
- 2 (2017-06-25 (日) 23:07:52)
- 3 (2017-06-26 (月) 23:08:39)
- 4 (2017-06-28 (水) 23:25:26)
- 5 (2017-07-01 (土) 01:18:40)
- 6 (2017-07-02 (日) 20:09:39)
- 7 (2017-07-11 (火) 20:01:26)
- 8 (2017-07-11 (火) 22:58:56)
- 9 (2017-07-11 (火) 23:57:22)
- 10 (2017-07-12 (水) 23:31:04)
- 11 (2017-07-18 (火) 21:51:44)
- 12 (2018-02-04 (日) 22:32:14)
概要 †
ここでは,拡張機能の開発で必要となる知識について整理する。
具体的には,拡張機能のディレクトリ構造,ビルドスクリプト,制御ファイルについて記述する。
拡張機能のディレクトリ構造 †
CREATE EXTENSIONとしてインストールされる拡張機能のディレクトリ構造は,以下のようになっている(ここでは,拡張機能を「myext」として説明を進める)。
myext |- myext.control |- myext--xx.sql |- Makefile |- myext.c
- myext.control
- CREATE EXTENSIONやALTER EXTENSIONが実行されたときに読み込まれる。
- myext--xx.sql
- CREATE EXTENSIONやALTER EXTENSIONが実行されたときに実行されるターゲットバージョンのスクリプト。xxからyyへのアップデートに段階的な更新が必要な場合は,myext--xx--yy.sqlのようにする。
- Makefile
- ビルド定義
- myex.c
- ソースコード。もちろん複数のソースコードのコンパイル&リンクも問題ない。
サンプル1 trueを返すだけのmyext関数の作成
各ファイルの内容はざっと最小限で書いて以下のような感じになる。各ファイルの定義内容については後述する。
Makefile
MODULES = myext EXTENSION = myext DATA = myext--1.0.sql PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS)
myext--1.0.sql
\echo USE "CREATE EXTENSION myext" TO LOAD this file. \quit CREATE OR REPLACE FUNCTION myext() RETURNS BOOL AS 'MODULE_PATHNAME' LANGUAGE C STRICT;
myext.c
#include "postgres.h" #include "fmgr.h" #include "funcapi.h" PG_MODULE_MAGIC; PG_FUNCTION_INFO_V1(myext); Datum myext(PG_FUNCTION_ARGS) { PG_RETURN_BOOL(true); // ただtrueを返すだけの関数 }
この内容で作成される拡張関数だが,以下のような結果を返すものである。
postgres=# select myext(); myext ------- t (1 row)
Makefile †
制御ファイル(.control) †
CreateExtension実行の流れ †
CREATE EXTENSION呼び出しの流れをデバッガのスタックトレースを実行し俯瞰する。
まずは,以下のコマンドを実行してみる。
# myext.soとmyext2.soがターゲットリストに加わる MODULES = myext myext2
最終的にはpg_dlsymが呼ばれるだろうと想定しブレークポイントを貼っておく。以下,コマンドを実行しブレークポイントで中断させた時のスタックトレースである。
(lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 24.1 * frame #0: 0x000000010edba000 postgres`pg_dlsym(...) at dynloader.c:38 <-- 最終的にシステムコールで共有オブジェクトの読み込み frame #1: 0x000000010f0083bd postgres`internal_load_library(...) at dfmgr.c:240 <-- ライブラリのロード frame #2: 0x000000010f007d7f postgres`load_external_function(...) at dfmgr.c:105 frame #3: 0x000000010eb8f532 postgres`fmgr_c_validator(...) at pg_proc.c:823 frame #4: 0x000000010f00c143 postgres`OidFunctionCall1Coll(...) at fmgr.c:1596 frame #5: 0x000000010eb8f0bb postgres`ProcedureCreate(...) at pg_proc.c:726 frame #6: 0x000000010ec45204 postgres`CreateFunction(...) at functioncmds.c:1048 frame #7: 0x000000010ee7520e postgres`ProcessUtilitySlow(...) at utility.c:1361 frame #8: 0x000000010ee73878 postgres`standard_ProcessUtility(...) at utility.c:892 frame #9: 0x000000010ee7299d postgres`ProcessUtility(...) at utility.c:334 frame #10: 0x000000010ec3f486 postgres`execute_sql_string(...) at extension.c:744 <-- インストールスクリプト実行 frame #11: 0x000000010ec39764 postgres`execute_extension_script(...) at extension.c:904 frame #12: 0x000000010ec386af postgres`CreateExtension(...) at extension.c:1461 <-- ここでCREATE EXTENSIONコマンド実行 frame #13: 0x000000010ee74cb9 postgres`ProcessUtilitySlow(...) at utility.c:1281 frame #14: 0x000000010ee73878 postgres`standard_ProcessUtility(...) at utility.c:892 frame #15: 0x000000010ee7299d postgres`ProcessUtility(...) at utility.c:334 frame #16: 0x000000010ee72318 postgres`PortalRunUtility(...) at pquery.c:1183 frame #17: 0x000000010ee7155c postgres`PortalRunMulti(...) at pquery.c:1314 frame #18: 0x000000010ee70b6d postgres`PortalRun(...) at pquery.c:812 frame #19: 0x000000010ee6c527 postgres`exec_simple_query(...) at postgres.c:1104 frame #20: 0x000000010ee6b730 postgres`PostgresMain(...) at postgres.c:4045 frame #21: 0x000000010edd45e2 postgres`BackendRun(...) at postmaster.c:4253 frame #22: 0x000000010edd389d postgres`BackendStartup(...) at postmaster.c:3927 frame #23: 0x000000010edd2965 postgres`ServerLoop at postmaster.c:1698 frame #24: 0x000000010edd02d6 postgres`PostmasterMain(...) at postmaster.c:1306 frame #25: 0x000000010ed1097f postgres`main(...) at main.c:228 frame #26: 0x00007fffdb4e0235 libdyld.dylib`start + 1 frame #27: 0x00007fffdb4e0235 libdyld.dylib`start + 1
参考リンク †
- extension.c - on doxygen.postgresql.org
- CreateExtension() - on doxygen.postgresql.org
- AlterExtension() - on doxygen.postgresql.org
- parse_extension_control_file() - on doxygen.postgresql.org
- PostgreSQL 9.5.4文書 35.15. 関連するオブジェクトを拡張としてパッケージ化 - PostgreSQL 9.5.4文書
- PostgreSQL 9.5.4文書 35.16. 拡張構築基盤 - PostgreSQL 9.5.4文書