mirror of
https://github.com/postgres/postgres.git
synced 2025-10-22 14:32:25 +03:00
substring(), and perhaps other callers, isn't careful to pass a slice length that is no more than the datum's true size. Since toast_decompress_datum_slice's children will palloc the requested slice length, this can waste memory. Also, close study of the liblz4 documentation suggests that it is dependent on the caller to not ask for more than the correct amount of decompressed data; this squares with observed misbehavior with liblz4 1.8.3. Avoid these problems by switching to the normal full-decompression code path if the slice request is >= datum's decompressed size. Tom Lane and Dilip Kumar Discussion: https://postgr.es/m/507597.1616370729@sss.pgh.pa.us
64 lines
2.1 KiB
C
64 lines
2.1 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* toast_internals.h
|
|
* Internal definitions for the TOAST system.
|
|
*
|
|
* Copyright (c) 2000-2021, PostgreSQL Global Development Group
|
|
*
|
|
* src/include/access/toast_internals.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef TOAST_INTERNALS_H
|
|
#define TOAST_INTERNALS_H
|
|
|
|
#include "access/toast_compression.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!) */
|
|
uint32 tcinfo; /* 2 bits for compression method and 30 bits
|
|
* external size; see va_extinfo */
|
|
} toast_compress_header;
|
|
|
|
/*
|
|
* Utilities for manipulation of header information for compressed
|
|
* toast entries.
|
|
*/
|
|
#define TOAST_COMPRESS_EXTSIZE(ptr) \
|
|
(((toast_compress_header *) (ptr))->tcinfo & VARLENA_EXTSIZE_MASK)
|
|
#define TOAST_COMPRESS_METHOD(ptr) \
|
|
(((toast_compress_header *) (ptr))->tcinfo >> VARLENA_EXTSIZE_BITS)
|
|
|
|
#define TOAST_COMPRESS_SET_SIZE_AND_COMPRESS_METHOD(ptr, len, cm_method) \
|
|
do { \
|
|
Assert((len) > 0 && (len) <= VARLENA_EXTSIZE_MASK); \
|
|
Assert((cm_method) == TOAST_PGLZ_COMPRESSION_ID || \
|
|
(cm_method) == TOAST_LZ4_COMPRESSION_ID); \
|
|
((toast_compress_header *) (ptr))->tcinfo = \
|
|
(len) | ((uint32) (cm_method) << VARLENA_EXTSIZE_BITS); \
|
|
} while (0)
|
|
|
|
extern Datum toast_compress_datum(Datum value, char cmethod);
|
|
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 */
|