"No amcanreturn" alone is not enough.
The failure needs
amoptionalkey = true together with amgettuple != NULL and amcanreturn
NULL. I could not find an in-core AM with that combination; diskann
has it, which is why the third-party extension showed the bug.
https://github.com/timescale/pgvectorscale/blob/main/pgvectorscale/src/access_method/mod.rs```
amroutine.amoptionalkey = true;
...
amroutine.amgettuple = Some(scan::amgettuple);
amroutine.amgetbitmap = None;
```
I reproduced it on current master without pgvectorscale, using a tiny
module AM that only implements those flags and returns heap TIDs
without filling xs_hitup/xs_itup. With enable_seqscan/bitmapscan off:
```
Aggregate
-> Index Only Scan using idx_nopk on t_nopk
ERROR: no data returned for index-only scan
```
So this is not a mixed-binary problem with the extension.
The hole is in check_index_only(): bms_is_subset(attrs_used,
index_canreturn_attrs) is true when attrs_used is empty even if the
index cannot return any column. That matches the empty-targetlist
count(*) case. It is in the same family as the earlier
get_actual_variable_range() amcanreturn check (74197bdc842).