読者です 読者をやめる 読者になる 読者になる

HeapTupleHeader構造体の活用

OSS/Linux

SE-PostgreSQLPostgreSQLでは、データベースのデータ形式に互換性がない上に、DLLで提供されている拡張SQL関数群も専用のものを用意しなければならない。

これは、8.2.xベースのSE-PostgreSQLを設計した際に HeapTuple のデータ形式について私の理解が十分でなかったのを引きずっているためである。
HeapTupleというのは、データベースの『行』に対応する PostgreSQL では最も基本的なデータ構造の一つ。8.2.xベースのSE-PostgreSQLでは、ここにセキュリティ属性を格納するための専用の変数を追加しているが、それ故に、最も低いレベルでのデータ形式に互換性が無くなっている。

もうすぐPostgreSQL-8.3.0がリリースされるが、8.3.xベースのSE-PostgreSQLでは、HeapTupleHeader構造体の可変長データ領域にセキュリティ属性を格納するようになる。
これによって、HeapTupleのデータ形式がオリジナルのPostgreSQLと同一になり、DLLで提供されている拡張SQL関数をそのまま利用できるようになる(はず)。

HeapTupleHeaderData構造体
 +------------------------------+ + 0
 | union {                      |
 |   HeapTupleFields t_heap;    |
 |   DatumTupleFields t_datum;  |
 | } t_choice;                  |
 +------------------------------+ +12
 | ItemPointerData t_ctid;      |
 +------------------------------+ +18
 | uint16      t_infomask2;     |
 +------------------------------+ +20
 | uint16      t_infomask;      |
 +------------------------------+ +22
 | uint8       t_hoff;          |
 +------------------------------+ +23
 | padding...                   |
===                            ===
 |                   ...padding |
 +------------------------------+ + t_hoff - 2 * sizeof(Oid)
 | Oid  <Security Attribute>    |
 +------------------------------+ + t_hoff - sizeof(Oid)
 | Oid  <Object Identifier>     |
 +------------------------------+ + t_hoff
 | Data ....                    |
 |                              |

カギになるのは、先頭から5番目のメンバt_hoff。実際のデータ領域は、オフセットt_hoffから開始になるので、固定長のヘッダ領域と、オフセットt_hoffまでのpaddingエリアには好きなデータを入れてよい。
元々、この領域にはObject IDが入れられていたが、これと同じ方法でSE-PostgreSQLの利用するセキュリティ属性を格納するように変更した。
これは、オリジナルのPostgreSQLの範疇での変更なので、仮にPostgreSQL用のDLLをロードして利用したとしても、これらのバイナリからは同様にHeapTupleHeaderを参照できる。

したがって、8.3.xベースのSE-PostgreSQLでは、*.soファイルはRPMファイルに含まなくなるだろう。但し、データベースに関しては共有できない。これは、"security_context"システム列を追加している都合上、SE-PostgreSQLのpg_attributeシステムカタログには余剰の列が追加されているためだ。こちらは、今のところ諦めるしかない。