mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-02 02:31:16 +08:00
Added support for index-only scans to IVFFlat
This commit is contained in:
@@ -182,6 +182,15 @@ ivfflatvalidate(Oid opclassoid)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if index-only scan is supported
|
||||
*/
|
||||
static bool
|
||||
ivfflatcanreturn(Relation index, int attno)
|
||||
{
|
||||
return attno == 1 && IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC) == NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Define index handler
|
||||
*
|
||||
@@ -223,7 +232,7 @@ ivfflathandler(PG_FUNCTION_ARGS)
|
||||
amroutine->aminsert = ivfflatinsert;
|
||||
amroutine->ambulkdelete = ivfflatbulkdelete;
|
||||
amroutine->amvacuumcleanup = ivfflatvacuumcleanup;
|
||||
amroutine->amcanreturn = NULL; /* tuple not included in heapsort */
|
||||
amroutine->amcanreturn = ivfflatcanreturn;
|
||||
amroutine->amcostestimate = ivfflatcostestimate;
|
||||
amroutine->amoptions = ivfflatoptions;
|
||||
amroutine->amproperty = NULL; /* TODO AMPROP_DISTANCE_ORDERABLE */
|
||||
|
||||
@@ -141,6 +141,7 @@ GetScanItems(IndexScanDesc scan, Datum value)
|
||||
IndexTuple itup;
|
||||
Datum datum;
|
||||
bool isnull;
|
||||
ItemPointerData indextid;
|
||||
ItemId itemid = PageGetItemId(page, offno);
|
||||
|
||||
/* Skip dead tuples */
|
||||
@@ -149,6 +150,7 @@ GetScanItems(IndexScanDesc scan, Datum value)
|
||||
|
||||
itup = (IndexTuple) PageGetItem(page, itemid);
|
||||
datum = index_getattr(itup, 1, tupdesc, &isnull);
|
||||
ItemPointerSet(&indextid, searchPage, offno);
|
||||
|
||||
/*
|
||||
* Add virtual tuple
|
||||
@@ -161,7 +163,7 @@ GetScanItems(IndexScanDesc scan, Datum value)
|
||||
slot->tts_isnull[0] = false;
|
||||
slot->tts_values[1] = PointerGetDatum(&itup->t_tid);
|
||||
slot->tts_isnull[1] = false;
|
||||
slot->tts_values[2] = Int32GetDatum((int) searchPage);
|
||||
slot->tts_values[2] = PointerGetDatum(&indextid);
|
||||
slot->tts_isnull[2] = false;
|
||||
ExecStoreVirtualTuple(slot);
|
||||
|
||||
@@ -280,7 +282,7 @@ ivfflatbeginscan(Relation index, int nkeys, int norderbys)
|
||||
#endif
|
||||
TupleDescInitEntry(so->tupdesc, (AttrNumber) 1, "distance", FLOAT8OID, -1, 0);
|
||||
TupleDescInitEntry(so->tupdesc, (AttrNumber) 2, "heaptid", TIDOID, -1, 0);
|
||||
TupleDescInitEntry(so->tupdesc, (AttrNumber) 3, "indexblkno", INT4OID, -1, 0);
|
||||
TupleDescInitEntry(so->tupdesc, (AttrNumber) 3, "indextid", TIDOID, -1, 0);
|
||||
|
||||
/* Prep sort */
|
||||
so->sortstate = tuplesort_begin_heap(so->tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, work_mem, NULL, false);
|
||||
@@ -295,6 +297,8 @@ ivfflatbeginscan(Relation index, int nkeys, int norderbys)
|
||||
|
||||
scan->opaque = so;
|
||||
|
||||
scan->xs_itupdesc = RelationGetDescr(index);
|
||||
|
||||
return scan;
|
||||
}
|
||||
|
||||
@@ -380,7 +384,7 @@ ivfflatgettuple(IndexScanDesc scan, ScanDirection dir)
|
||||
if (tuplesort_gettupleslot(so->sortstate, true, false, so->slot, NULL))
|
||||
{
|
||||
ItemPointer heaptid = (ItemPointer) DatumGetPointer(slot_getattr(so->slot, 2, &so->isnull));
|
||||
BlockNumber indexblkno = DatumGetInt32(slot_getattr(so->slot, 3, &so->isnull));
|
||||
ItemPointer indextid = (ItemPointer) DatumGetPointer(slot_getattr(so->slot, 3, &so->isnull));
|
||||
|
||||
#if PG_VERSION_NUM >= 120000
|
||||
scan->xs_heaptid = *heaptid;
|
||||
@@ -401,7 +405,20 @@ ivfflatgettuple(IndexScanDesc scan, ScanDirection dir)
|
||||
*
|
||||
* https://www.postgresql.org/docs/current/index-locking.html
|
||||
*/
|
||||
so->buf = ReadBuffer(scan->indexRelation, indexblkno);
|
||||
so->buf = ReadBuffer(scan->indexRelation, ItemPointerGetBlockNumber(indextid));
|
||||
|
||||
if (scan->xs_want_itup)
|
||||
{
|
||||
Page page;
|
||||
|
||||
LockBuffer(so->buf, BUFFER_LOCK_SHARE);
|
||||
page = BufferGetPage(so->buf);
|
||||
|
||||
/* TODO Copy tuple to IvfflatScanOpaque */
|
||||
scan->xs_itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, ItemPointerGetOffsetNumber(indextid)));
|
||||
|
||||
LockBuffer(so->buf, BUFFER_LOCK_UNLOCK);
|
||||
}
|
||||
|
||||
scan->xs_recheckorderby = false;
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user