aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/gist/gistget.c17
-rw-r--r--src/backend/access/gist/gistscan.c5
-rw-r--r--src/backend/access/gist/gistutil.c6
-rw-r--r--src/backend/access/index/genam.c2
-rw-r--r--src/backend/access/index/indexam.c4
-rw-r--r--src/backend/access/spgist/spgscan.c24
-rw-r--r--src/backend/executor/nodeIndexonlyscan.c21
7 files changed, 50 insertions, 29 deletions
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index eea366b1ad4..122dc38db56 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -441,12 +441,13 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
so->pageData[so->nPageData].offnum = i;
/*
- * In an index-only scan, also fetch the data from the tuple.
+ * In an index-only scan, also fetch the data from the tuple. The
+ * reconstructed tuples are stored in pageDataCxt.
*/
if (scan->xs_want_itup)
{
oldcxt = MemoryContextSwitchTo(so->pageDataCxt);
- so->pageData[so->nPageData].ftup =
+ so->pageData[so->nPageData].recontup =
gistFetchTuple(giststate, r, it);
MemoryContextSwitchTo(oldcxt);
}
@@ -478,7 +479,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
* In an index-only scan, also fetch the data from the tuple.
*/
if (scan->xs_want_itup)
- item->data.heap.ftup = gistFetchTuple(giststate, r, it);
+ item->data.heap.recontup = gistFetchTuple(giststate, r, it);
}
else
{
@@ -540,11 +541,11 @@ getNextNearest(IndexScanDesc scan)
bool res = false;
int i;
- if (scan->xs_itup)
+ if (scan->xs_hitup)
{
/* free previously returned tuple */
- pfree(scan->xs_itup);
- scan->xs_itup = NULL;
+ pfree(scan->xs_hitup);
+ scan->xs_hitup = NULL;
}
do
@@ -601,7 +602,7 @@ getNextNearest(IndexScanDesc scan)
/* in an index-only scan, also return the reconstructed tuple. */
if (scan->xs_want_itup)
- scan->xs_itup = item->data.heap.ftup;
+ scan->xs_hitup = item->data.heap.recontup;
res = true;
}
else
@@ -685,7 +686,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
/* in an index-only scan, also return the reconstructed tuple */
if (scan->xs_want_itup)
- scan->xs_itup = so->pageData[so->curPageData].ftup;
+ scan->xs_hitup = so->pageData[so->curPageData].recontup;
so->curPageData++;
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c
index 33b388906aa..81ff8fc8b6e 100644
--- a/src/backend/access/gist/gistscan.c
+++ b/src/backend/access/gist/gistscan.c
@@ -155,7 +155,7 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys,
* tuple descriptor to represent the returned index tuples and create a
* memory context to hold them during the scan.
*/
- if (scan->xs_want_itup && !scan->xs_itupdesc)
+ if (scan->xs_want_itup && !scan->xs_hitupdesc)
{
int natts;
int attno;
@@ -174,8 +174,9 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys,
scan->indexRelation->rd_opcintype[attno - 1],
-1, 0);
}
- scan->xs_itupdesc = so->giststate->fetchTupdesc;
+ scan->xs_hitupdesc = so->giststate->fetchTupdesc;
+ /* Also create a memory context that will hold the returned tuples */
so->pageDataCxt = AllocSetContextCreate(so->giststate->scanCxt,
"GiST page data context",
ALLOCSET_DEFAULT_SIZES);
diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c
index f92baedffdd..75845ba0e76 100644
--- a/src/backend/access/gist/gistutil.c
+++ b/src/backend/access/gist/gistutil.c
@@ -624,9 +624,9 @@ gistFetchAtt(GISTSTATE *giststate, int nkey, Datum k, Relation r)
/*
* Fetch all keys in tuple.
- * returns new IndexTuple that contains GISTENTRY with fetched data
+ * Returns a new HeapTuple containing the originally-indexed data.
*/
-IndexTuple
+HeapTuple
gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple)
{
MemoryContext oldcxt = MemoryContextSwitchTo(giststate->tempCxt);
@@ -660,7 +660,7 @@ gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple)
}
MemoryContextSwitchTo(oldcxt);
- return index_form_tuple(giststate->fetchTupdesc, fetchatt, isnull);
+ return heap_form_tuple(giststate->fetchTupdesc, fetchatt, isnull);
}
float
diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
index c4a393f34e8..35994769307 100644
--- a/src/backend/access/index/genam.c
+++ b/src/backend/access/index/genam.c
@@ -119,6 +119,8 @@ RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
scan->xs_itup = NULL;
scan->xs_itupdesc = NULL;
+ scan->xs_hitup = NULL;
+ scan->xs_hitupdesc = NULL;
ItemPointerSetInvalid(&scan->xs_ctup.t_self);
scan->xs_ctup.t_data = NULL;
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 4e7eca73cce..cc5ac8b8571 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -535,8 +535,8 @@ index_getnext_tid(IndexScanDesc scan, ScanDirection direction)
/*
* The AM's amgettuple proc finds the next index entry matching the scan
* keys, and puts the TID into scan->xs_ctup.t_self. It should also set
- * scan->xs_recheck and possibly scan->xs_itup, though we pay no attention
- * to those fields here.
+ * scan->xs_recheck and possibly scan->xs_itup/scan->xs_hitup, though we
+ * pay no attention to those fields here.
*/
found = scan->indexRelation->rd_amroutine->amgettuple(scan, direction);
diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c
index 139d9986004..2d96c0094e6 100644
--- a/src/backend/access/spgist/spgscan.c
+++ b/src/backend/access/spgist/spgscan.c
@@ -92,11 +92,11 @@ resetSpGistScanOpaque(SpGistScanOpaque so)
if (so->want_itup)
{
- /* Must pfree IndexTuples to avoid memory leak */
+ /* Must pfree reconstructed tuples to avoid memory leak */
int i;
for (i = 0; i < so->nPtrs; i++)
- pfree(so->indexTups[i]);
+ pfree(so->reconTups[i]);
}
so->iPtr = so->nPtrs = 0;
}
@@ -195,8 +195,8 @@ spgbeginscan(Relation rel, int keysz, int orderbysz)
"SP-GiST search temporary context",
ALLOCSET_DEFAULT_SIZES);
- /* Set up indexTupDesc and xs_itupdesc in case it's an index-only scan */
- so->indexTupDesc = scan->xs_itupdesc = RelationGetDescr(rel);
+ /* Set up indexTupDesc and xs_hitupdesc in case it's an index-only scan */
+ so->indexTupDesc = scan->xs_hitupdesc = RelationGetDescr(rel);
scan->opaque = so;
@@ -591,12 +591,12 @@ storeGettuple(SpGistScanOpaque so, ItemPointer heapPtr,
if (so->want_itup)
{
/*
- * Reconstruct desired IndexTuple. We have to copy the datum out of
- * the temp context anyway, so we may as well create the tuple here.
+ * Reconstruct index data. We have to copy the datum out of the temp
+ * context anyway, so we may as well create the tuple here.
*/
- so->indexTups[so->nPtrs] = index_form_tuple(so->indexTupDesc,
- &leafValue,
- &isnull);
+ so->reconTups[so->nPtrs] = heap_form_tuple(so->indexTupDesc,
+ &leafValue,
+ &isnull);
}
so->nPtrs++;
}
@@ -619,18 +619,18 @@ spggettuple(IndexScanDesc scan, ScanDirection dir)
/* continuing to return tuples from a leaf page */
scan->xs_ctup.t_self = so->heapPtrs[so->iPtr];
scan->xs_recheck = so->recheck[so->iPtr];
- scan->xs_itup = so->indexTups[so->iPtr];
+ scan->xs_hitup = so->reconTups[so->iPtr];
so->iPtr++;
return true;
}
if (so->want_itup)
{
- /* Must pfree IndexTuples to avoid memory leak */
+ /* Must pfree reconstructed tuples to avoid memory leak */
int i;
for (i = 0; i < so->nPtrs; i++)
- pfree(so->indexTups[i]);
+ pfree(so->reconTups[i]);
}
so->iPtr = so->nPtrs = 0;
diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c
index 66c2ad66d71..4a7f39a7c7d 100644
--- a/src/backend/executor/nodeIndexonlyscan.c
+++ b/src/backend/executor/nodeIndexonlyscan.c
@@ -149,9 +149,26 @@ IndexOnlyNext(IndexOnlyScanState *node)
}
/*
- * Fill the scan tuple slot with data from the index.
+ * Fill the scan tuple slot with data from the index. This might be
+ * provided in either HeapTuple or IndexTuple format. Conceivably an
+ * index AM might fill both fields, in which case we prefer the heap
+ * format, since it's probably a bit cheaper to fill a slot from.
*/
- StoreIndexTuple(slot, scandesc->xs_itup, scandesc->xs_itupdesc);
+ if (scandesc->xs_hitup)
+ {
+ /*
+ * We don't take the trouble to verify that the provided tuple has
+ * exactly the slot's format, but it seems worth doing a quick
+ * check on the number of fields.
+ */
+ Assert(slot->tts_tupleDescriptor->natts ==
+ scandesc->xs_hitupdesc->natts);
+ ExecStoreTuple(scandesc->xs_hitup, slot, InvalidBuffer, false);
+ }
+ else if (scandesc->xs_itup)
+ StoreIndexTuple(slot, scandesc->xs_itup, scandesc->xs_itupdesc);
+ else
+ elog(ERROR, "no data returned for index-only scan");
/*
* If the index was lossy, we have to recheck the index quals.