PostgreSQL Source Code git master
Loading...
Searching...
No Matches
toast_compression.c File Reference
#include "postgres.h"
#include "access/detoast.h"
#include "access/toast_compression.h"
#include "common/pg_lzcompress.h"
#include "varatt.h"
Include dependency graph for toast_compression.c:

Go to the source code of this file.

Macros

#define NO_COMPRESSION_SUPPORT(method)
 

Functions

struct varlenapglz_compress_datum (const struct varlena *value)
 
struct varlenapglz_decompress_datum (const struct varlena *value)
 
struct varlenapglz_decompress_datum_slice (const struct varlena *value, int32 slicelength)
 
struct varlenalz4_compress_datum (const struct varlena *value)
 
struct varlenalz4_decompress_datum (const struct varlena *value)
 
struct varlenalz4_decompress_datum_slice (const struct varlena *value, int32 slicelength)
 
ToastCompressionId toast_get_compression_id (struct varlena *attr)
 
char CompressionNameToMethod (const char *compression)
 
const charGetCompressionMethodName (char method)
 

Variables

int default_toast_compression = TOAST_PGLZ_COMPRESSION
 

Macro Definition Documentation

◆ NO_COMPRESSION_SUPPORT

#define NO_COMPRESSION_SUPPORT (   method)
Value:
errmsg("compression method %s not supported", method), \
errdetail("This functionality requires the server to be built with %s support.", method)))
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
static int fb(int x)

Definition at line 28 of file toast_compression.c.

40{
42 len;
43 struct varlena *tmp = NULL;
44
46
47 /*
48 * No point in wasting a palloc cycle if value size is outside the allowed
49 * range for compression.
50 */
51 if (valsize < PGLZ_strategy_default->min_input_size ||
53 return NULL;
54
55 /*
56 * Figure out the maximum possible size of the pglz output, add the bytes
57 * that will be needed for varlena overhead, and allocate that amount.
58 */
59 tmp = (struct varlena *) palloc(PGLZ_MAX_OUTPUT(valsize) +
61
63 valsize,
64 (char *) tmp + VARHDRSZ_COMPRESSED,
65 NULL);
66 if (len < 0)
67 {
68 pfree(tmp);
69 return NULL;
70 }
71
73
74 return tmp;
75}
76
77/*
78 * Decompress a varlena that was compressed using PGLZ.
79 */
80struct varlena *
82{
83 struct varlena *result;
85
86 /* allocate memory for the uncompressed data */
88
89 /* decompress the data */
92 VARDATA(result),
94 if (rawsize < 0)
97 errmsg_internal("compressed pglz data is corrupt")));
98
99 SET_VARSIZE(result, rawsize + VARHDRSZ);
100
101 return result;
102}
103
104/*
105 * Decompress part of a varlena that was compressed using PGLZ.
106 */
107struct varlena *
110{
111 struct varlena *result;
113
114 /* allocate memory for the uncompressed data */
115 result = (struct varlena *) palloc(slicelength + VARHDRSZ);
116
117 /* decompress the data */
120 VARDATA(result),
121 slicelength, false);
122 if (rawsize < 0)
125 errmsg_internal("compressed pglz data is corrupt")));
126
127 SET_VARSIZE(result, rawsize + VARHDRSZ);
128
129 return result;
130}
131
132/*
133 * Compress a varlena using LZ4.
134 *
135 * Returns the compressed varlena, or NULL if compression fails.
136 */
137struct varlena *
138lz4_compress_datum(const struct varlena *value)
139{
140#ifndef USE_LZ4
142 return NULL; /* keep compiler quiet */
143#else
145 int32 len;
146 int32 max_size;
147 struct varlena *tmp = NULL;
148
150
151 /*
152 * Figure out the maximum possible size of the LZ4 output, add the bytes
153 * that will be needed for varlena overhead, and allocate that amount.
154 */
155 max_size = LZ4_compressBound(valsize);
156 tmp = (struct varlena *) palloc(max_size + VARHDRSZ_COMPRESSED);
157
159 (char *) tmp + VARHDRSZ_COMPRESSED,
160 valsize, max_size);
161 if (len <= 0)
162 elog(ERROR, "lz4 compression failed");
163
164 /* data is incompressible so just free the memory and return NULL */
165 if (len > valsize)
166 {
167 pfree(tmp);
168 return NULL;
169 }
170
172
173 return tmp;
174#endif
175}
176
177/*
178 * Decompress a varlena that was compressed using LZ4.
179 */
180struct varlena *
182{
183#ifndef USE_LZ4
185 return NULL; /* keep compiler quiet */
186#else
188 struct varlena *result;
189
190 /* allocate memory for the uncompressed data */
192
193 /* decompress the data */
195 VARDATA(result),
198 if (rawsize < 0)
201 errmsg_internal("compressed lz4 data is corrupt")));
202
203
204 SET_VARSIZE(result, rawsize + VARHDRSZ);
205
206 return result;
207#endif
208}
209
210/*
211 * Decompress part of a varlena that was compressed using LZ4.
212 */
213struct varlena *
215{
216#ifndef USE_LZ4
218 return NULL; /* keep compiler quiet */
219#else
221 struct varlena *result;
222
223 /* slice decompression not supported prior to 1.8.3 */
224 if (LZ4_versionNumber() < 10803)
226
227 /* allocate memory for the uncompressed data */
228 result = (struct varlena *) palloc(slicelength + VARHDRSZ);
229
230 /* decompress the data */
232 VARDATA(result),
236 if (rawsize < 0)
239 errmsg_internal("compressed lz4 data is corrupt")));
240
241 SET_VARSIZE(result, rawsize + VARHDRSZ);
242
243 return result;
244#endif
245}
246
247/*
248 * Extract compression ID from a varlena.
249 *
250 * Returns TOAST_INVALID_COMPRESSION_ID if the varlena is not compressed.
251 */
254{
256
257 /*
258 * If it is stored externally then fetch the compression method id from
259 * the external toast pointer. If compressed inline, fetch it from the
260 * toast compression header.
261 */
263 {
264 struct varatt_external toast_pointer;
265
266 VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
267
268 if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
270 }
271 else if (VARATT_IS_COMPRESSED(attr))
273
274 return cmid;
275}
276
277/*
278 * CompressionNameToMethod - Get compression method from compression name
279 *
280 * Search in the available built-in methods. If the compression not found
281 * in the built-in methods then return InvalidCompressionMethod.
282 */
283char
284CompressionNameToMethod(const char *compression)
285{
286 if (strcmp(compression, "pglz") == 0)
288 else if (strcmp(compression, "lz4") == 0)
289 {
290#ifndef USE_LZ4
292#endif
294 }
295
297}
298
299/*
300 * GetCompressionMethodName - Get compression method name
301 */
302const char *
303GetCompressionMethodName(char method)
304{
305 switch (method)
306 {
308 return "pglz";
310 return "lz4";
311 default:
312 elog(ERROR, "invalid compression method %c", method);
313 return NULL; /* keep compiler quiet */
314 }
315}
#define VARHDRSZ
Definition c.h:711
int32_t int32
Definition c.h:542
#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr)
Definition detoast.h:22
int errmsg_internal(const char *fmt,...)
Definition elog.c:1170
#define elog(elevel,...)
Definition elog.h:226
static struct @172 value
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc(Size size)
Definition mcxt.c:1387
#define ERRCODE_DATA_CORRUPTED
const void size_t len
const PGLZ_Strategy *const PGLZ_strategy_default
int32 pglz_decompress(const char *source, int32 slen, char *dest, int32 rawsize, bool check_complete)
int32 pglz_compress(const char *source, int32 slen, char *dest, const PGLZ_Strategy *strategy)
#define PGLZ_MAX_OUTPUT(_dlen)
Definition c.h:706
#define NO_COMPRESSION_SUPPORT(method)
const char * GetCompressionMethodName(char method)
struct varlena * pglz_decompress_datum(const struct varlena *value)
struct varlena * lz4_compress_datum(const struct varlena *value)
struct varlena * pglz_decompress_datum_slice(const struct varlena *value, int32 slicelength)
struct varlena * lz4_decompress_datum(const struct varlena *value)
struct varlena * lz4_decompress_datum_slice(const struct varlena *value, int32 slicelength)
char CompressionNameToMethod(const char *compression)
ToastCompressionId toast_get_compression_id(struct varlena *attr)
ToastCompressionId
@ TOAST_INVALID_COMPRESSION_ID
#define TOAST_PGLZ_COMPRESSION
#define InvalidCompressionMethod
#define TOAST_LZ4_COMPRESSION
static Size VARDATA_COMPRESSED_GET_EXTSIZE(const void *PTR)
Definition varatt.h:493
static void SET_VARSIZE_COMPRESSED(void *PTR, Size len)
Definition varatt.h:446
static bool VARATT_IS_EXTERNAL_ONDISK(const void *PTR)
Definition varatt.h:361
static uint32 VARDATA_COMPRESSED_GET_COMPRESS_METHOD(const void *PTR)
Definition varatt.h:500
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition varatt.h:472
static Size VARSIZE(const void *PTR)
Definition varatt.h:298
static char * VARDATA(const void *PTR)
Definition varatt.h:305
static char * VARDATA_ANY(const void *PTR)
Definition varatt.h:486
static bool VARATT_IS_COMPRESSED(const void *PTR)
Definition varatt.h:347
#define VARHDRSZ_COMPRESSED
Definition varatt.h:277
static uint32 VARATT_EXTERNAL_GET_COMPRESS_METHOD(struct varatt_external toast_pointer)
Definition varatt.h:513
static bool VARATT_EXTERNAL_IS_COMPRESSED(struct varatt_external toast_pointer)
Definition varatt.h:536
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432

Function Documentation

◆ CompressionNameToMethod()

char CompressionNameToMethod ( const char compression)

Definition at line 285 of file toast_compression.c.

286{
287 if (strcmp(compression, "pglz") == 0)
289 else if (strcmp(compression, "lz4") == 0)
290 {
291#ifndef USE_LZ4
293#endif
295 }
296
298}

References fb(), InvalidCompressionMethod, NO_COMPRESSION_SUPPORT, TOAST_LZ4_COMPRESSION, and TOAST_PGLZ_COMPRESSION.

Referenced by GetAttributeCompression().

◆ GetCompressionMethodName()

const char * GetCompressionMethodName ( char  method)

Definition at line 304 of file toast_compression.c.

305{
306 switch (method)
307 {
309 return "pglz";
311 return "lz4";
312 default:
313 elog(ERROR, "invalid compression method %c", method);
314 return NULL; /* keep compiler quiet */
315 }
316}

References elog, ERROR, fb(), TOAST_LZ4_COMPRESSION, and TOAST_PGLZ_COMPRESSION.

Referenced by getAttributesList(), MergeAttributes(), and transformTableLikeClause().

◆ lz4_compress_datum()

struct varlena * lz4_compress_datum ( const struct varlena value)

Definition at line 139 of file toast_compression.c.

140{
141#ifndef USE_LZ4
143 return NULL; /* keep compiler quiet */
144#else
146 int32 len;
147 int32 max_size;
148 struct varlena *tmp = NULL;
149
151
152 /*
153 * Figure out the maximum possible size of the LZ4 output, add the bytes
154 * that will be needed for varlena overhead, and allocate that amount.
155 */
156 max_size = LZ4_compressBound(valsize);
157 tmp = (struct varlena *) palloc(max_size + VARHDRSZ_COMPRESSED);
158
160 (char *) tmp + VARHDRSZ_COMPRESSED,
161 valsize, max_size);
162 if (len <= 0)
163 elog(ERROR, "lz4 compression failed");
164
165 /* data is incompressible so just free the memory and return NULL */
166 if (len > valsize)
167 {
168 pfree(tmp);
169 return NULL;
170 }
171
173
174 return tmp;
175#endif
176}

References elog, ERROR, fb(), len, NO_COMPRESSION_SUPPORT, palloc(), pfree(), SET_VARSIZE_COMPRESSED(), value, VARDATA_ANY(), VARHDRSZ_COMPRESSED, and VARSIZE_ANY_EXHDR().

Referenced by toast_compress_datum().

◆ lz4_decompress_datum()

struct varlena * lz4_decompress_datum ( const struct varlena value)

Definition at line 182 of file toast_compression.c.

183{
184#ifndef USE_LZ4
186 return NULL; /* keep compiler quiet */
187#else
189 struct varlena *result;
190
191 /* allocate memory for the uncompressed data */
193
194 /* decompress the data */
196 VARDATA(result),
199 if (rawsize < 0)
202 errmsg_internal("compressed lz4 data is corrupt")));
203
204
205 SET_VARSIZE(result, rawsize + VARHDRSZ);
206
207 return result;
208#endif
209}

References ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg_internal(), ERROR, fb(), NO_COMPRESSION_SUPPORT, palloc(), SET_VARSIZE(), value, VARDATA(), VARDATA_COMPRESSED_GET_EXTSIZE(), VARHDRSZ, VARHDRSZ_COMPRESSED, and VARSIZE().

Referenced by lz4_decompress_datum_slice(), and toast_decompress_datum().

◆ lz4_decompress_datum_slice()

struct varlena * lz4_decompress_datum_slice ( const struct varlena value,
int32  slicelength 
)

Definition at line 215 of file toast_compression.c.

216{
217#ifndef USE_LZ4
219 return NULL; /* keep compiler quiet */
220#else
222 struct varlena *result;
223
224 /* slice decompression not supported prior to 1.8.3 */
225 if (LZ4_versionNumber() < 10803)
227
228 /* allocate memory for the uncompressed data */
229 result = (struct varlena *) palloc(slicelength + VARHDRSZ);
230
231 /* decompress the data */
233 VARDATA(result),
237 if (rawsize < 0)
240 errmsg_internal("compressed lz4 data is corrupt")));
241
242 SET_VARSIZE(result, rawsize + VARHDRSZ);
243
244 return result;
245#endif
246}

References ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg_internal(), ERROR, fb(), lz4_decompress_datum(), NO_COMPRESSION_SUPPORT, palloc(), SET_VARSIZE(), value, VARDATA(), VARHDRSZ, VARHDRSZ_COMPRESSED, and VARSIZE().

Referenced by toast_decompress_datum_slice().

◆ pglz_compress_datum()

struct varlena * pglz_compress_datum ( const struct varlena value)

Definition at line 40 of file toast_compression.c.

41{
43 len;
44 struct varlena *tmp = NULL;
45
47
48 /*
49 * No point in wasting a palloc cycle if value size is outside the allowed
50 * range for compression.
51 */
52 if (valsize < PGLZ_strategy_default->min_input_size ||
54 return NULL;
55
56 /*
57 * Figure out the maximum possible size of the pglz output, add the bytes
58 * that will be needed for varlena overhead, and allocate that amount.
59 */
60 tmp = (struct varlena *) palloc(PGLZ_MAX_OUTPUT(valsize) +
62
64 valsize,
65 (char *) tmp + VARHDRSZ_COMPRESSED,
66 NULL);
67 if (len < 0)
68 {
69 pfree(tmp);
70 return NULL;
71 }
72
74
75 return tmp;
76}

References fb(), len, PGLZ_Strategy::max_input_size, palloc(), pfree(), pglz_compress(), PGLZ_MAX_OUTPUT, PGLZ_strategy_default, SET_VARSIZE_COMPRESSED(), value, VARDATA_ANY(), VARHDRSZ_COMPRESSED, and VARSIZE_ANY_EXHDR().

Referenced by toast_compress_datum().

◆ pglz_decompress_datum()

struct varlena * pglz_decompress_datum ( const struct varlena value)

Definition at line 82 of file toast_compression.c.

83{
84 struct varlena *result;
86
87 /* allocate memory for the uncompressed data */
89
90 /* decompress the data */
93 VARDATA(result),
95 if (rawsize < 0)
98 errmsg_internal("compressed pglz data is corrupt")));
99
100 SET_VARSIZE(result, rawsize + VARHDRSZ);
101
102 return result;
103}

References ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg_internal(), ERROR, fb(), palloc(), pglz_decompress(), SET_VARSIZE(), value, VARDATA(), VARDATA_COMPRESSED_GET_EXTSIZE(), VARHDRSZ, VARHDRSZ_COMPRESSED, and VARSIZE().

Referenced by toast_decompress_datum().

◆ pglz_decompress_datum_slice()

struct varlena * pglz_decompress_datum_slice ( const struct varlena value,
int32  slicelength 
)

Definition at line 109 of file toast_compression.c.

111{
112 struct varlena *result;
114
115 /* allocate memory for the uncompressed data */
116 result = (struct varlena *) palloc(slicelength + VARHDRSZ);
117
118 /* decompress the data */
121 VARDATA(result),
122 slicelength, false);
123 if (rawsize < 0)
126 errmsg_internal("compressed pglz data is corrupt")));
127
128 SET_VARSIZE(result, rawsize + VARHDRSZ);
129
130 return result;
131}

References ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg_internal(), ERROR, fb(), palloc(), pglz_decompress(), SET_VARSIZE(), value, VARDATA(), VARHDRSZ, VARHDRSZ_COMPRESSED, and VARSIZE().

Referenced by toast_decompress_datum_slice().

◆ toast_get_compression_id()

ToastCompressionId toast_get_compression_id ( struct varlena attr)

Definition at line 254 of file toast_compression.c.

255{
257
258 /*
259 * If it is stored externally then fetch the compression method id from
260 * the external toast pointer. If compressed inline, fetch it from the
261 * toast compression header.
262 */
264 {
265 struct varatt_external toast_pointer;
266
267 VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
268
269 if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
271 }
272 else if (VARATT_IS_COMPRESSED(attr))
274
275 return cmid;
276}

References fb(), TOAST_INVALID_COMPRESSION_ID, VARATT_EXTERNAL_GET_COMPRESS_METHOD(), VARATT_EXTERNAL_GET_POINTER, VARATT_EXTERNAL_IS_COMPRESSED(), VARATT_IS_COMPRESSED(), VARATT_IS_EXTERNAL_ONDISK(), and VARDATA_COMPRESSED_GET_COMPRESS_METHOD().

Referenced by pg_column_compression().

Variable Documentation

◆ default_toast_compression

int default_toast_compression = TOAST_PGLZ_COMPRESSION

Definition at line 26 of file toast_compression.c.

Referenced by toast_compress_datum().