You are not “calling Go from SQL” in the sense of a separate daemon. The Go code is compiled into libpageindex_bridge.so (-buildmode=c-shared). Postgres loads pg_pageindex.so, which links that library and exposes C symbols the SQL functions bind to.
flowchart LR
subgraph postgres[PostgreSQL backend]
SQL[SQL: pageindex.*]
C[pg_pageindex.so]
SQL --> C
end
C -->|dlopen / link| G[libpageindex_bridge.so]
G -->|purego + nocgo tag| M[MuPDF shared libs]
The bridge is built with -tags=nocgo: MuPDF via purego, not cgo. That keeps the C toolchain surface smaller, but you still need MuPDF .so present at runtime for the dynamic loader.
| Path | Role |
|---|---|
src/pg_pageindex.c |
PG_FUNCTION_INFO_V1, JSONB ↔ C strings, error handling |
bridge/main.go |
Export //export entrypoints consumed by C |
bridge/go.mod |
Pins github.com/neurondb/pageindex |
sql/pg_pageindex--1.0.sql |
Installed catalog definitions |
- Wrong
pg_configat install → extension files land in a tree Postgres never reads. - MuPDF missing at runtime → backend may abort when the bridge loads (fail-fast, not per-query
NOTICE). - Path permissions →
build_*functions read files as the server OS user, not your client login.