Compare commits

...

4 Commits

Author SHA1 Message Date
Andrew Kane
26f7fc1694 Added comment [skip ci] 2023-09-03 17:14:15 -07:00
Andrew Kane
46e1db1f15 Added SetIndexTuple function 2023-09-03 17:10:09 -07:00
Andrew Kane
ed9e450571 Copy index tuple 2023-09-03 17:06:22 -07:00
Andrew Kane
97000a7903 Added support for index-only scans to IVFFlat 2023-09-03 16:56:34 -07:00
3 changed files with 55 additions and 5 deletions

View File

@@ -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 */

View File

@@ -248,6 +248,7 @@ typedef struct IvfflatScanOpaqueData
bool first;
Buffer buf;
ItemPointerData heaptid;
IndexTuple itup;
/* Sorting */
Tuplesortstate *sortstate;

View File

@@ -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);
@@ -236,6 +238,34 @@ MarkPriorTupleDead(IndexScanDesc scan)
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
}
/*
* Set tuple for index-only scan
*/
static void
SetIndexTuple(IndexScanDesc scan, ItemPointer indextid)
{
IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque;
Buffer buf = so->buf;
Page page;
OffsetNumber offno = ItemPointerGetOffsetNumber(indextid);
IndexTuple itup;
Size itupSize;
LockBuffer(buf, BUFFER_LOCK_SHARE);
page = BufferGetPage(buf);
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offno));
itupSize = IndexTupleSize(itup);
if (so->itup == NULL)
so->itup = palloc(BLCKSZ);
memcpy(so->itup, itup, itupSize);
scan->xs_itup = so->itup;
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
}
/*
* Prepare for an index scan
*/
@@ -264,6 +294,7 @@ ivfflatbeginscan(Relation index, int nkeys, int norderbys)
so->buf = InvalidBuffer;
so->first = true;
ItemPointerSetInvalid(&so->heaptid);
so->itup = NULL;
so->probes = probes;
so->dimensions = dimensions;
@@ -280,7 +311,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 +326,8 @@ ivfflatbeginscan(Relation index, int nkeys, int norderbys)
scan->opaque = so;
scan->xs_itupdesc = RelationGetDescr(index);
return scan;
}
@@ -380,7 +413,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 +434,11 @@ 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));
/* Set tuple for index-only scan */
if (scan->xs_want_itup)
SetIndexTuple(scan, indextid);
scan->xs_recheckorderby = false;
return true;
@@ -422,6 +459,9 @@ ivfflatendscan(IndexScanDesc scan)
if (BufferIsValid(so->buf))
ReleaseBuffer(so->buf);
if (so->itup != NULL)
pfree(so->itup);
pairingheap_free(so->listQueue);
tuplesort_end(so->sortstate);