SlideShare a Scribd company logo
PostgreSQL
C言語によるユーザ定義関数の作り方

   日本PostgreSQLユーザ会
        永安悟史
    snaga@snaga.org
Contents

PostgreSQL関数の基礎知識
もっとも簡単な関数の作成
関数に引数を渡す
レコードを返却する関数の作成
複数行を返却する関数の作成
テーブルを返却する関数の作成
PostgreSQL関数の基礎知識
C言語で関数を作るメリット

PostgreSQLの内部構造にアクセス・操作できる
  共有メモリ
  システムカタログ
外部のさまざまなライブラリと連携できる
  外部ライブラリの機能をPostgreSQLの関数の
  延長で使用できる
高速
  Cですから
関数の種類

引数
 引数無し
 引数有り
戻り値
 値(単一行、単一列)
 レコード(単一行、複数列)
 複数行(複数行、単一列)
 テーブル(複数行、複数列)
開発のおおまかな流れ

  C言語で関数本体を作成する
  Makefileを作成する
  関数を登録するSQLを作成する
  C言語関数のコンパイルとインストール
  SQL文で関数を登録
                      共有              バックエンド
C言語ソース
                    オブジェクト              登録



         Makefile            登録用SQL
もっとも簡単な関数の作成
サンプル(1)

  もっとも簡単な関数
    引数:無し
    戻り値:常にtrueを返す

snaga=# SELECT testfunc1();
 testfunc1
-----------
 t
(1 row)

snaga=#
サンプル(1) ~ C関数の作成

 まず、“testfunc.c” を作る

 1:#include "postgres.h"
 2:#include "fmgr.h"
 3:#include "funcapi.h"
 4:
 5:PG_FUNCTION_INFO_V1(testfunc1);           /*   お約束 */
 6:
 7:extern Datum testfunc1(PG_FUNCTION_ARGS); /*   お約束 */
 8:
 9:Datum                            /* 戻り値は       ‘Datum’ になる */
10:testfunc1(PG_FUNCTION_ARGS)               /*   引数定義 */
11:{
12:        PG_RETURN_BOOL(true);             /*   値を返す */
13:}
サンプル(1) ~ Makefileの作成

 次に Makefile を作成
 1:SRCS            = testfunc.c
 2:
 3:MODULE_big      = testfunc
 4:OBJS            = $(SRCS:.c=.o)
 5:DOCS            =
 6:DATA_built      = testfunc.sql
 7:
 8:ifdef USE_PGXS
 9:PGXS = $(shell pg_config --pgxs)
10:include $(PGXS)
11:else
12:subdir = contrib/testfunc
13:top_builddir = ../..
14:include $(top_builddir)/src/Makefile.global
15:include $(top_srcdir)/contrib/contrib-global.mk
16:endif
サンプル(1) ~ 登録用SQLの作成

    登録用のSQL文を作成する
     “testfunc.sql.in” として作成


                        SQLの関数名

戻り値の型
                                           C言語の関数名


  CREATE OR REPLACE FUNCTION testfunc1()
  RETURNS boolean
  AS 'MODULE_PATHNAME', 'testfunc1'
  LANGUAGE 'C' STRICT;
サンプル(1) ~ 関数のコンパイル

     作成したファイルを contrib/testfunc に置く
      contrib はソースを展開したディレクトリにある
{657}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% pwd
/home/snaga/postgresql-8.1beta2/contrib/testfunc
{658}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% ls -l
合計 12
-rw-r--r--    1 snaga    users         585 9月 24 20:34 Makefile
-rw-r--r--    1 snaga    users         200 9月 24 20:34 testfunc.c
-rw-r--r--    1 snaga    users         110 9月 24 20:36 testfunc.sql.in
{659}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc%
サンプル(1) ~ 関数のコンパイル
      make する(makeコマンドを実行)
{659}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% make
sed 's,MODULE_PATHNAME,$libdir/testfunc,g' testfunc.sql.in >testfunc.sql
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -fno-strict-aliasing
 -fpic -I. -I../../src/include -D_GNU_SOURCE   -c -o testfunc.o testfunc.c
ar crs libtestfunc.a testfunc.o
ranlib libtestfunc.a
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -fno-strict-aliasing
 -fpic -shared -Wl,-soname,libtestfunc.so.0 testfunc.o -L../../src/port
 -Wl,-rpath,/home/snaga/pgsql81b2/lib -o libtestfunc.so.0.0
rm -f libtestfunc.so.0
ln -s libtestfunc.so.0.0 libtestfunc.so.0
rm -f libtestfunc.so
ln -s libtestfunc.so.0.0 libtestfunc.so
{660}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% ls
Makefile         libtestfunc.so.0@    testfunc.o
libtestfunc.a    libtestfunc.so.0.0* testfunc.sql
libtestfunc.so@ testfunc.c            testfunc.sql.in
{661}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc%
サンプル(1) ~ 関数のインストール
                                                            testfunc.sql が
      make install を実行                                      share/contrib に
                                                            インストールされる



{662}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% make install
/bin/sh ../../config/install-sh -c -m 644 testfunc.sql
  /home/snaga/pgsql81b2/share/contrib
/bin/sh ../../config/install-sh -c -m 755 libtestfunc.so.0.0
  /home/snaga/pgsql81b2/lib/testfunc.so
{663}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc%


             Libtestfunc.so.0.0 が
             lib にインストールされる
サンプル(1) ~ 関数の登録

      データベースに対して関数を登録する
{663}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% psql -f ¥
 /home/snaga/pgsql81b2/share/contrib/testfunc.sql
CREATE FUNCTION
{664}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc%


             データベースに対して
             testfunc.sql を実行する
             (実際には一行)
サンプル(1) ~ 動作確認

      psql を使って動作を確認する
{87}snaga@athena:~/pgsql81b2% ./bin/psql
Welcome to psql 8.1beta2, the PostgreSQL interactive terminal.

Type: ¥copyright for distribution terms
      ¥h for help with SQL commands
      ¥? for help with psql commands
      ¥g or terminate with semicolon to execute query
      ¥q to quit

snaga=# SELECT testfunc1();
 testfunc1
-----------
 t
(1 row)

snaga=#
関数に引数を渡す
引数を渡すには

必要な処理は二ヶ所にある
 C言語関数における引数受け取り
 CREATE FUNCTIONによる定義
引数の受け取り方

 マクロ “PG_GETARG_xxx” を使う
   型に対応したマクロは include/fmgr.h を参照
 1:#include "postgres.h"
 2:#include "fmgr.h"
 3:#include "funcapi.h"
 4:
 5:PG_FUNCTION_INFO_V1(testfunc2);
 6:
 7:extern Datum testfunc2(PG_FUNCTION_ARGS);
 8:
                                        ここの定義は変わらない
 9:Datum
10:testfunc2(PG_FUNCTION_ARGS)
11:{
12:      int i = PG_GETARG_INT32(0);         “0” は1番目の引数の意。
13:                                          PG_GETARG_INT32は
14:      PG_RETURN_BOOL(true);               int4型を受け取る場合。
15:}
関数定義のしかた

  関数登録用SQLで引数の型を宣言する
   複数引数の宣言も可能
CREATE OR REPLACE FUNCTION testfunc2(int4)
RETURNS boolean
AS 'MODULE_PATHNAME', 'testfunc2'          渡す引数の型を宣言する
LANGUAGE 'C' STRICT;                       (ここではint4)
レコードを返却する関数の作成
レコードの返し方(1/2)

     レコード(=タプル)として返却するために
       ここでは2つの int8 の組みをレコードとして返す
   Datum
   testfunc3(PG_FUNCTION_ARGS)
   {
       TupleDesc tupd;                 /* タプルの型情報の構造体 */
       HeapTupleData tupleData;        /* タプルのデータ用構造体 */
       HeapTuple tuple = &tupleData;   /* タプルのデータ用ポインタ */
       char *values[2];
                                               タプルの型情報(の入れ物)を作る
       Datum result;
                                                            型情報を作成する
       tupd = CreateTemplateTupleDesc(2, false);
       TupleDescInitEntry(tupd, 1, "c1", INT8OID, -1, 0);
       TupleDescInitEntry(tupd, 2, "c2", INT8OID, -1, 0);

これらのカラムを組みに
してレコードとする。              カラム番号           カラム名          カラムの型
レコードの返し方(2/2)

    データをレコードとして組み立てて返却する
                                バッファを作成して
                                文字列として作成する
                                                 データを文字列の配列と
                                                 して用意する
     values[0] = palloc(32);
     snprintf(values[0], 32, "%d", 128);
     values[1] = palloc(32);                          先に作成した型情報と
     snprintf(values[1], 32, "%d", 256);              データからタプルを作る

     tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupd),
                                    values);

     result = TupleGetDatum(TupleDescGetSlot(tupd), tuple);

     PG_RETURN_DATUM(result);
                                  タプルをDatum型に変換
}
    Datumを返却
関数定義のしかた

  返却される型として “RECORD” を指定する
CREATE OR REPLACE FUNCTION testfunc3()
RETURNS RECORD
AS 'MODULE_PATHNAME', 'testfunc3'
LANGUAGE 'C' STRICT;
動作確認

      関数の呼び出し方
       レコードを返却する場合には、レコードの型情報
       を指定する必要がある。

snaga=# SELECT * FROM testfunc3() f(c1 int8, c2 int8);
 c1 | c2
-----+-----
 128 | 256
(1 row)                                       testfunc3()が返却するのは
                                             int8型のカラム“c1”と
                                             int8型のカラム“c2”である。
snaga=#
                 レコードとして返却される
複数行を返却する関数の作成
概要

SET RETURNING FUNCTION(SRF)とも
呼ばれる
返却する行数と同じ回数、関数が呼び出される
  一回目の呼び出しで初期化
  呼び出し一回につき、一行を返却する
二つのメモリコンテキストを使う
  関数用コンテキスト
  ユーザデータ用コンテキスト
   関数用コンテキストの中にある
コード概要
                                        関数コンテキスト
Datum testfunc4(PG_FUNCTION_ARGS)
{                                            一回目の呼び出し
  FuncCallContext *funcctx;

    if (SRF_IS_FIRSTCALL())                           コンテキスト初期化
    {
      funcctx = SRF_FIRSTCALL_INIT();             呼び出し最大回数を
                                                  設定
        funcctx->max_calls = 3;
    }                                       関数コンテキストを
                                            取り出す
    funcctx = SRF_PERCALL_SETUP();
                                                          回数がMAXに達して
    if (call_cntr < max_calls)                            いなければ行を返す
        SRF_RETURN_NEXT(funcctx, Int32GetDatum(call_cntr));
    else
        SRF_RETURN_DONE(funcctx);
}                                                             Datum型を渡す
                                        呼び出し回数が
                                        最大に達したら
レコードの返し方(1/3)

  関数コンテキスト用のポインタを宣言する
Datum
testfunc4(PG_FUNCTION_ARGS)
{
  FuncCallContext *funcctx;   /* 関数コンテキスト */
  MemoryContext oldcontext;
レコードの返し方(2/3)

       最初の呼び出し時には、関数コンテキストを初期
       化し、ユーザデータ用のメモリ領域も初期化する
       if (SRF_IS_FIRSTCALL())                  関数コンテキスト
                                                初期化
       {                                                       ユーザデータ用コンテ
         funcctx = SRF_FIRSTCALL_INIT();                       キストに切り替え

呼び出し
一回目        oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

           /* MyData *fctx = (MyData *) palloc(sizeof(MyData)); */
                                                                     ユーザ用領域を
           funcctx->max_calls = 3;                 呼び出し              確保
           /* funcctx->user_fctx = fctx; */        最大回数を設定

           MemoryContextSwitchTo(oldcontext);       ユーザデータ用コンテ
       }                                            キストを設定
                前のコンテキストに
                切り替え
レコードの返し方(3/3)

    関数コンテキストを取り出す
     呼び出し最大回数を越えてなければ値を
     Datum型で返却する
            SRF_RETURN_NEXT()
           最大回数を越えていたら終了する
            SRF_RETURN_DONE()
    funcctx = SRF_PERCALL_SETUP();

    if (funcctx->call_cntr < funcctx->max_calls)
     SRF_RETURN_NEXT(funcctx, Int32GetDatum(call_cntr));
    else
     SRF_RETURN_DONE(funcctx);
}
コード全体
Datum testfunc4(PG_FUNCTION_ARGS)
{
  FuncCallContext *funcctx;
  MemoryContext oldcontext;

    if (SRF_IS_FIRSTCALL())
    {
      funcctx = SRF_FIRSTCALL_INIT();

        oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

        /* MyData *fctx = (MyData *) palloc(sizeof(MyData)); */

        funcctx->max_calls = 3;
        /* funcctx->user_fctx = fctx; */

        MemoryContextSwitchTo(oldcontext);
    }

    funcctx = SRF_PERCALL_SETUP();

    if (funcctx->call_cntr < funcctx->max_calls)
      SRF_RETURN_NEXT(funcctx, Int32GetDatum(funcctx->call_cntr));
    else
      SRF_RETURN_DONE(funcctx);
}
関数定義のしかた

  返却される型に追加して “SETOF” を指定する
CREATE OR REPLACE FUNCTION testfunc4()
RETURNS SETOF INT4
AS 'MODULE_PATHNAME', 'testfunc4'
LANGUAGE 'C' STRICT;
動作確認

      関数の呼び出し方
snaga=# SELECT testfunc4();
 testfunc4
-----------
         1
         2
         3
(3 rows)

snaga=#         int4型の値が複数行に
                渡って返却される
テーブルを返却する関数の作成
概要

マニュアルではTable Functionと呼ばれている
ここまで解説した手法を組み合わせる
  「複数行」の「レコード」を返却する関数として
  実装する
コード全体(1/2)
Datum
testfunc5(PG_FUNCTION_ARGS)
{
                                    最初の呼び出しの場合
  FuncCallContext *funcctx;
  MemoryContext oldcontext;

                                             関数コンテキスト初期化
  if (SRF_IS_FIRSTCALL())
  {
    TupleDesc tupd;                                                 ユーザ領域用コンテキス
                                                                    トに切り替え
      funcctx = SRF_FIRSTCALL_INIT();

      oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
                                                                            タプルデスクリプタ作成
      tupd = CreateTemplateTupleDesc(2, false);
      TupleDescInitEntry(tupd, 1, "c1", INT8OID, -1, 0);
      TupleDescInitEntry(tupd, 2, "c2", INT8OID, -1, 0);

      funcctx->max_calls = 3;                      タプルデスクリプタを
      funcctx->user_fctx = tupd;                   ユーザ領域に保存
                                                                            前のコンテキストに
      MemoryContextSwitchTo(oldcontext);                                    戻す
  }
コード全体(2/2)
    funcctx = SRF_PERCALL_SETUP();
                                                         関数コンテキストを取り出す
    if (funcctx->call_cntr < funcctx->max_calls)         (毎回呼ばれる)
    {
      TupleDesc tupd;
      HeapTupleData tupleData;
      HeapTuple tuple = &tupleData;              ユーザ用コンテキストから
      Datum result;                              タプルデスクリプタを取り出す
      char *values[2];
                                                                   タプルデータを組み立てる
      tupd = (TupleDesc)funcctx->user_fctx;
                                                                   (適当な数値データを作
                                                                   成)
      values[0] = palloc(32);
      snprintf(values[0], 32, "%d", 128 * funcctx->call_cntr);                   タプルデスクリプタとデータ
      values[1] = palloc(32);                                                    からレコードを作製
      snprintf(values[1], 32, "%d", 256 * funcctx->call_cntr);

      tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupd), values);
      result = TupleGetDatum(TupleDescGetSlot(tupd), tuple);

      SRF_RETURN_NEXT(funcctx, result);
    }                                               レコードを返却
    else
      SRF_RETURN_DONE(funcctx);
}
関数定義のしかた

  “SETOF” な “RECORD” を 返却する
CREATE OR REPLACE FUNCTION testfunc5()
RETURNS SETOF RECORD
AS 'MODULE_PATHNAME', 'testfunc5'
LANGUAGE 'C' STRICT;
動作確認

      関数の呼び出し方
snaga=# SELECT * FROM testfunc5() f(c1 int8, c2 int8);
 c1 | c2
-----+-----
   0 | 0
 128 | 256
 256 | 512                                   testfunc5()が返却するのは
(3 rows)                                     int8型のカラム“c1”と
                                           int8型のカラム“c2”である。
snaga=#
          “c1”, “c2” から成るレコードが
          複数返却される
Appendix

引数の受け取り方(include/fmgr.h)
 PG_GETARG_xxxx()
値の返却(include/fmgr.h)
 PG_RETURN_xxxx()
値とDatumとの変換(include/postgres.h)
 xxxxGetDatum()
 DatumGetxxxx()

More Related Content

What's hot

オンライン物理バックアップの排他モードと非排他モードについて ~PostgreSQLバージョン15対応版~(第34回PostgreSQLアンカンファレンス...
オンライン物理バックアップの排他モードと非排他モードについて ~PostgreSQLバージョン15対応版~(第34回PostgreSQLアンカンファレンス...オンライン物理バックアップの排他モードと非排他モードについて ~PostgreSQLバージョン15対応版~(第34回PostgreSQLアンカンファレンス...
オンライン物理バックアップの排他モードと非排他モードについて ~PostgreSQLバージョン15対応版~(第34回PostgreSQLアンカンファレンス...
NTT DATA Technology & Innovation
 
PostgreSQL 15 開発最新情報
PostgreSQL 15 開発最新情報PostgreSQL 15 開発最新情報
PostgreSQL 15 開発最新情報
Masahiko Sawada
 
PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
Miki Shimogai
 
PostgreSQLでスケールアウト
PostgreSQLでスケールアウトPostgreSQLでスケールアウト
PostgreSQLでスケールアウト
Masahiko Sawada
 
PostgreSQLの統計情報について(第26回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQLの統計情報について(第26回PostgreSQLアンカンファレンス@オンライン 発表資料)PostgreSQLの統計情報について(第26回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQLの統計情報について(第26回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
いまさら聞けないPostgreSQL運用管理
いまさら聞けないPostgreSQL運用管理いまさら聞けないPostgreSQL運用管理
いまさら聞けないPostgreSQL運用管理
Uptime Technologies LLC (JP)
 
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
アーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーションアーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーション
Masahiko Sawada
 
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
より深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニングより深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニング
Yuto Hayamizu
 
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
NTT DATA Technology & Innovation
 
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
NTT DATA OSS Professional Services
 
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
YugabyteDBの実行計画を眺める(NewSQL/分散SQLデータベースよろず勉強会 #3 発表資料)
YugabyteDBの実行計画を眺める(NewSQL/分散SQLデータベースよろず勉強会 #3 発表資料)YugabyteDBの実行計画を眺める(NewSQL/分散SQLデータベースよろず勉強会 #3 発表資料)
YugabyteDBの実行計画を眺める(NewSQL/分散SQLデータベースよろず勉強会 #3 発表資料)
NTT DATA Technology & Innovation
 
Docker Tokyo
Docker TokyoDocker Tokyo
Docker Tokyo
cyberblack28 Ichikawa
 
Vacuum徹底解説
Vacuum徹底解説Vacuum徹底解説
Vacuum徹底解説
Masahiko Sawada
 
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
PostgreSQLの関数属性を知ろう
PostgreSQLの関数属性を知ろうPostgreSQLの関数属性を知ろう
PostgreSQLの関数属性を知ろう
kasaharatt
 

What's hot (20)

オンライン物理バックアップの排他モードと非排他モードについて ~PostgreSQLバージョン15対応版~(第34回PostgreSQLアンカンファレンス...
オンライン物理バックアップの排他モードと非排他モードについて ~PostgreSQLバージョン15対応版~(第34回PostgreSQLアンカンファレンス...オンライン物理バックアップの排他モードと非排他モードについて ~PostgreSQLバージョン15対応版~(第34回PostgreSQLアンカンファレンス...
オンライン物理バックアップの排他モードと非排他モードについて ~PostgreSQLバージョン15対応版~(第34回PostgreSQLアンカンファレンス...
 
PostgreSQL 15 開発最新情報
PostgreSQL 15 開発最新情報PostgreSQL 15 開発最新情報
PostgreSQL 15 開発最新情報
 
PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQLのfull_page_writesについて(第24回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
 
PostgreSQLでスケールアウト
PostgreSQLでスケールアウトPostgreSQLでスケールアウト
PostgreSQLでスケールアウト
 
PostgreSQLの統計情報について(第26回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQLの統計情報について(第26回PostgreSQLアンカンファレンス@オンライン 発表資料)PostgreSQLの統計情報について(第26回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQLの統計情報について(第26回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
いまさら聞けないPostgreSQL運用管理
いまさら聞けないPostgreSQL運用管理いまさら聞けないPostgreSQL運用管理
いまさら聞けないPostgreSQL運用管理
 
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
アーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーションアーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーション
 
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
オンライン物理バックアップの排他モードと非排他モードについて(第15回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
より深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニングより深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニング
 
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
 
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
 
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
YugabyteDBの実行計画を眺める(NewSQL/分散SQLデータベースよろず勉強会 #3 発表資料)
YugabyteDBの実行計画を眺める(NewSQL/分散SQLデータベースよろず勉強会 #3 発表資料)YugabyteDBの実行計画を眺める(NewSQL/分散SQLデータベースよろず勉強会 #3 発表資料)
YugabyteDBの実行計画を眺める(NewSQL/分散SQLデータベースよろず勉強会 #3 発表資料)
 
Docker Tokyo
Docker TokyoDocker Tokyo
Docker Tokyo
 
Vacuum徹底解説
Vacuum徹底解説Vacuum徹底解説
Vacuum徹底解説
 
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
PostgreSQLの関数属性を知ろう
PostgreSQLの関数属性を知ろうPostgreSQLの関数属性を知ろう
PostgreSQLの関数属性を知ろう
 

Viewers also liked

PostgreSQLコミュニティに飛び込もう
PostgreSQLコミュニティに飛び込もうPostgreSQLコミュニティに飛び込もう
PostgreSQLコミュニティに飛び込もう
NTT DATA OSS Professional Services
 
Psycopg2 - Connect to PostgreSQL using Python Script
Psycopg2 - Connect to PostgreSQL using Python ScriptPsycopg2 - Connect to PostgreSQL using Python Script
Psycopg2 - Connect to PostgreSQL using Python Script
Survey Department
 
"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014
Henning Jacobs
 
HAクラスタで PostgreSQLレプリケーション構成の 高可用化
HAクラスタで PostgreSQLレプリケーション構成の 高可用化HAクラスタで PostgreSQLレプリケーション構成の 高可用化
HAクラスタで PostgreSQLレプリケーション構成の 高可用化
Takatoshi Matsuo
 
PostgreSQLの運用・監視にまつわるエトセトラ
PostgreSQLの運用・監視にまつわるエトセトラPostgreSQLの運用・監視にまつわるエトセトラ
PostgreSQLの運用・監視にまつわるエトセトラ
NTT DATA OSS Professional Services
 
Webアプリケーション負荷試験実践入門
Webアプリケーション負荷試験実践入門Webアプリケーション負荷試験実践入門
Webアプリケーション負荷試験実践入門
樽八 仲川
 
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけRDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
Recruit Technologies
 
まずやっとくPostgreSQLチューニング
まずやっとくPostgreSQLチューニングまずやっとくPostgreSQLチューニング
まずやっとくPostgreSQLチューニング
Kosuke Kida
 
明日から使えるPostgre sql運用管理テクニック(監視編)
明日から使えるPostgre sql運用管理テクニック(監視編)明日から使えるPostgre sql運用管理テクニック(監視編)
明日から使えるPostgre sql運用管理テクニック(監視編)kasaharatt
 

Viewers also liked (9)

PostgreSQLコミュニティに飛び込もう
PostgreSQLコミュニティに飛び込もうPostgreSQLコミュニティに飛び込もう
PostgreSQLコミュニティに飛び込もう
 
Psycopg2 - Connect to PostgreSQL using Python Script
Psycopg2 - Connect to PostgreSQL using Python ScriptPsycopg2 - Connect to PostgreSQL using Python Script
Psycopg2 - Connect to PostgreSQL using Python Script
 
"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014
 
HAクラスタで PostgreSQLレプリケーション構成の 高可用化
HAクラスタで PostgreSQLレプリケーション構成の 高可用化HAクラスタで PostgreSQLレプリケーション構成の 高可用化
HAクラスタで PostgreSQLレプリケーション構成の 高可用化
 
PostgreSQLの運用・監視にまつわるエトセトラ
PostgreSQLの運用・監視にまつわるエトセトラPostgreSQLの運用・監視にまつわるエトセトラ
PostgreSQLの運用・監視にまつわるエトセトラ
 
Webアプリケーション負荷試験実践入門
Webアプリケーション負荷試験実践入門Webアプリケーション負荷試験実践入門
Webアプリケーション負荷試験実践入門
 
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけRDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
 
まずやっとくPostgreSQLチューニング
まずやっとくPostgreSQLチューニングまずやっとくPostgreSQLチューニング
まずやっとくPostgreSQLチューニング
 
明日から使えるPostgre sql運用管理テクニック(監視編)
明日から使えるPostgre sql運用管理テクニック(監視編)明日から使えるPostgre sql運用管理テクニック(監視編)
明日から使えるPostgre sql運用管理テクニック(監視編)
 

Similar to PostgreSQL - C言語によるユーザ定義関数の作り方

x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
Masami Ichikawa
 
ラボユース最終成果報告会(Web公開版)
ラボユース最終成果報告会(Web公開版)ラボユース最終成果報告会(Web公開版)
ラボユース最終成果報告会(Web公開版)Shinichi Awamoto
 
エキ Py 読書会02 2章後半
エキ Py 読書会02 2章後半エキ Py 読書会02 2章後半
エキ Py 読書会02 2章後半
Tetsuya Morimoto
 
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
Mr. Vengineer
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。
Kazuki Onishi
 
Ylug 110th kpatch code reading
Ylug 110th kpatch code readingYlug 110th kpatch code reading
Ylug 110th kpatch code reading
Masami Hiramatsu
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
tako pons
 
エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7Tetsuya Morimoto
 
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLakirahiguchi
 
Apache Camel Netty component
Apache Camel Netty componentApache Camel Netty component
Apache Camel Netty componentssogabe
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
y_taka_23
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説
do_aki
 
TypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめ
Yu Nobuoka
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2
Tomohiro Namba
 
Rakuten tech conf
Rakuten tech confRakuten tech conf
Rakuten tech conf
Koichi Fujikawa
 

Similar to PostgreSQL - C言語によるユーザ定義関数の作り方 (20)

x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
ラボユース最終成果報告会(Web公開版)
ラボユース最終成果報告会(Web公開版)ラボユース最終成果報告会(Web公開版)
ラボユース最終成果報告会(Web公開版)
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
エキ Py 読書会02 2章後半
エキ Py 読書会02 2章後半エキ Py 読書会02 2章後半
エキ Py 読書会02 2章後半
 
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。
 
Ylug 110th kpatch code reading
Ylug 110th kpatch code readingYlug 110th kpatch code reading
Ylug 110th kpatch code reading
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
20071030
2007103020071030
20071030
 
エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7
 
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQL
 
Apache Camel Netty component
Apache Camel Netty componentApache Camel Netty component
Apache Camel Netty component
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説
 
TypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめ
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2
 
Prosym2012
Prosym2012Prosym2012
Prosym2012
 
Junit4
Junit4Junit4
Junit4
 
Rakuten tech conf
Rakuten tech confRakuten tech conf
Rakuten tech conf
 

More from Satoshi Nagayasu

データウェアハウスモデリング入門(ダイジェスト版)(事前公開版)
データウェアハウスモデリング入門(ダイジェスト版)(事前公開版) データウェアハウスモデリング入門(ダイジェスト版)(事前公開版)
データウェアハウスモデリング入門(ダイジェスト版)(事前公開版)
Satoshi Nagayasu
 
Oracle対応アプリケーションのDockerize事始め
Oracle対応アプリケーションのDockerize事始めOracle対応アプリケーションのDockerize事始め
Oracle対応アプリケーションのDockerize事始め
Satoshi Nagayasu
 
アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会
アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会
アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会
Satoshi Nagayasu
 
In-Database Analyticsの必要性と可能性
In-Database Analyticsの必要性と可能性In-Database Analyticsの必要性と可能性
In-Database Analyticsの必要性と可能性
Satoshi Nagayasu
 
10 Reasons to Start Your Analytics Project with PostgreSQL
10 Reasons to Start Your Analytics Project with PostgreSQL10 Reasons to Start Your Analytics Project with PostgreSQL
10 Reasons to Start Your Analytics Project with PostgreSQL
Satoshi Nagayasu
 
pgDay Asia 2016 & 2017
pgDay Asia 2016 & 2017pgDay Asia 2016 & 2017
pgDay Asia 2016 & 2017
Satoshi Nagayasu
 
A Story Behind the Conference, or How pgDay Asia was born
A Story Behind the Conference, or How pgDay Asia was bornA Story Behind the Conference, or How pgDay Asia was born
A Story Behind the Conference, or How pgDay Asia was born
Satoshi Nagayasu
 
データベースエンジニアがデータヘルスの2年間で見たもの(仮)
データベースエンジニアがデータヘルスの2年間で見たもの(仮)データベースエンジニアがデータヘルスの2年間で見たもの(仮)
データベースエンジニアがデータヘルスの2年間で見たもの(仮)
Satoshi Nagayasu
 
PostgreSQL 9.4, 9.5 and Beyond @ COSCUP 2015 Taipei
PostgreSQL 9.4, 9.5 and Beyond @ COSCUP 2015 TaipeiPostgreSQL 9.4, 9.5 and Beyond @ COSCUP 2015 Taipei
PostgreSQL 9.4, 9.5 and Beyond @ COSCUP 2015 Taipei
Satoshi Nagayasu
 
[WIP] pgDay Asia 2016
[WIP] pgDay Asia 2016[WIP] pgDay Asia 2016
[WIP] pgDay Asia 2016
Satoshi Nagayasu
 
PostgreSQL 9.4 and Beyond @ FOSSASIA 2015 Singapore
PostgreSQL 9.4 and Beyond @ FOSSASIA 2015 SingaporePostgreSQL 9.4 and Beyond @ FOSSASIA 2015 Singapore
PostgreSQL 9.4 and Beyond @ FOSSASIA 2015 Singapore
Satoshi Nagayasu
 
PostgreSQL 9.4
PostgreSQL 9.4PostgreSQL 9.4
PostgreSQL 9.4
Satoshi Nagayasu
 
PostgreSQL Community in Japan
PostgreSQL Community in JapanPostgreSQL Community in Japan
PostgreSQL Community in Japan
Satoshi Nagayasu
 
海外の技術カンファレンスに行こう! Let’s go tech conferences overseas!
海外の技術カンファレンスに行こう! Let’s go tech conferences overseas!海外の技術カンファレンスに行こう! Let’s go tech conferences overseas!
海外の技術カンファレンスに行こう! Let’s go tech conferences overseas!
Satoshi Nagayasu
 
Django/Celeyを用いたデータ分析Webアプリケーションにおける非同期処理の設計と実装
Django/Celeyを用いたデータ分析Webアプリケーションにおける非同期処理の設計と実装Django/Celeyを用いたデータ分析Webアプリケーションにおける非同期処理の設計と実装
Django/Celeyを用いたデータ分析Webアプリケーションにおける非同期処理の設計と実装
Satoshi Nagayasu
 
映画「マネーボール」に学ぶデータ分析と組織行動論
映画「マネーボール」に学ぶデータ分析と組織行動論映画「マネーボール」に学ぶデータ分析と組織行動論
映画「マネーボール」に学ぶデータ分析と組織行動論Satoshi Nagayasu
 
統計勉強会 分割表とカイ二乗検定
統計勉強会 分割表とカイ二乗検定統計勉強会 分割表とカイ二乗検定
統計勉強会 分割表とカイ二乗検定Satoshi Nagayasu
 
PgAccelerator
PgAcceleratorPgAccelerator
PgAccelerator
Satoshi Nagayasu
 
PostgreSQL Internals - Buffer Management
PostgreSQL Internals - Buffer ManagementPostgreSQL Internals - Buffer Management
PostgreSQL Internals - Buffer ManagementSatoshi Nagayasu
 
遊休リソースを用いた 相同性検索処理の並列化とその評価
遊休リソースを用いた相同性検索処理の並列化とその評価遊休リソースを用いた相同性検索処理の並列化とその評価
遊休リソースを用いた 相同性検索処理の並列化とその評価Satoshi Nagayasu
 

More from Satoshi Nagayasu (20)

データウェアハウスモデリング入門(ダイジェスト版)(事前公開版)
データウェアハウスモデリング入門(ダイジェスト版)(事前公開版) データウェアハウスモデリング入門(ダイジェスト版)(事前公開版)
データウェアハウスモデリング入門(ダイジェスト版)(事前公開版)
 
Oracle対応アプリケーションのDockerize事始め
Oracle対応アプリケーションのDockerize事始めOracle対応アプリケーションのDockerize事始め
Oracle対応アプリケーションのDockerize事始め
 
アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会
アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会
アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会
 
In-Database Analyticsの必要性と可能性
In-Database Analyticsの必要性と可能性In-Database Analyticsの必要性と可能性
In-Database Analyticsの必要性と可能性
 
10 Reasons to Start Your Analytics Project with PostgreSQL
10 Reasons to Start Your Analytics Project with PostgreSQL10 Reasons to Start Your Analytics Project with PostgreSQL
10 Reasons to Start Your Analytics Project with PostgreSQL
 
pgDay Asia 2016 & 2017
pgDay Asia 2016 & 2017pgDay Asia 2016 & 2017
pgDay Asia 2016 & 2017
 
A Story Behind the Conference, or How pgDay Asia was born
A Story Behind the Conference, or How pgDay Asia was bornA Story Behind the Conference, or How pgDay Asia was born
A Story Behind the Conference, or How pgDay Asia was born
 
データベースエンジニアがデータヘルスの2年間で見たもの(仮)
データベースエンジニアがデータヘルスの2年間で見たもの(仮)データベースエンジニアがデータヘルスの2年間で見たもの(仮)
データベースエンジニアがデータヘルスの2年間で見たもの(仮)
 
PostgreSQL 9.4, 9.5 and Beyond @ COSCUP 2015 Taipei
PostgreSQL 9.4, 9.5 and Beyond @ COSCUP 2015 TaipeiPostgreSQL 9.4, 9.5 and Beyond @ COSCUP 2015 Taipei
PostgreSQL 9.4, 9.5 and Beyond @ COSCUP 2015 Taipei
 
[WIP] pgDay Asia 2016
[WIP] pgDay Asia 2016[WIP] pgDay Asia 2016
[WIP] pgDay Asia 2016
 
PostgreSQL 9.4 and Beyond @ FOSSASIA 2015 Singapore
PostgreSQL 9.4 and Beyond @ FOSSASIA 2015 SingaporePostgreSQL 9.4 and Beyond @ FOSSASIA 2015 Singapore
PostgreSQL 9.4 and Beyond @ FOSSASIA 2015 Singapore
 
PostgreSQL 9.4
PostgreSQL 9.4PostgreSQL 9.4
PostgreSQL 9.4
 
PostgreSQL Community in Japan
PostgreSQL Community in JapanPostgreSQL Community in Japan
PostgreSQL Community in Japan
 
海外の技術カンファレンスに行こう! Let’s go tech conferences overseas!
海外の技術カンファレンスに行こう! Let’s go tech conferences overseas!海外の技術カンファレンスに行こう! Let’s go tech conferences overseas!
海外の技術カンファレンスに行こう! Let’s go tech conferences overseas!
 
Django/Celeyを用いたデータ分析Webアプリケーションにおける非同期処理の設計と実装
Django/Celeyを用いたデータ分析Webアプリケーションにおける非同期処理の設計と実装Django/Celeyを用いたデータ分析Webアプリケーションにおける非同期処理の設計と実装
Django/Celeyを用いたデータ分析Webアプリケーションにおける非同期処理の設計と実装
 
映画「マネーボール」に学ぶデータ分析と組織行動論
映画「マネーボール」に学ぶデータ分析と組織行動論映画「マネーボール」に学ぶデータ分析と組織行動論
映画「マネーボール」に学ぶデータ分析と組織行動論
 
統計勉強会 分割表とカイ二乗検定
統計勉強会 分割表とカイ二乗検定統計勉強会 分割表とカイ二乗検定
統計勉強会 分割表とカイ二乗検定
 
PgAccelerator
PgAcceleratorPgAccelerator
PgAccelerator
 
PostgreSQL Internals - Buffer Management
PostgreSQL Internals - Buffer ManagementPostgreSQL Internals - Buffer Management
PostgreSQL Internals - Buffer Management
 
遊休リソースを用いた 相同性検索処理の並列化とその評価
遊休リソースを用いた相同性検索処理の並列化とその評価遊休リソースを用いた相同性検索処理の並列化とその評価
遊休リソースを用いた 相同性検索処理の並列化とその評価
 

Recently uploaded

【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
ARISE analytics
 
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
Osaka University
 
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
sugiuralab
 
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMMハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
osamut
 
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライドHumanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
tazaki1
 
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
嶋 是一 (Yoshikazu SHIMA)
 
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
Yuki Miyazaki
 
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobodyロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
azuma satoshi
 
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
Osaka University
 
iMacwoSu_Gong_de_barabaranishitaHua_.pptx
iMacwoSu_Gong_de_barabaranishitaHua_.pptxiMacwoSu_Gong_de_barabaranishitaHua_.pptx
iMacwoSu_Gong_de_barabaranishitaHua_.pptx
kitamisetagayaxxx
 

Recently uploaded (10)

【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
 
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
 
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
 
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMMハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
 
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライドHumanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
 
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
 
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
 
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobodyロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
 
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
 
iMacwoSu_Gong_de_barabaranishitaHua_.pptx
iMacwoSu_Gong_de_barabaranishitaHua_.pptxiMacwoSu_Gong_de_barabaranishitaHua_.pptx
iMacwoSu_Gong_de_barabaranishitaHua_.pptx
 

PostgreSQL - C言語によるユーザ定義関数の作り方

  • 1. PostgreSQL C言語によるユーザ定義関数の作り方 日本PostgreSQLユーザ会 永安悟史 snaga@snaga.org
  • 4. C言語で関数を作るメリット PostgreSQLの内部構造にアクセス・操作できる 共有メモリ システムカタログ 外部のさまざまなライブラリと連携できる 外部ライブラリの機能をPostgreSQLの関数の 延長で使用できる 高速 Cですから
  • 5. 関数の種類 引数 引数無し 引数有り 戻り値 値(単一行、単一列) レコード(単一行、複数列) 複数行(複数行、単一列) テーブル(複数行、複数列)
  • 6. 開発のおおまかな流れ C言語で関数本体を作成する Makefileを作成する 関数を登録するSQLを作成する C言語関数のコンパイルとインストール SQL文で関数を登録 共有 バックエンド C言語ソース オブジェクト 登録 Makefile 登録用SQL
  • 8. サンプル(1) もっとも簡単な関数 引数:無し 戻り値:常にtrueを返す snaga=# SELECT testfunc1(); testfunc1 ----------- t (1 row) snaga=#
  • 9. サンプル(1) ~ C関数の作成 まず、“testfunc.c” を作る 1:#include "postgres.h" 2:#include "fmgr.h" 3:#include "funcapi.h" 4: 5:PG_FUNCTION_INFO_V1(testfunc1); /* お約束 */ 6: 7:extern Datum testfunc1(PG_FUNCTION_ARGS); /* お約束 */ 8: 9:Datum /* 戻り値は ‘Datum’ になる */ 10:testfunc1(PG_FUNCTION_ARGS) /* 引数定義 */ 11:{ 12: PG_RETURN_BOOL(true); /* 値を返す */ 13:}
  • 10. サンプル(1) ~ Makefileの作成 次に Makefile を作成 1:SRCS = testfunc.c 2: 3:MODULE_big = testfunc 4:OBJS = $(SRCS:.c=.o) 5:DOCS = 6:DATA_built = testfunc.sql 7: 8:ifdef USE_PGXS 9:PGXS = $(shell pg_config --pgxs) 10:include $(PGXS) 11:else 12:subdir = contrib/testfunc 13:top_builddir = ../.. 14:include $(top_builddir)/src/Makefile.global 15:include $(top_srcdir)/contrib/contrib-global.mk 16:endif
  • 11. サンプル(1) ~ 登録用SQLの作成 登録用のSQL文を作成する “testfunc.sql.in” として作成 SQLの関数名 戻り値の型 C言語の関数名 CREATE OR REPLACE FUNCTION testfunc1() RETURNS boolean AS 'MODULE_PATHNAME', 'testfunc1' LANGUAGE 'C' STRICT;
  • 12. サンプル(1) ~ 関数のコンパイル 作成したファイルを contrib/testfunc に置く contrib はソースを展開したディレクトリにある {657}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% pwd /home/snaga/postgresql-8.1beta2/contrib/testfunc {658}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% ls -l 合計 12 -rw-r--r-- 1 snaga users 585 9月 24 20:34 Makefile -rw-r--r-- 1 snaga users 200 9月 24 20:34 testfunc.c -rw-r--r-- 1 snaga users 110 9月 24 20:36 testfunc.sql.in {659}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc%
  • 13. サンプル(1) ~ 関数のコンパイル make する(makeコマンドを実行) {659}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% make sed 's,MODULE_PATHNAME,$libdir/testfunc,g' testfunc.sql.in >testfunc.sql gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -fno-strict-aliasing -fpic -I. -I../../src/include -D_GNU_SOURCE -c -o testfunc.o testfunc.c ar crs libtestfunc.a testfunc.o ranlib libtestfunc.a gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -fno-strict-aliasing -fpic -shared -Wl,-soname,libtestfunc.so.0 testfunc.o -L../../src/port -Wl,-rpath,/home/snaga/pgsql81b2/lib -o libtestfunc.so.0.0 rm -f libtestfunc.so.0 ln -s libtestfunc.so.0.0 libtestfunc.so.0 rm -f libtestfunc.so ln -s libtestfunc.so.0.0 libtestfunc.so {660}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% ls Makefile libtestfunc.so.0@ testfunc.o libtestfunc.a libtestfunc.so.0.0* testfunc.sql libtestfunc.so@ testfunc.c testfunc.sql.in {661}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc%
  • 14. サンプル(1) ~ 関数のインストール testfunc.sql が make install を実行 share/contrib に インストールされる {662}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% make install /bin/sh ../../config/install-sh -c -m 644 testfunc.sql /home/snaga/pgsql81b2/share/contrib /bin/sh ../../config/install-sh -c -m 755 libtestfunc.so.0.0 /home/snaga/pgsql81b2/lib/testfunc.so {663}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% Libtestfunc.so.0.0 が lib にインストールされる
  • 15. サンプル(1) ~ 関数の登録 データベースに対して関数を登録する {663}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% psql -f ¥ /home/snaga/pgsql81b2/share/contrib/testfunc.sql CREATE FUNCTION {664}snaga@athena:~/postgresql-8.1beta2/contrib/testfunc% データベースに対して testfunc.sql を実行する (実際には一行)
  • 16. サンプル(1) ~ 動作確認 psql を使って動作を確認する {87}snaga@athena:~/pgsql81b2% ./bin/psql Welcome to psql 8.1beta2, the PostgreSQL interactive terminal. Type: ¥copyright for distribution terms ¥h for help with SQL commands ¥? for help with psql commands ¥g or terminate with semicolon to execute query ¥q to quit snaga=# SELECT testfunc1(); testfunc1 ----------- t (1 row) snaga=#
  • 19. 引数の受け取り方 マクロ “PG_GETARG_xxx” を使う 型に対応したマクロは include/fmgr.h を参照 1:#include "postgres.h" 2:#include "fmgr.h" 3:#include "funcapi.h" 4: 5:PG_FUNCTION_INFO_V1(testfunc2); 6: 7:extern Datum testfunc2(PG_FUNCTION_ARGS); 8: ここの定義は変わらない 9:Datum 10:testfunc2(PG_FUNCTION_ARGS) 11:{ 12: int i = PG_GETARG_INT32(0); “0” は1番目の引数の意。 13: PG_GETARG_INT32は 14: PG_RETURN_BOOL(true); int4型を受け取る場合。 15:}
  • 20. 関数定義のしかた 関数登録用SQLで引数の型を宣言する 複数引数の宣言も可能 CREATE OR REPLACE FUNCTION testfunc2(int4) RETURNS boolean AS 'MODULE_PATHNAME', 'testfunc2' 渡す引数の型を宣言する LANGUAGE 'C' STRICT; (ここではint4)
  • 22. レコードの返し方(1/2) レコード(=タプル)として返却するために ここでは2つの int8 の組みをレコードとして返す Datum testfunc3(PG_FUNCTION_ARGS) { TupleDesc tupd; /* タプルの型情報の構造体 */ HeapTupleData tupleData; /* タプルのデータ用構造体 */ HeapTuple tuple = &tupleData; /* タプルのデータ用ポインタ */ char *values[2]; タプルの型情報(の入れ物)を作る Datum result; 型情報を作成する tupd = CreateTemplateTupleDesc(2, false); TupleDescInitEntry(tupd, 1, "c1", INT8OID, -1, 0); TupleDescInitEntry(tupd, 2, "c2", INT8OID, -1, 0); これらのカラムを組みに してレコードとする。 カラム番号 カラム名 カラムの型
  • 23. レコードの返し方(2/2) データをレコードとして組み立てて返却する バッファを作成して 文字列として作成する データを文字列の配列と して用意する values[0] = palloc(32); snprintf(values[0], 32, "%d", 128); values[1] = palloc(32); 先に作成した型情報と snprintf(values[1], 32, "%d", 256); データからタプルを作る tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupd), values); result = TupleGetDatum(TupleDescGetSlot(tupd), tuple); PG_RETURN_DATUM(result); タプルをDatum型に変換 } Datumを返却
  • 24. 関数定義のしかた 返却される型として “RECORD” を指定する CREATE OR REPLACE FUNCTION testfunc3() RETURNS RECORD AS 'MODULE_PATHNAME', 'testfunc3' LANGUAGE 'C' STRICT;
  • 25. 動作確認 関数の呼び出し方 レコードを返却する場合には、レコードの型情報 を指定する必要がある。 snaga=# SELECT * FROM testfunc3() f(c1 int8, c2 int8); c1 | c2 -----+----- 128 | 256 (1 row) testfunc3()が返却するのは int8型のカラム“c1”と int8型のカラム“c2”である。 snaga=# レコードとして返却される
  • 27. 概要 SET RETURNING FUNCTION(SRF)とも 呼ばれる 返却する行数と同じ回数、関数が呼び出される 一回目の呼び出しで初期化 呼び出し一回につき、一行を返却する 二つのメモリコンテキストを使う 関数用コンテキスト ユーザデータ用コンテキスト 関数用コンテキストの中にある
  • 28. コード概要 関数コンテキスト Datum testfunc4(PG_FUNCTION_ARGS) { 一回目の呼び出し FuncCallContext *funcctx; if (SRF_IS_FIRSTCALL()) コンテキスト初期化 { funcctx = SRF_FIRSTCALL_INIT(); 呼び出し最大回数を 設定 funcctx->max_calls = 3; } 関数コンテキストを 取り出す funcctx = SRF_PERCALL_SETUP(); 回数がMAXに達して if (call_cntr < max_calls) いなければ行を返す SRF_RETURN_NEXT(funcctx, Int32GetDatum(call_cntr)); else SRF_RETURN_DONE(funcctx); } Datum型を渡す 呼び出し回数が 最大に達したら
  • 29. レコードの返し方(1/3) 関数コンテキスト用のポインタを宣言する Datum testfunc4(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; /* 関数コンテキスト */ MemoryContext oldcontext;
  • 30. レコードの返し方(2/3) 最初の呼び出し時には、関数コンテキストを初期 化し、ユーザデータ用のメモリ領域も初期化する if (SRF_IS_FIRSTCALL()) 関数コンテキスト 初期化 { ユーザデータ用コンテ funcctx = SRF_FIRSTCALL_INIT(); キストに切り替え 呼び出し 一回目 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); /* MyData *fctx = (MyData *) palloc(sizeof(MyData)); */ ユーザ用領域を funcctx->max_calls = 3; 呼び出し 確保 /* funcctx->user_fctx = fctx; */ 最大回数を設定 MemoryContextSwitchTo(oldcontext); ユーザデータ用コンテ } キストを設定 前のコンテキストに 切り替え
  • 31. レコードの返し方(3/3) 関数コンテキストを取り出す 呼び出し最大回数を越えてなければ値を Datum型で返却する SRF_RETURN_NEXT() 最大回数を越えていたら終了する SRF_RETURN_DONE() funcctx = SRF_PERCALL_SETUP(); if (funcctx->call_cntr < funcctx->max_calls) SRF_RETURN_NEXT(funcctx, Int32GetDatum(call_cntr)); else SRF_RETURN_DONE(funcctx); }
  • 32. コード全体 Datum testfunc4(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; MemoryContext oldcontext; if (SRF_IS_FIRSTCALL()) { funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); /* MyData *fctx = (MyData *) palloc(sizeof(MyData)); */ funcctx->max_calls = 3; /* funcctx->user_fctx = fctx; */ MemoryContextSwitchTo(oldcontext); } funcctx = SRF_PERCALL_SETUP(); if (funcctx->call_cntr < funcctx->max_calls) SRF_RETURN_NEXT(funcctx, Int32GetDatum(funcctx->call_cntr)); else SRF_RETURN_DONE(funcctx); }
  • 33. 関数定義のしかた 返却される型に追加して “SETOF” を指定する CREATE OR REPLACE FUNCTION testfunc4() RETURNS SETOF INT4 AS 'MODULE_PATHNAME', 'testfunc4' LANGUAGE 'C' STRICT;
  • 34. 動作確認 関数の呼び出し方 snaga=# SELECT testfunc4(); testfunc4 ----------- 1 2 3 (3 rows) snaga=# int4型の値が複数行に 渡って返却される
  • 36. 概要 マニュアルではTable Functionと呼ばれている ここまで解説した手法を組み合わせる 「複数行」の「レコード」を返却する関数として 実装する
  • 37. コード全体(1/2) Datum testfunc5(PG_FUNCTION_ARGS) { 最初の呼び出しの場合 FuncCallContext *funcctx; MemoryContext oldcontext; 関数コンテキスト初期化 if (SRF_IS_FIRSTCALL()) { TupleDesc tupd; ユーザ領域用コンテキス トに切り替え funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); タプルデスクリプタ作成 tupd = CreateTemplateTupleDesc(2, false); TupleDescInitEntry(tupd, 1, "c1", INT8OID, -1, 0); TupleDescInitEntry(tupd, 2, "c2", INT8OID, -1, 0); funcctx->max_calls = 3; タプルデスクリプタを funcctx->user_fctx = tupd; ユーザ領域に保存 前のコンテキストに MemoryContextSwitchTo(oldcontext); 戻す }
  • 38. コード全体(2/2) funcctx = SRF_PERCALL_SETUP(); 関数コンテキストを取り出す if (funcctx->call_cntr < funcctx->max_calls) (毎回呼ばれる) { TupleDesc tupd; HeapTupleData tupleData; HeapTuple tuple = &tupleData; ユーザ用コンテキストから Datum result; タプルデスクリプタを取り出す char *values[2]; タプルデータを組み立てる tupd = (TupleDesc)funcctx->user_fctx; (適当な数値データを作 成) values[0] = palloc(32); snprintf(values[0], 32, "%d", 128 * funcctx->call_cntr); タプルデスクリプタとデータ values[1] = palloc(32); からレコードを作製 snprintf(values[1], 32, "%d", 256 * funcctx->call_cntr); tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupd), values); result = TupleGetDatum(TupleDescGetSlot(tupd), tuple); SRF_RETURN_NEXT(funcctx, result); } レコードを返却 else SRF_RETURN_DONE(funcctx); }
  • 39. 関数定義のしかた “SETOF” な “RECORD” を 返却する CREATE OR REPLACE FUNCTION testfunc5() RETURNS SETOF RECORD AS 'MODULE_PATHNAME', 'testfunc5' LANGUAGE 'C' STRICT;
  • 40. 動作確認 関数の呼び出し方 snaga=# SELECT * FROM testfunc5() f(c1 int8, c2 int8); c1 | c2 -----+----- 0 | 0 128 | 256 256 | 512 testfunc5()が返却するのは (3 rows) int8型のカラム“c1”と int8型のカラム“c2”である。 snaga=# “c1”, “c2” から成るレコードが 複数返却される