PostgreSQL/開発

概要

ここでは,拡張機能の開発で必要となる知識について整理する。
具体的には,拡張機能のディレクトリ構造,ビルドスクリプト,制御ファイルについて記述する。

拡張機能のディレクトリ構造

CREATE EXTENSIONとしてインストールされる拡張機能のディレクトリ構造は,以下のようになっている(ここでは,拡張機能を「myext」として説明を進める)。

myext
    |- myext.control
    |- myext--xx.sql
    |- Makefile
    |- myext.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呼び出しの流れをデバッガのスタックトレースを実行し俯瞰する。
まずは,以下のコマンドを実行してみる。

# デフォルト
#directory = 'extension'
directory = 'myext'

最終的には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

参考リンク


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