The vault access method¶
A table access method is a struct of function pointers — TableAmRoutine — that PostgreSQL consults for everything it does with a table's storage. CREATE ACCESS METHOD registers a function that returns one.
Construction¶
The routine is built by copying heap's wholesale and then overriding specific members:
heap_methods = GetHeapamTableAmRoutine();
memcpy(&vault_methods, heap_methods, sizeof(TableAmRoutine));
Anything not deliberately replaced is heap's behaviour by construction, rather than by remembering to assign it.
The enforcement callbacks¶
Five callbacks can modify a row, and all five are overridden:
| Callback | Reached by |
|---|---|
tuple_insert |
INSERT |
multi_insert |
COPY FROM |
tuple_insert_speculative |
INSERT ... ON CONFLICT |
tuple_update |
UPDATE, MERGE, ON CONFLICT DO UPDATE |
tuple_delete |
DELETE, MERGE |
All five matter. COPY FROM never touches tuple_insert — it goes through multi_insert. Overriding only the three obvious callbacks would leave COPY writing freely into a table granting no insert.
The identity shims¶
Two further callbacks are overridden for a reason that has nothing to do with enforcement.
heap_getnext() contains a safety check that rejects any relation whose access method routine is not pointer-identical to heap's own. Its comment is explicit that the pointer, rather than the access method's OID, is compared — which supports an access method that is heap, but not one that wraps it.
Two of heap's own callbacks reach that function:
index_build_range_scan— every index build, so everyPRIMARY KEYindex_validate_scan—CREATE INDEX CONCURRENTLY
Delegating them unmodified fails. The shims present the relation as heap for exactly the duration of the delegated call, wrapped in PG_TRY/PG_FINALLY so an error cannot leave the relation permanently claiming to be a heap table.
The alternative would have been copying several hundred lines of heap's HOT-chain and snapshot handling into this extension, and re-verifying it against every PostgreSQL release.
TOAST¶
A vault table's TOAST relation inherits the vault access method, but this is harmless: PostgreSQL's TOAST code calls heap_insert and simple_heap_delete directly rather than going through the access method layer, and reads via index scans rather than heap_getnext.
No exemption is needed, and none should be added.