23. large object の auto-delete を考える2 - PostgreSQL のソースコードを読む

独自の組み込み型定義

hige=# insert into person values(4);
ERROR:  column "social_no" is of type higeid but expression is of type integer
HINT:  You will need to rewrite or cast the expression.
hige=# insert into person values(oid(4));
ERROR:  column "social_no" is of type higeid but expression is of type oid
HINT:  You will need to rewrite or cast the expression.

higeid は oid と互換にしたいので cast 手続きを書く必要があるっぽい。
pg_cast かな。うわ pg_cast カタログのデータをマクロでそのまま定義している。うーん。定数は oid なんだろうけどせめてマクロで書いて欲しい。
それはともかく int(oid 23) -> higeid(oid 90) のデータを定義する。

DATA(insert (	23	 90    0 i ));

ビルドし直し。

hige=# select typname from pg_type where typname like 'hige%';
 typname 
---------
 higeid
(1 row)

hige=# 
hige=# CREATE TABLE person (social_no higeid);
CREATE TABLE
hige=# insert into person values(3);
INSERT 0 1

できた。

create table に hook

create table はどこで処理される?
/src/backend/commands/tablecmds.c で処理される。
DefineRelation(CreateStmt *stmt, char relkind) の最後あたりで schema に特定の型が存在したら trigger を作る。
ってので良さそうだなあ。
typeid は 0 なので typename->names の方を見るべし。

    foreach(listptr, schema)
    {
        ColumnDef  *colDef = lfirst(listptr);
        fprintf(stderr, "==== typied=%d\n", colDef->typename->typeid);
        if (colDef->typename->typeid == 90) {
          printf("higeid found in create table\n");
        }
        foreach(ptr, colDef->typename->names)
        {
            Value  *value = lfirst(ptr);
            fprintf(stderr, "==== typied=%s\n", value->val.str);
        }
    }

次の1手

  • 組み込み triggerと
  • pg_trigger への登録