diff --git a/src/ivfbuild.c b/src/ivfbuild.c index 54a5be5..fa7a0a8 100644 --- a/src/ivfbuild.c +++ b/src/ivfbuild.c @@ -138,7 +138,7 @@ SampleRows(IvfflatBuildState * buildstate) * Add tuple to sort */ static void -AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState * buildstate) +AddTupleToSort(Relation index, ItemPointer tid, Datum *values, bool *isnull, IvfflatBuildState * buildstate) { double distance; double minDistance = DBL_MAX; @@ -184,6 +184,11 @@ AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState slot->tts_isnull[1] = false; slot->tts_values[2] = value; slot->tts_isnull[2] = false; + for (int i = 1; i < buildstate->tupdesc->natts; i++) + { + slot->tts_values[2 + i] = values[i]; + slot->tts_isnull[2 + i] = isnull[i]; + } ExecStoreVirtualTuple(slot); /* @@ -215,7 +220,7 @@ BuildCallback(Relation index, ItemPointer tid, Datum *values, oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); /* Add tuple to sort */ - AddTupleToSort(index, tid, values, buildstate); + AddTupleToSort(index, tid, values, isnull, buildstate); /* Reset memory context */ MemoryContextSwitchTo(oldCtx); @@ -226,19 +231,20 @@ BuildCallback(Relation index, ItemPointer tid, Datum *values, * Get index tuple from sort state */ static inline void -GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, IndexTuple *itup, int *list) +GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, Datum *values, bool *isnull, IndexTuple *itup, int *list) { if (tuplesort_gettupleslot(sortstate, true, false, slot, NULL)) { - Datum value; - bool isnull; + bool unused; - *list = DatumGetInt32(slot_getattr(slot, 1, &isnull)); - value = slot_getattr(slot, 3, &isnull); + *list = DatumGetInt32(slot_getattr(slot, 1, &unused)); + + for (int i = 0; i < tupdesc->natts; i++) + values[i] = slot_getattr(slot, 3 + i, &isnull[i]); /* Form the index tuple */ - *itup = index_form_tuple(tupdesc, &value, &isnull); - (*itup)->t_tid = *((ItemPointer) DatumGetPointer(slot_getattr(slot, 2, &isnull))); + *itup = index_form_tuple(tupdesc, values, isnull); + (*itup)->t_tid = *((ItemPointer) DatumGetPointer(slot_getattr(slot, 2, &unused))); } else *list = -1; @@ -256,12 +262,14 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) TupleTableSlot *slot = MakeSingleTupleTableSlot(buildstate->sortdesc, &TTSOpsMinimalTuple); TupleDesc tupdesc = buildstate->tupdesc; + Datum *values = palloc(tupdesc->natts * sizeof(Datum)); + bool *isnull = palloc(tupdesc->natts * sizeof(bool)); pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, PROGRESS_IVFFLAT_PHASE_LOAD); pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_TOTAL, buildstate->indtuples); - GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list); + GetNextTuple(buildstate->sortstate, tupdesc, slot, values, isnull, &itup, &list); for (int i = 0; i < buildstate->centers->length; i++) { @@ -297,7 +305,7 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE, ++inserted); - GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list); + GetNextTuple(buildstate->sortstate, tupdesc, slot, values, isnull, &itup, &list); } insertPage = BufferGetBlockNumber(buf); @@ -307,6 +315,9 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) /* Set the start and insert pages */ IvfflatUpdateList(index, buildstate->listInfo[i], insertPage, InvalidBlockNumber, startPage, forkNum); } + + pfree(values); + pfree(isnull); } /* @@ -360,7 +371,8 @@ InitBuildState(IvfflatBuildState * buildstate, Relation heap, Relation index, In buildstate->sortdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(buildstate->sortdesc, (AttrNumber) 1, "list", INT4OID, -1, 0); TupleDescInitEntry(buildstate->sortdesc, (AttrNumber) 2, "tid", TIDOID, -1, 0); - TupleDescInitEntry(buildstate->sortdesc, (AttrNumber) 3, "vector", buildstate->tupdesc->attrs[0].atttypid, -1, 0); + for (int i = 0; i < buildstate->tupdesc->natts; i++) + TupleDescInitEntry(buildstate->sortdesc, (AttrNumber) (3 + i), NULL, buildstate->tupdesc->attrs[0].atttypid, -1, 0); buildstate->slot = MakeSingleTupleTableSlot(buildstate->sortdesc, &TTSOpsVirtual); diff --git a/src/ivfinsert.c b/src/ivfinsert.c index b748c5e..57f839b 100644 --- a/src/ivfinsert.c +++ b/src/ivfinsert.c @@ -78,6 +78,8 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, R BlockNumber insertPage = InvalidBlockNumber; ListInfo listInfo; BlockNumber originalInsertPage; + TupleDesc tupdesc = RelationGetDescr(index); + Datum *newValues = palloc(tupdesc->natts * sizeof(Datum)); /* Detoast once for all calls */ value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); @@ -102,8 +104,12 @@ InsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, R Assert(BlockNumberIsValid(insertPage)); originalInsertPage = insertPage; + newValues[0] = value; + for (int i = 1; i < tupdesc->natts; i++) + newValues[i] = values[i]; + /* Form tuple */ - itup = index_form_tuple(RelationGetDescr(index), &value, isnull); + itup = index_form_tuple(tupdesc, newValues, isnull); itup->t_tid = *heap_tid; /* Get tuple size */