diff options
author | Tom Lane | 2017-02-27 22:20:34 +0000 |
---|---|---|
committer | Tom Lane | 2017-02-27 22:20:34 +0000 |
commit | 9b88f27cb42fe8ff59ddc75e29c005624b8850a2 (patch) | |
tree | 285c2882206b72c19cc9ac5f7e84a33b663e204c /src/include | |
parent | 30df93f698d016d086e8961aa6c6076b37ea0ef4 (diff) |
Allow index AMs to return either HeapTuple or IndexTuple format during IOS.
Previously, only IndexTuple format was supported for the output data of
an index-only scan. This is fine for btree, which is just returning a
verbatim index tuple anyway. It's not so fine for SP-GiST, which can
return reconstructed data that's much larger than a page.
To fix, extend the index AM API so that index-only scan data can be
returned in either HeapTuple or IndexTuple format. There's other ways
we could have done it, but this way avoids an API break for index AMs
that aren't concerned with the issue, and it costs little except a couple
more fields in IndexScanDescs.
I changed both GiST and SP-GiST to use the HeapTuple method. I'm not
very clear on whether GiST can reconstruct data that's too large for an
IndexTuple, but that seems possible, and it's not much of a code change to
fix.
Per a complaint from Vik Fearing. Reviewed by Jason Li.
Discussion: https://postgr.es/m/[email protected]
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/access/gist_private.h | 4 | ||||
-rw-r--r-- | src/include/access/relscan.h | 9 | ||||
-rw-r--r-- | src/include/access/spgist_private.h | 2 |
3 files changed, 11 insertions, 4 deletions
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 5b3303056b0..1ad4ed6da75 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -119,7 +119,7 @@ typedef struct GISTSearchHeapItem ItemPointerData heapPtr; bool recheck; /* T if quals must be rechecked */ bool recheckDistances; /* T if distances must be rechecked */ - IndexTuple ftup; /* data fetched back from the index, used in + HeapTuple recontup; /* data reconstructed from the index, used in * index-only scans */ OffsetNumber offnum; /* track offset in page to mark tuple as * LP_DEAD */ @@ -477,7 +477,7 @@ extern void gistMakeUnionItVec(GISTSTATE *giststate, IndexTuple *itvec, int len, extern bool gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b); extern void gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p, OffsetNumber o, GISTENTRY *attdata, bool *isnull); -extern IndexTuple gistFetchTuple(GISTSTATE *giststate, Relation r, +extern HeapTuple gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple); extern void gistMakeUnionKey(GISTSTATE *giststate, int attno, GISTENTRY *entry1, bool isnull1, diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h index ce3ca8d4ac2..3fc726d712f 100644 --- a/src/include/access/relscan.h +++ b/src/include/access/relscan.h @@ -104,9 +104,16 @@ typedef struct IndexScanDescData /* index access method's private state */ void *opaque; /* access-method-specific info */ - /* in an index-only scan, this is valid after a successful amgettuple */ + /* + * In an index-only scan, a successful amgettuple call must fill either + * xs_itup (and xs_itupdesc) or xs_hitup (and xs_hitupdesc) to provide the + * data returned by the scan. It can fill both, in which case the heap + * format will be used. + */ IndexTuple xs_itup; /* index tuple returned by AM */ TupleDesc xs_itupdesc; /* rowtype descriptor of xs_itup */ + HeapTuple xs_hitup; /* index data returned by AM, as HeapTuple */ + TupleDesc xs_hitupdesc; /* rowtype descriptor of xs_hitup */ /* xs_ctup/xs_cbuf/xs_recheck are valid after a successful index_getnext */ HeapTupleData xs_ctup; /* current heap tuple, if any */ diff --git a/src/include/access/spgist_private.h b/src/include/access/spgist_private.h index e42079b09f8..4072c050dea 100644 --- a/src/include/access/spgist_private.h +++ b/src/include/access/spgist_private.h @@ -159,7 +159,7 @@ typedef struct SpGistScanOpaqueData int iPtr; /* index for scanning through same */ ItemPointerData heapPtrs[MaxIndexTuplesPerPage]; /* TIDs from cur page */ bool recheck[MaxIndexTuplesPerPage]; /* their recheck flags */ - IndexTuple indexTups[MaxIndexTuplesPerPage]; /* reconstructed tuples */ + HeapTuple reconTups[MaxIndexTuplesPerPage]; /* reconstructed tuples */ /* * Note: using MaxIndexTuplesPerPage above is a bit hokey since |