access-method-apislisted
Install: claude install-skill matejformanek/postgres-claude
# Access-method APIs — operational guide
This skill is for code that **implements** an AM (or significantly extends one).
Read-only "how does btree work" questions don't need it — go straight to the
per-AM README.
## Two completely separate plug points
| | Index AM | Table AM |
|---|---|---|
| Struct | `IndexAmRoutine` in `src/include/access/amapi.h` | `TableAmRoutine` in `src/include/access/tableam.h` |
| Resolver | `GetIndexAmRoutine(amhandler)` in `src/backend/access/index/amapi.c` | `GetTableAmRoutine(amhandler)` in `src/backend/access/table/tableamapi.c` |
| Catalog | `pg_am.amtype = 'i'` | `pg_am.amtype = 't'` |
| Executor wrapper | `genam.c` / `indexam.c` | inline wrappers in `tableam.h` (`table_beginscan`, `table_tuple_insert`, …) |
| Canonical impl | `nbtree.c`, also `brin.c`, `gin.c`, `gist.c`, `hash.c`, `spgist.c` | `heapam_handler.c` (the only in-tree one) |
| Minimal stub | `src/test/modules/dummy_index_am/dummy_index_am.c` | none in tree |
| Added | Index AM API since 9.6 (`amapi.h`); table AM since v12 | |
Both APIs work the same way at the dispatch level: a `pg_am` row's `amhandler`
column names a SQL-callable C function (`PG_FUNCTION_INFO_V1`) that returns a
pointer to a **statically allocated** `IndexAmRoutine`/`TableAmRoutine`. The
core never copies or frees the struct.
```c
Datum
myhandler(PG_FUNCTION_ARGS)
{
static const IndexAmRoutine amroutine = { .type = T_IndexAmRoutine, ... };
PG_RETURN_POINTER(&amroutine);
}
```
## Index AM (IndexAmRou