return_heaptuple_in_btree_indexonlyscan_v1.patch
text/x-patch
Filename: return_heaptuple_in_btree_indexonlyscan_v1.patch
Type: text/x-patch
Part: 0
Patch
Format: unified
Series: patch v1
| File | + | − |
|---|---|---|
| src/backend/access/nbtree/nbtree.c | 2 | 0 |
| src/backend/access/nbtree/nbtsearch.c | 102 | 0 |
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 8158508..db8a55c 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -374,6 +374,8 @@ btbeginscan(Relation rel, int nkeys, int norderbys)
so->currTuples = so->markTuples = NULL;
scan->xs_itupdesc = RelationGetDescr(rel);
+ scan->xs_hitupdesc = NULL;
+ scan->xs_hitup = NULL;
scan->opaque = so;
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index 51dca64..dd3e8b2 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -25,6 +25,7 @@
#include "utils/tqual.h"
+static HeapTuple _bt_fetch_tuple(IndexScanDesc scandesc);
static bool _bt_readpage(IndexScanDesc scan, ScanDirection dir,
OffsetNumber offnum);
static void _bt_saveitem(BTScanOpaque so, int itemIndex,
@@ -38,6 +39,31 @@ static bool _bt_endpoint(IndexScanDesc scan, ScanDirection dir);
static void _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp);
static inline void _bt_initialize_more_data(BTScanOpaque so, ScanDirection dir);
+/*
+ * Fetch all keys in tuple.
+ * Returns a new HeapTuple containing the originally-indexed data.
+ */
+static HeapTuple
+_bt_fetch_tuple(IndexScanDesc scandesc)
+{
+ Relation index = scandesc->indexRelation;
+ Datum fetchatt[INDEX_MAX_KEYS];
+ bool isnull[INDEX_MAX_KEYS];
+ int i;
+ HeapTuple htuple;
+
+ for (i = 0; i < index->rd_att->natts; i++)
+ {
+ fetchatt[i] = index_getattr(scandesc->xs_itup, i + 1,
+ scandesc->xs_itupdesc, &isnull[i]);
+ }
+
+ htuple = heap_form_tuple(scandesc->xs_hitupdesc, fetchatt, isnull);
+ htuple->t_tableOid = scandesc->heapRelation->rd_id;
+
+
+ return htuple;
+}
/*
* _bt_drop_lock_and_maybe_pin()
@@ -1105,8 +1131,32 @@ readcomplete:
/* OK, itemIndex says what to return */
currItem = &so->currPos.items[so->currPos.itemIndex];
scan->xs_ctup.t_self = currItem->heapTid;
+
if (scan->xs_want_itup)
+ {
+ if (!scan->xs_hitupdesc)
+ {
+ int natts = RelationGetNumberOfAttributes(scan->indexRelation);
+ int attno;
+ /*
+ * The storage type of the index can be different from the original
+ * datatype being indexed, so we cannot just grab the index's tuple
+ * descriptor. Instead, construct a descriptor with the original data
+ * types.
+ */
+ scan->xs_hitupdesc = CreateTemplateTupleDesc(natts, false);
+ for (attno = 1; attno <= natts; attno++)
+ {
+ TupleDescInitEntry(scan->xs_hitupdesc, attno, NULL,
+ scan->indexRelation->rd_opcintype[attno - 1],
+ -1, 0);
+ }
+ }
+
scan->xs_itup = (IndexTuple) (so->currTuples + currItem->tupleOffset);
+ scan->xs_hitup = _bt_fetch_tuple(scan);
+ scan->xs_hitup->t_self = currItem->heapTid;
+ }
return true;
}
@@ -1155,8 +1205,34 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
/* OK, itemIndex says what to return */
currItem = &so->currPos.items[so->currPos.itemIndex];
scan->xs_ctup.t_self = currItem->heapTid;
+
if (scan->xs_want_itup)
+ {
+ if (!scan->xs_hitupdesc)
+ {
+ int natts = RelationGetNumberOfAttributes(scan->indexRelation);
+ int attno;
+ /*
+ * The storage type of the index can be different from the original
+ * datatype being indexed, so we cannot just grab the index's tuple
+ * descriptor. Instead, construct a descriptor with the original data
+ * types.
+ */
+ scan->xs_hitupdesc = CreateTemplateTupleDesc(natts, false);
+ for (attno = 1; attno <= natts; attno++)
+ {
+ TupleDescInitEntry(scan->xs_hitupdesc, attno, NULL,
+ scan->indexRelation->rd_opcintype[attno - 1],
+ -1, 0);
+ }
+ }
+
scan->xs_itup = (IndexTuple) (so->currTuples + currItem->tupleOffset);
+ if (scan->xs_hitup)
+ pfree(scan->xs_hitup);
+ scan->xs_hitup = _bt_fetch_tuple(scan);
+ scan->xs_hitup->t_self = currItem->heapTid;
+ }
return true;
}
@@ -1932,8 +2008,34 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
/* OK, itemIndex says what to return */
currItem = &so->currPos.items[so->currPos.itemIndex];
scan->xs_ctup.t_self = currItem->heapTid;
+
if (scan->xs_want_itup)
+ {
+ if (!scan->xs_hitupdesc)
+ {
+ int natts = RelationGetNumberOfAttributes(scan->indexRelation);
+ int attno;
+ /*
+ * The storage type of the index can be different from the original
+ * datatype being indexed, so we cannot just grab the index's tuple
+ * descriptor. Instead, construct a descriptor with the original data
+ * types.
+ */
+ scan->xs_hitupdesc = CreateTemplateTupleDesc(natts, false);
+ for (attno = 1; attno <= natts; attno++)
+ {
+ TupleDescInitEntry(scan->xs_hitupdesc, attno, NULL,
+ scan->indexRelation->rd_opcintype[attno - 1],
+ -1, 0);
+ }
+ }
+
scan->xs_itup = (IndexTuple) (so->currTuples + currItem->tupleOffset);
+ if (scan->xs_hitup)
+ pfree(scan->xs_hitup);
+ scan->xs_hitup = _bt_fetch_tuple(scan);
+ scan->xs_hitup->t_self = currItem->heapTid;
+ }
return true;
}