custom-scan-apilisted
Install: claude install-skill matejformanek/postgres-claude
# custom-scan-api — plug new executor nodes into the planner
Custom Scan lets you register a NEW EXECUTOR NODE from an extension. Unlike an FDW (which handles "foreign data"), Custom Scan is for entirely new operations: parallelization strategies, columnar processing, hardware acceleration (GPU joins), specialized aggregates. citus (distributed queries) and timescaledb (chunk elimination) both use it heavily.
Two-part registration:
- **CustomPath** — planner side. Register a Path shape the planner can consider during path generation.
- **CustomScan / CustomScanState** — executor side. Turn the picked Path into a runnable node.
## The file map
| File | Role |
|---|---|
| `src/backend/optimizer/util/pathnode.c` | Path construction — `create_customscan_path` for extensions. |
| `src/backend/optimizer/plan/createplan.c` | `create_customscan_plan` — converts CustomPath → CustomScan Plan node. |
| `src/backend/executor/nodeCustom.c` | Runtime — `ExecInitCustomScan` / `ExecCustomScan` / `ExecEndCustomScan` — dispatches to the extension's methods. |
| `src/include/commands/customexpr.h` | Public API — CustomPathMethods, CustomScanMethods, CustomExecMethods structs. |
| `src/backend/nodes/copyfuncs.c` / `readfuncs.c` / `outfuncs.c` | Serialization support for CustomPath / CustomScan. |
## The three method structs
### `CustomPathMethods` — planner-side
```c
typedef struct CustomPathMethods {
const char *CustomName;
/* Called when converting Path to Plan */
Plan *(*