mirror of
https://github.com/postgres/postgres.git
synced 2025-10-21 02:52:47 +03:00
Split tuptoaster.c into three separate files.
detoast.c/h contain functions required to detoast a datum, partially or completely, plus a few other utility functions for examining the size of toasted datums. toast_internals.c/h contain functions that are used internally to the TOAST subsystem but which (mostly) do not need to be accessed from outside. heaptoast.c/h contains code that is intrinsically specific to the heap AM, either because it operates on HeapTuples or is based on the layout of a heap page. detoast.c and toast_internals.c are placed in src/backend/access/common rather than src/backend/access/heap. At present, both files still have dependencies on the heap, but that will be improved in a future commit. Patch by me, reviewed and tested by Prabhat Sabu, Thomas Munro, Andres Freund, and Álvaro Herrera. Discussion: http://postgr.es/m/CA+TgmoZv-=2iWM4jcw5ZhJeL18HF96+W1yJeYrnGMYdkFFnEpQ@mail.gmail.com
This commit is contained in:
92
src/include/access/detoast.h
Normal file
92
src/include/access/detoast.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* detoast.h
|
||||
* Access to compressed and external varlena values.
|
||||
*
|
||||
* Copyright (c) 2000-2019, PostgreSQL Global Development Group
|
||||
*
|
||||
* src/include/access/detoast.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef DETOAST_H
|
||||
#define DETOAST_H
|
||||
|
||||
/*
|
||||
* Testing whether an externally-stored value is compressed now requires
|
||||
* comparing extsize (the actual length of the external data) to rawsize
|
||||
* (the original uncompressed datum's size). The latter includes VARHDRSZ
|
||||
* overhead, the former doesn't. We never use compression unless it actually
|
||||
* saves space, so we expect either equality or less-than.
|
||||
*/
|
||||
#define VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) \
|
||||
((toast_pointer).va_extsize < (toast_pointer).va_rawsize - VARHDRSZ)
|
||||
|
||||
/*
|
||||
* Macro to fetch the possibly-unaligned contents of an EXTERNAL datum
|
||||
* into a local "struct varatt_external" toast pointer. This should be
|
||||
* just a memcpy, but some versions of gcc seem to produce broken code
|
||||
* that assumes the datum contents are aligned. Introducing an explicit
|
||||
* intermediate "varattrib_1b_e *" variable seems to fix it.
|
||||
*/
|
||||
#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \
|
||||
do { \
|
||||
varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \
|
||||
Assert(VARATT_IS_EXTERNAL(attre)); \
|
||||
Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \
|
||||
memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \
|
||||
} while (0)
|
||||
|
||||
/* Size of an EXTERNAL datum that contains a standard TOAST pointer */
|
||||
#define TOAST_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external))
|
||||
|
||||
/* Size of an EXTERNAL datum that contains an indirection pointer */
|
||||
#define INDIRECT_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_indirect))
|
||||
|
||||
/* ----------
|
||||
* heap_tuple_fetch_attr() -
|
||||
*
|
||||
* Fetches an external stored attribute from the toast
|
||||
* relation. Does NOT decompress it, if stored external
|
||||
* in compressed format.
|
||||
* ----------
|
||||
*/
|
||||
extern struct varlena *heap_tuple_fetch_attr(struct varlena *attr);
|
||||
|
||||
/* ----------
|
||||
* heap_tuple_untoast_attr() -
|
||||
*
|
||||
* Fully detoasts one attribute, fetching and/or decompressing
|
||||
* it as needed.
|
||||
* ----------
|
||||
*/
|
||||
extern struct varlena *heap_tuple_untoast_attr(struct varlena *attr);
|
||||
|
||||
/* ----------
|
||||
* heap_tuple_untoast_attr_slice() -
|
||||
*
|
||||
* Fetches only the specified portion of an attribute.
|
||||
* (Handles all cases for attribute storage)
|
||||
* ----------
|
||||
*/
|
||||
extern struct varlena *heap_tuple_untoast_attr_slice(struct varlena *attr,
|
||||
int32 sliceoffset,
|
||||
int32 slicelength);
|
||||
|
||||
/* ----------
|
||||
* toast_raw_datum_size -
|
||||
*
|
||||
* Return the raw (detoasted) size of a varlena datum
|
||||
* ----------
|
||||
*/
|
||||
extern Size toast_raw_datum_size(Datum value);
|
||||
|
||||
/* ----------
|
||||
* toast_datum_size -
|
||||
*
|
||||
* Return the storage size of a varlena datum
|
||||
* ----------
|
||||
*/
|
||||
extern Size toast_datum_size(Datum value);
|
||||
|
||||
#endif /* DETOAST_H */
|
@@ -1,29 +1,22 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* tuptoaster.h
|
||||
* POSTGRES definitions for external and compressed storage
|
||||
* heaptoast.h
|
||||
* Heap-specific definitions for external and compressed storage
|
||||
* of variable size attributes.
|
||||
*
|
||||
* Copyright (c) 2000-2019, PostgreSQL Global Development Group
|
||||
*
|
||||
* src/include/access/tuptoaster.h
|
||||
* src/include/access/heaptoast.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef TUPTOASTER_H
|
||||
#define TUPTOASTER_H
|
||||
#ifndef HEAPTOAST_H
|
||||
#define HEAPTOAST_H
|
||||
|
||||
#include "access/htup_details.h"
|
||||
#include "storage/lockdefs.h"
|
||||
#include "utils/relcache.h"
|
||||
|
||||
/*
|
||||
* This enables de-toasting of index entries. Needed until VACUUM is
|
||||
* smart enough to rebuild indexes from scratch.
|
||||
*/
|
||||
#define TOAST_INDEX_HACK
|
||||
|
||||
|
||||
/*
|
||||
* Find the maximum size of a tuple if there are to be N tuples per page.
|
||||
*/
|
||||
@@ -95,37 +88,6 @@
|
||||
sizeof(int32) - \
|
||||
VARHDRSZ)
|
||||
|
||||
/* Size of an EXTERNAL datum that contains a standard TOAST pointer */
|
||||
#define TOAST_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external))
|
||||
|
||||
/* Size of an EXTERNAL datum that contains an indirection pointer */
|
||||
#define INDIRECT_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_indirect))
|
||||
|
||||
/*
|
||||
* Testing whether an externally-stored value is compressed now requires
|
||||
* comparing extsize (the actual length of the external data) to rawsize
|
||||
* (the original uncompressed datum's size). The latter includes VARHDRSZ
|
||||
* overhead, the former doesn't. We never use compression unless it actually
|
||||
* saves space, so we expect either equality or less-than.
|
||||
*/
|
||||
#define VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) \
|
||||
((toast_pointer).va_extsize < (toast_pointer).va_rawsize - VARHDRSZ)
|
||||
|
||||
/*
|
||||
* Macro to fetch the possibly-unaligned contents of an EXTERNAL datum
|
||||
* into a local "struct varatt_external" toast pointer. This should be
|
||||
* just a memcpy, but some versions of gcc seem to produce broken code
|
||||
* that assumes the datum contents are aligned. Introducing an explicit
|
||||
* intermediate "varattrib_1b_e *" variable seems to fix it.
|
||||
*/
|
||||
#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \
|
||||
do { \
|
||||
varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \
|
||||
Assert(VARATT_IS_EXTERNAL(attre)); \
|
||||
Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \
|
||||
memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \
|
||||
} while (0)
|
||||
|
||||
/* ----------
|
||||
* toast_insert_or_update -
|
||||
*
|
||||
@@ -144,36 +106,6 @@ extern HeapTuple toast_insert_or_update(Relation rel,
|
||||
*/
|
||||
extern void toast_delete(Relation rel, HeapTuple oldtup, bool is_speculative);
|
||||
|
||||
/* ----------
|
||||
* heap_tuple_fetch_attr() -
|
||||
*
|
||||
* Fetches an external stored attribute from the toast
|
||||
* relation. Does NOT decompress it, if stored external
|
||||
* in compressed format.
|
||||
* ----------
|
||||
*/
|
||||
extern struct varlena *heap_tuple_fetch_attr(struct varlena *attr);
|
||||
|
||||
/* ----------
|
||||
* heap_tuple_untoast_attr() -
|
||||
*
|
||||
* Fully detoasts one attribute, fetching and/or decompressing
|
||||
* it as needed.
|
||||
* ----------
|
||||
*/
|
||||
extern struct varlena *heap_tuple_untoast_attr(struct varlena *attr);
|
||||
|
||||
/* ----------
|
||||
* heap_tuple_untoast_attr_slice() -
|
||||
*
|
||||
* Fetches only the specified portion of an attribute.
|
||||
* (Handles all cases for attribute storage)
|
||||
* ----------
|
||||
*/
|
||||
extern struct varlena *heap_tuple_untoast_attr_slice(struct varlena *attr,
|
||||
int32 sliceoffset,
|
||||
int32 slicelength);
|
||||
|
||||
/* ----------
|
||||
* toast_flatten_tuple -
|
||||
*
|
||||
@@ -204,36 +136,4 @@ extern HeapTuple toast_build_flattened_tuple(TupleDesc tupleDesc,
|
||||
Datum *values,
|
||||
bool *isnull);
|
||||
|
||||
/* ----------
|
||||
* toast_compress_datum -
|
||||
*
|
||||
* Create a compressed version of a varlena datum, if possible
|
||||
* ----------
|
||||
*/
|
||||
extern Datum toast_compress_datum(Datum value);
|
||||
|
||||
/* ----------
|
||||
* toast_raw_datum_size -
|
||||
*
|
||||
* Return the raw (detoasted) size of a varlena datum
|
||||
* ----------
|
||||
*/
|
||||
extern Size toast_raw_datum_size(Datum value);
|
||||
|
||||
/* ----------
|
||||
* toast_datum_size -
|
||||
*
|
||||
* Return the storage size of a varlena datum
|
||||
* ----------
|
||||
*/
|
||||
extern Size toast_datum_size(Datum value);
|
||||
|
||||
/* ----------
|
||||
* toast_get_valid_index -
|
||||
*
|
||||
* Return OID of valid index associated to a toast relation
|
||||
* ----------
|
||||
*/
|
||||
extern Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock);
|
||||
|
||||
#endif /* TUPTOASTER_H */
|
||||
#endif /* HEAPTOAST_H */
|
54
src/include/access/toast_internals.h
Normal file
54
src/include/access/toast_internals.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* toast_internals.h
|
||||
* Internal definitions for the TOAST system.
|
||||
*
|
||||
* Copyright (c) 2000-2019, PostgreSQL Global Development Group
|
||||
*
|
||||
* src/include/access/toast_internals.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef TOAST_INTERNALS_H
|
||||
#define TOAST_INTERNALS_H
|
||||
|
||||
#include "storage/lockdefs.h"
|
||||
#include "utils/relcache.h"
|
||||
#include "utils/snapshot.h"
|
||||
|
||||
/*
|
||||
* The information at the start of the compressed toast data.
|
||||
*/
|
||||
typedef struct toast_compress_header
|
||||
{
|
||||
int32 vl_len_; /* varlena header (do not touch directly!) */
|
||||
int32 rawsize;
|
||||
} toast_compress_header;
|
||||
|
||||
/*
|
||||
* Utilities for manipulation of header information for compressed
|
||||
* toast entries.
|
||||
*/
|
||||
#define TOAST_COMPRESS_HDRSZ ((int32) sizeof(toast_compress_header))
|
||||
#define TOAST_COMPRESS_RAWSIZE(ptr) (((toast_compress_header *) (ptr))->rawsize)
|
||||
#define TOAST_COMPRESS_RAWDATA(ptr) \
|
||||
(((char *) (ptr)) + TOAST_COMPRESS_HDRSZ)
|
||||
#define TOAST_COMPRESS_SET_RAWSIZE(ptr, len) \
|
||||
(((toast_compress_header *) (ptr))->rawsize = (len))
|
||||
|
||||
extern Datum toast_compress_datum(Datum value);
|
||||
extern Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock);
|
||||
|
||||
extern void toast_delete_datum(Relation rel, Datum value, bool is_speculative);
|
||||
extern Datum toast_save_datum(Relation rel, Datum value,
|
||||
struct varlena *oldexternal, int options);
|
||||
|
||||
extern int toast_open_indexes(Relation toastrel,
|
||||
LOCKMODE lock,
|
||||
Relation **toastidxs,
|
||||
int *num_indexes);
|
||||
extern void toast_close_indexes(Relation *toastidxs, int num_indexes,
|
||||
LOCKMODE lock);
|
||||
extern void init_toast_snapshot(Snapshot toast_snapshot);
|
||||
|
||||
#endif /* TOAST_INTERNALS_H */
|
Reference in New Issue
Block a user