@@ -328,7 +328,8 @@ typedef struct
328
328
#define VARDATA_COMPRESSED_GET_EXTSIZE (PTR ) \
329
329
(((varattrib_4b *) (PTR))->va_compressed.va_tcinfo & VARLENA_EXTSIZE_MASK)
330
330
#define VARDATA_COMPRESSED_GET_COMPRESS_METHOD (PTR ) \
331
- (((varattrib_4b *) (PTR))->va_compressed.va_tcinfo >> VARLENA_EXTSIZE_BITS)
331
+ ( (VARATT_IS_4BCE(PTR)) ? (VARATT_4BCE_CMP_METHOD(VARATT_4BCE_HDR_PTR(PTR)->ext_hdr)) \
332
+ : (((varattrib_4b *) (PTR))->va_compressed.va_tcinfo >> VARLENA_EXTSIZE_BITS))
332
333
333
334
/* Same for external Datums; but note argument is a struct varatt_external */
334
335
#define VARATT_EXTERNAL_GET_EXTSIZE (toast_pointer ) \
@@ -340,8 +341,17 @@ typedef struct
340
341
do { \
341
342
Assert((cm) == TOAST_PGLZ_COMPRESSION_ID || \
342
343
(cm) == TOAST_LZ4_COMPRESSION_ID); \
343
- ((toast_pointer).va_extinfo = \
344
- (len) | ((uint32) (cm) << VARLENA_EXTSIZE_BITS)); \
344
+ if ((cm) <= TOAST_LAST_COMPRESSION_ID_BEFORE_EXT) \
345
+ { \
346
+ /* Store the actual method in va_extinfo */ \
347
+ ((toast_pointer ).va_extinfo = \
348
+ (len ) | ((uint32 ) (cm ) << VARLENA_EXTSIZE_BITS )); \
349
+ } \
350
+ else \
351
+ { \
352
+ /* Store 11 in the top bits, meaning "extended" method. */ \
353
+ (toast_pointer ).va_extinfo = (uint32 )(len ) | (VARATT_4BCE_MASK << VARLENA_EXTSIZE_BITS ); \
354
+ } \
345
355
} while (0 )
346
356
347
357
/*
@@ -355,4 +365,61 @@ typedef struct
355
365
(VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer) < \
356
366
(toast_pointer).va_rawsize - VARHDRSZ)
357
367
368
+ typedef struct varatt_cmp_extended
369
+ {
370
+ uint32 ext_hdr ; /* [ size:24 | type:8 ] */
371
+ char ext_data [FLEXIBLE_ARRAY_MEMBER ]; /* algorithm-specific meta */
372
+ } varatt_cmp_extended ;
373
+
374
+ /*--------------------------------------------------------------------*/
375
+ /* 1) Detect the extended compression */
376
+ /* (top-2 mode bits of va_tcinfo are 0b11) */
377
+ #define VARATT_4BCE_MASK 0x0003
378
+
379
+ #define VARATT_IS_4BCE (ptr ) \
380
+ ((((varattrib_4b*)(ptr))->va_compressed.va_tcinfo >> VARLENA_EXTSIZE_BITS) \
381
+ == VARATT_4BCE_MASK)
382
+
383
+ /*--------------------------------------------------------------------*/
384
+ /* 2) Pointer to varatt_cmp_extended header (just after the 8-byte varlena head) */
385
+ #define VARATT_4BCE_HDR_PTR (ptr ) ((varatt_cmp_extended*)(((char*)(ptr)) + VARHDRSZ_COMPRESSED))
386
+ #define VARATT_4BCE_GET_HDR (ptr ) ((uint32)(VARATT_4BCE_HDR_PTR(ptr)->ext_hdr))
387
+
388
+ /*--------------------------------------------------------------------*/
389
+ /* 3) The 32-bit ext_hdr */
390
+ /* Layout: [ meta size:24 bits | type:8 bits ] */
391
+ #define VARATT_4BCE_TYPE_MASK 0x000000FF /* low-order 8 bits */
392
+ #define VARATT_4BCE_SIZE_MASK 0xFFFFFF00 /* high-order 24 bits */
393
+
394
+ #define VARATT_4BCE_SET_HDR (hdr , type , size24 ) \
395
+ do { \
396
+ Assert((uint32)(type) <= VARATT_4BCE_TYPE_MASK); /* 8 bits */ \
397
+ Assert ((uint32 )(size24 ) <= (VARATT_4BCE_SIZE_MASK >> 8 )); \
398
+ (hdr ) = ( ((uint32 )(type )) ) | ( ((uint32 )(size24 ) << 8 ) ); \
399
+ } while (0 )
400
+
401
+ #define VARATT_4BCE_CMP_METHOD (hdr ) ( (uint8) ((hdr) & VARATT_4BCE_TYPE_MASK) )
402
+ #define VARATT_4BCE_META_SIZE (hdr ) ( ((hdr) & VARATT_4BCE_SIZE_MASK) >> 8)
403
+
404
+ /*--------------------------------------------------------------------*/
405
+ /* 4) Derived helpers to jump inside the extension block */
406
+
407
+ /* -> metadata begins immediately after the 4-byte ext header */
408
+ #define VARATT_4BCE_META_PTR (ptr ) ( (void*) VARATT_4BCE_HDR_PTR(ptr)->ext_data )
409
+
410
+ /* -> compressed bytes begins after metadata */
411
+ #define VARATT_4BCE_DATA_PTR (ptr ) \
412
+ ( (void*)( (char*)VARATT_4BCE_META_PTR(ptr) \
413
+ + VARATT_4BCE_META_SIZE(VARATT_4BCE_HDR_PTR(ptr)->ext_hdr) ) )
414
+
415
+ /* -> payload byte count */
416
+ #define VARATT_4BCE_DATA_SIZE (ptr ) \
417
+ ( VARSIZE_4B(ptr) \
418
+ - VARHDRSZ_COMPRESSED \
419
+ - sizeof(varatt_cmp_extended) \
420
+ - VARATT_4BCE_META_SIZE(VARATT_4BCE_HDR_PTR(ptr)->ext_hdr) )
421
+
422
+ /* Expects varatt_cmp_extended pointer */
423
+ #define VARATT_4BCE_HDRSZ (ptr ) (VARHDRSZ_COMPRESSED + sizeof(varatt_cmp_extended) + VARATT_4BCE_META_SIZE((ptr)->ext_hdr))
424
+
358
425
#endif
0 commit comments