1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-21 02:52:47 +03:00

tableam: New callback relation_fetch_toast_slice.

Instead of always calling heap_fetch_toast_slice during detoasting,
invoke a table AM callback which, when the toast table is a heap
table, will be heap_fetch_toast_slice.

This makes it possible for a table AM other than heap to be used
as a TOAST table. It also completes the series of commits intended
to improve the interaction of tableam with TOAST that began with
commit 8b94dab06617ef80a0901ab103ebd8754427ef5a; detoast.c is
now, hopefully, fully AM-independent.

Patch by me, reviewed by Andres Freund and Peter Eisentraut.

Discussion: http://postgr.es/m/CA+TgmoZv-=2iWM4jcw5ZhJeL18HF96+W1yJeYrnGMYdkFFnEpQ@mail.gmail.com
This commit is contained in:
Robert Haas
2020-01-07 14:35:48 -05:00
parent 83322e38da
commit ce242ae154
5 changed files with 245 additions and 193 deletions

View File

@@ -136,4 +136,14 @@ extern HeapTuple toast_build_flattened_tuple(TupleDesc tupleDesc,
Datum *values,
bool *isnull);
/* ----------
* heap_fetch_toast_slice
*
* Fetch a slice from a toast value stored in a heap table.
* ----------
*/
extern void heap_fetch_toast_slice(Relation toastrel, Oid valueid,
int32 attrsize, int32 sliceoffset,
int32 slicelength, struct varlena *result);
#endif /* HEAPTOAST_H */

View File

@@ -588,6 +588,17 @@ typedef struct TableAmRoutine
*/
Oid (*relation_toast_am) (Relation rel);
/*
* This callback is invoked when detoasting a value stored in a toast
* table implemented by this AM. See table_relation_fetch_toast_slice()
* for more details.
*/
void (*relation_fetch_toast_slice) (Relation toastrel, Oid valueid,
int32 attrsize,
int32 sliceoffset,
int32 slicelength,
struct varlena *result);
/* ------------------------------------------------------------------------
* Planner related functions.
@@ -1620,6 +1631,41 @@ table_relation_toast_am(Relation rel)
return rel->rd_tableam->relation_toast_am(rel);
}
/*
* Fetch all or part of a TOAST value from a TOAST table.
*
* If this AM is never used to implement a TOAST table, then this callback
* is not needed. But, if toasted values are ever stored in a table of this
* type, then you will need this callback.
*
* toastrel is the relation in which the toasted value is stored.
*
* valueid identifes which toast value is to be fetched. For the heap,
* this corresponds to the values stored in the chunk_id column.
*
* attrsize is the total size of the toast value to be fetched.
*
* sliceoffset is the offset within the toast value of the first byte that
* should be fetched.
*
* slicelength is the number of bytes from the toast value that should be
* fetched.
*
* result is caller-allocated space into which the fetched bytes should be
* stored.
*/
static inline void
table_relation_fetch_toast_slice(Relation toastrel, Oid valueid,
int32 attrsize, int32 sliceoffset,
int32 slicelength, struct varlena *result)
{
return toastrel->rd_tableam->relation_fetch_toast_slice(toastrel, valueid,
attrsize,
sliceoffset,
slicelength,
result);
}
/* ----------------------------------------------------------------------------
* Planner related functionality