Virtual tuple slots versus TOAST: big problem

TOASTが必要なTupleをinsert/updateした時、backendがcrushする問題について。
http://archives.postgresql.org/pgsql-hackers/2005-11/msg01016.php

(1)ExecInsertにTupleTableSlot(slot)が渡される。
このときslotのvirtual tuple領域(slot->tts_valuesなど)にデータが設定されている。

(2)ExecMaterializeSlotでslotのvirtual tupleから、physical tuple(slot->tts_tuple)に変換する。slotのvirtual tupleはクリアされる。

(3)ExecConstraintsで制約チェックを実行する。
slotのphysical tupleからチェックするカラムのデータを取り出す。このとき、取り出したカラムとそれより前にあるカラムのデータはslotのvirtual tuple領域にcacheされる。

(4)heap_insertにslotのphysical tupleを渡して、ページにtupleを登録する。
heap_insertでは、tupleサイズがTOAST_TUPLE_THRESHOLDより大きい場合、heap_tuple_toast_attrsを実行する。heap_tuple_toast_attrsは、tupleを上書きして再構成するため、tupleのサイズや各カラムのデータの位置などが変わる。
(*)ここでslotのphysical tupleとvirtual tuple cacheの情報が矛盾してしまう

(5)(ExecInsertに戻って)ExecInsertIndexTuplesを実行してindexにデータを登録するとき、index用のtupleを構築するためにslotのphysical tupleまたはvirtual tupleから、indexに必要なカラムのデータを取り出す。
virtual tupleの情報はphysical tupleの情報と矛盾しているため、virtual tupleの情報を参照したときに正しくない位置のメモリを読んでしまい、backendがcrushするか、間違ったデータを取り出してしまう。

updateについても同様の問題が発生する。
当面の解決策はheap_insert/heap_updateの実行後にvirtual tuple cacheを無効にすること。