Internal lazy HNSW cursor
Phase 15 puts pgContext’s graph-read HNSW traversal behind one statement-local, resumable cursor. This is an internal foundation for later bounded beam search, not a SQL API or a user-selectable planner mode.
Contract
The cursor owns only traversal state: the pending and nearest heaps, visited nodes, adjacency scratch space, cumulative work, and a typed terminal reason. It supports seed, peek, pop, bounded advance, finish, and exhausted operations. Peek performs no graph work. Frontier order is ascending distance and then internal node ID; final result order remains ascending distance and then point ID. Nodes are visited once, and masked nodes may connect traversal but cannot enter the result set.
Existing eager graph-read entry points now drain this same cursor, so page, mapped, quantized, segmented, delta-overlay, and filtered HNSW serving keep the same SQL behavior. PostgreSQL still resolves approximate heap identities under the current snapshot and exactly rechecks the authoritative source operator before final ordering. The cursor does not weaken MVCC, ACL, RLS, deletion, or source-row checks.
Cursor state borrows its graph adapter, query, comparison budget, and cancellation hook. It is deliberately not cloneable, serializable, or valid outside the statement and index snapshot that created it.
Bounds and termination
One advance requests 1–256 frontier expansions; the internal default is 32. The cursor admits at most 10,000,000 node expansions. This node-work counter is separate from the Phase 8 query executor’s provider/topology-call expansion budget. Query-wide comparison and memory ceilings retain their Phase 8 bounds, and the cursor additionally freezes a 10,000,000 adjacency-entry ceiling for certification. Allocation projections cover the visited set, both heaps, adjacency scratch, final results, and returned frontier batches before capacity growth. The standalone release gate also enforces a 256 MiB process-RSS ceiling.
Terminal diagnostics contain no vectors, filters, source keys, or row data.
They are exhausted, cancelled, comparison_budget, expansion_budget,
edge_budget, memory_budget, or adapter_error. Only exhausted proves a
complete provider result; every other reason remains visibly incomplete.
Certification and maturity
The frozen manifest is hnsw_lazy_cursor_v1. Its deterministic 10,000-row,
32-dimensional fixture runs 128 paired eager/cursor queries and checks exact
ordered results plus identical comparison, expansion, and edge work. Batch
sizes from 1 through 256, all supported metrics, ties, masks, sparse ACORN
connectors, cancellation, and exact budget boundaries have focused coverage.
The owned source registry covers page, mapped full-precision, mapped
quantized, segmented, and delta-overlay graph reads.
The release-mode gate requires cursor p50 latency no worse than 1.10 times the
eager compatibility drain and retained bytes no worse than 1.05 times the
pre-cursor projection.
The capability remains Internal. It changes no public SQL object, GUC, planner default, index format, or compatibility promise. Later graph phases may consume it only after preserving these bounds and PostgreSQL authority checks.