/* * Collect data from a pending-list page in preparation for insertion into * the main index. * * Go through all tuples >= startoff on page and collect values in accum * * Note that ka is just workspace --- it does not carry any state across * calls. */ static void processPendingPage(BuildAccumulator *accum, KeyArray *ka, Page page, OffsetNumber startoff) { ItemPointerData heapptr; OffsetNumber i, maxoff; OffsetNumber attrnum; /* reset *ka to empty */ ka->nvalues = 0; maxoff = PageGetMaxOffsetNumber(page); Assert(maxoff >= FirstOffsetNumber); ItemPointerSetInvalid(&heapptr); attrnum = 0; for (i = startoff; i <= maxoff; i = OffsetNumberNext(i)) { IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, i)); OffsetNumber curattnum; Datum curkey; GinNullCategory curcategory; /* Check for change of heap TID or attnum */ curattnum = gintuple_get_attrnum(accum->ginstate, itup); if (!ItemPointerIsValid(&heapptr)) { heapptr = itup->t_tid; attrnum = curattnum; } else if (!(ItemPointerEquals(&heapptr, &itup->t_tid) && curattnum == attrnum)) { /* * ginInsertBAEntries can insert several datums per call, but only * for one heap tuple and one column. So call it at a boundary, * and reset ka. */ ginInsertBAEntries(accum, &heapptr, attrnum, ka->keys, ka->categories, ka->nvalues); ka->nvalues = 0; heapptr = itup->t_tid; attrnum = curattnum; } /* Add key to KeyArray */ curkey = gintuple_get_key(accum->ginstate, itup, &curcategory); addDatum(ka, curkey, curcategory); } /* Dump out all remaining keys */ ginInsertBAEntries(accum, &heapptr, attrnum, ka->keys, ka->categories, ka->nvalues); }
/* * Extract index entries for a single indexable item, and add them to the * BuildAccumulator's state. * * This function is used only during initial index creation. */ static void ginHeapTupleBulkInsert(GinBuildState *buildstate, OffsetNumber attnum, Datum value, bool isNull, ItemPointer heapptr) { Datum *entries; GinNullCategory *categories; int32 nentries; MemoryContext oldCtx; oldCtx = MemoryContextSwitchTo(buildstate->funcCtx); entries = ginExtractEntries(buildstate->accum.ginstate, attnum, value, isNull, &nentries, &categories); MemoryContextSwitchTo(oldCtx); ginInsertBAEntries(&buildstate->accum, heapptr, attnum, entries, categories, nentries); buildstate->indtuples += nentries; MemoryContextReset(buildstate->funcCtx); }