@ -55,8 +55,8 @@
/*
/*
* struct varatt_external is a traditional " TOAST pointer " , that is , the
* struct varatt_external is a traditional " TOAST pointer " , that is , the
* information needed to fetch a Datum stored out - of - line in a TOAST table .
* information needed to fetch a Datum stored out - of - line in a TOAST table .
* The data is compressed if and only if the size stored in va_extinfo <
* The data is compressed if and only if the external size stored in
* va_rawsize - VARHDRSZ .
* va_extinfo is less than va_ rawsize - VARHDRSZ .
*
*
* This struct must not contain any padding , because we sometimes compare
* This struct must not contain any padding , because we sometimes compare
* these pointers using memcmp .
* these pointers using memcmp .
@ -75,6 +75,13 @@ typedef struct varatt_external
Oid va_toastrelid ; /* RelID of TOAST table containing it */
Oid va_toastrelid ; /* RelID of TOAST table containing it */
} varatt_external ;
} varatt_external ;
/*
* These macros define the " saved size " portion of va_extinfo . Its remaining
* two high - order bits identify the compression method .
*/
# define VARLENA_EXTSIZE_BITS 30
# define VARLENA_EXTSIZE_MASK ((1U << VARLENA_EXTSIZE_BITS) - 1)
/*
/*
* struct varatt_indirect is a " TOAST pointer " representing an out - of - line
* struct varatt_indirect is a " TOAST pointer " representing an out - of - line
* Datum that ' s stored in memory , not in an external toast relation .
* Datum that ' s stored in memory , not in an external toast relation .
@ -149,7 +156,7 @@ typedef union
{
{
uint32 va_header ;
uint32 va_header ;
uint32 va_tcinfo ; /* Original data size (excludes header) and
uint32 va_tcinfo ; /* Original data size (excludes header) and
* compression method */
* compression method ; see va_extinfo */
char va_data [ FLEXIBLE_ARRAY_MEMBER ] ; /* Compressed data */
char va_data [ FLEXIBLE_ARRAY_MEMBER ] ; /* Compressed data */
} va_compressed ;
} va_compressed ;
} varattrib_4b ;
} varattrib_4b ;
@ -235,6 +242,7 @@ typedef struct
# define SET_VARTAG_1B_E(PTR,tag) \
# define SET_VARTAG_1B_E(PTR,tag) \
( ( ( varattrib_1b_e * ) ( PTR ) ) - > va_header = 0x80 , \
( ( ( varattrib_1b_e * ) ( PTR ) ) - > va_header = 0x80 , \
( ( varattrib_1b_e * ) ( PTR ) ) - > va_tag = ( tag ) )
( ( varattrib_1b_e * ) ( PTR ) ) - > va_tag = ( tag ) )
# else /* !WORDS_BIGENDIAN */
# else /* !WORDS_BIGENDIAN */
# define VARATT_IS_4B(PTR) \
# define VARATT_IS_4B(PTR) \
@ -267,36 +275,28 @@ typedef struct
# define SET_VARTAG_1B_E(PTR,tag) \
# define SET_VARTAG_1B_E(PTR,tag) \
( ( ( varattrib_1b_e * ) ( PTR ) ) - > va_header = 0x01 , \
( ( ( varattrib_1b_e * ) ( PTR ) ) - > va_header = 0x01 , \
( ( varattrib_1b_e * ) ( PTR ) ) - > va_tag = ( tag ) )
( ( varattrib_1b_e * ) ( PTR ) ) - > va_tag = ( tag ) )
# endif /* WORDS_BIGENDIAN */
# define VARHDRSZ_SHORT offsetof(varattrib_1b, va_data)
# endif /* WORDS_BIGENDIAN */
# define VARATT_SHORT_MAX 0x7F
# define VARATT_CAN_MAKE_SHORT(PTR) \
( VARATT_IS_4B_U ( PTR ) & & \
( VARSIZE ( PTR ) - VARHDRSZ + VARHDRSZ_SHORT ) < = VARATT_SHORT_MAX )
# define VARATT_CONVERTED_SHORT_SIZE(PTR) \
( VARSIZE ( PTR ) - VARHDRSZ + VARHDRSZ_SHORT )
# define VARHDRSZ_EXTERNAL offsetof(varattrib_1b_e, va_data)
# define VARHDRSZ_COMPRESS offsetof(varattrib_4b, va_compressed.va_data)
# define VARDATA_4B(PTR) (((varattrib_4b *) (PTR))->va_4byte.va_data)
# define VARDATA_4B(PTR) (((varattrib_4b *) (PTR))->va_4byte.va_data)
# define VARDATA_4B_C(PTR) (((varattrib_4b *) (PTR))->va_compressed.va_data)
# define VARDATA_4B_C(PTR) (((varattrib_4b *) (PTR))->va_compressed.va_data)
# define VARDATA_1B(PTR) (((varattrib_1b *) (PTR))->va_data)
# define VARDATA_1B(PTR) (((varattrib_1b *) (PTR))->va_data)
# define VARDATA_1B_E(PTR) (((varattrib_1b_e *) (PTR))->va_data)
# define VARDATA_1B_E(PTR) (((varattrib_1b_e *) (PTR))->va_data)
# define VARLENA_RAWSIZE_BITS 30
# define VARLENA_RAWSIZE_MASK ((1U << VARLENA_RAWSIZE_BITS) - 1)
/*
/*
* va_tcinfo in va_compress contains raw size of datum and compression method .
* Externally visible TOAST macros begin here .
*/
*/
# define VARRAWSIZE_4B_C(PTR) \
( ( ( varattrib_4b * ) ( PTR ) ) - > va_compressed . va_tcinfo & VARLENA_RAWSIZE_MASK )
# define VARCOMPRESS_4B_C(PTR) \
( ( ( varattrib_4b * ) ( PTR ) ) - > va_compressed . va_tcinfo > > VARLENA_RAWSIZE_BITS )
/* Externally visible macros */
# define VARHDRSZ_EXTERNAL offsetof(varattrib_1b_e, va_data)
# define VARHDRSZ_COMPRESSED offsetof(varattrib_4b, va_compressed.va_data)
# define VARHDRSZ_SHORT offsetof(varattrib_1b, va_data)
# define VARATT_SHORT_MAX 0x7F
# define VARATT_CAN_MAKE_SHORT(PTR) \
( VARATT_IS_4B_U ( PTR ) & & \
( VARSIZE ( PTR ) - VARHDRSZ + VARHDRSZ_SHORT ) < = VARATT_SHORT_MAX )
# define VARATT_CONVERTED_SHORT_SIZE(PTR) \
( VARSIZE ( PTR ) - VARHDRSZ + VARHDRSZ_SHORT )
/*
/*
* In consumers oblivious to data alignment , call PG_DETOAST_DATUM_PACKED ( ) ,
* In consumers oblivious to data alignment , call PG_DETOAST_DATUM_PACKED ( ) ,
@ -336,35 +336,6 @@ typedef struct
( VARATT_IS_EXTERNAL ( PTR ) & & VARTAG_IS_EXPANDED ( VARTAG_EXTERNAL ( PTR ) ) )
( VARATT_IS_EXTERNAL ( PTR ) & & VARTAG_IS_EXPANDED ( VARTAG_EXTERNAL ( PTR ) ) )
# define VARATT_IS_EXTERNAL_NON_EXPANDED(PTR) \
# define VARATT_IS_EXTERNAL_NON_EXPANDED(PTR) \
( VARATT_IS_EXTERNAL ( PTR ) & & ! VARTAG_IS_EXPANDED ( VARTAG_EXTERNAL ( PTR ) ) )
( VARATT_IS_EXTERNAL ( PTR ) & & ! VARTAG_IS_EXPANDED ( VARTAG_EXTERNAL ( PTR ) ) )
/*
* va_extinfo in varatt_external contains actual length of the external data
* and compression method if external data is compressed .
*/
# define VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer) \
( ( toast_pointer ) . va_extinfo & VARLENA_RAWSIZE_MASK )
# define VARATT_EXTERNAL_SET_SIZE_AND_COMPRESSION(toast_pointer, len, cm) \
do { \
Assert ( ( cm ) = = TOAST_PGLZ_COMPRESSION_ID | | \
( cm ) = = TOAST_LZ4_COMPRESSION_ID ) ; \
( ( toast_pointer ) . va_extinfo = ( len ) | ( cm ) < < VARLENA_RAWSIZE_BITS ) ; \
} while ( 0 )
# define VARATT_EXTERNAL_GET_COMPRESSION(PTR) \
( ( toast_pointer ) . va_extinfo > > VARLENA_RAWSIZE_BITS )
/*
* Testing whether an externally - stored value is compressed now requires
* comparing size stored in va_extinfo ( 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) \
( VARATT_EXTERNAL_GET_EXTSIZE ( toast_pointer ) < \
( toast_pointer ) . va_rawsize - VARHDRSZ )
# define VARATT_IS_SHORT(PTR) VARATT_IS_1B(PTR)
# define VARATT_IS_SHORT(PTR) VARATT_IS_1B(PTR)
# define VARATT_IS_EXTENDED(PTR) (!VARATT_IS_4B_U(PTR))
# define VARATT_IS_EXTENDED(PTR) (!VARATT_IS_4B_U(PTR))
@ -390,6 +361,37 @@ typedef struct
# define VARDATA_ANY(PTR) \
# define VARDATA_ANY(PTR) \
( VARATT_IS_1B ( PTR ) ? VARDATA_1B ( PTR ) : VARDATA_4B ( PTR ) )
( VARATT_IS_1B ( PTR ) ? VARDATA_1B ( PTR ) : VARDATA_4B ( PTR ) )
/* Decompressed size and compression method of an external compressed Datum */
# define VARDATA_COMPRESSED_GET_EXTSIZE(PTR) \
( ( ( varattrib_4b * ) ( PTR ) ) - > va_compressed . va_tcinfo & VARLENA_EXTSIZE_MASK )
# define VARDATA_COMPRESSED_GET_COMPRESS_METHOD(PTR) \
( ( ( varattrib_4b * ) ( PTR ) ) - > va_compressed . va_tcinfo > > VARLENA_EXTSIZE_BITS )
/* Same, when working directly with a struct varatt_external */
# define VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer) \
( ( toast_pointer ) . va_extinfo & VARLENA_EXTSIZE_MASK )
# define VARATT_EXTERNAL_GET_COMPRESS_METHOD(toast_pointer) \
( ( toast_pointer ) . va_extinfo > > VARLENA_EXTSIZE_BITS )
# define VARATT_EXTERNAL_SET_SIZE_AND_COMPRESS_METHOD(toast_pointer, len, cm) \
do { \
Assert ( ( cm ) = = TOAST_PGLZ_COMPRESSION_ID | | \
( cm ) = = TOAST_LZ4_COMPRESSION_ID ) ; \
( ( toast_pointer ) . va_extinfo = \
( len ) | ( ( uint32 ) ( cm ) < < VARLENA_EXTSIZE_BITS ) ) ; \
} while ( 0 )
/*
* Testing whether an externally - stored value is compressed now requires
* comparing size stored in va_extinfo ( 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) \
( VARATT_EXTERNAL_GET_EXTSIZE ( toast_pointer ) < \
( toast_pointer ) . va_rawsize - VARHDRSZ )
/* ----------------------------------------------------------------
/* ----------------------------------------------------------------
* Section 2 : Datum type + support macros
* Section 2 : Datum type + support macros