From d742d81036168e42c16772c76b2599ab966db025 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Veldanda Date: Thu, 24 Sep 2026 00:30:27 -0700 Subject: [PATCH v3 3/5] Decode the compression method in toast_external_info_get() The compression method of an external value was fetched by each caller from the raw method bits of va_extinfo, with VARATT_EXTINFO_GET_COMPRESS_METHOD(). Decode it once instead, in toast_external_info_get(), into a new compress_method field of toast_external_data, and make detoast_attr_slice(), toast_get_compression_id() and amcheck read it from there. This leaves toast_external_info_get() as the only place that knows how the method is encoded in a TOAST pointer, which will matter once the encoding is not the same for all methods. detoast.h now includes toast_compression.h, for ToastCompressionId. No behavior change. --- contrib/amcheck/verify_heapam.c | 2 +- src/backend/access/common/detoast.c | 4 ++-- src/backend/access/common/toast_compression.c | 2 +- src/include/access/detoast.h | 10 +++++++++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index c6e272ff0ec..56c68a995a5 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -1816,7 +1816,7 @@ check_tuple_attribute(HeapCheckContext *ctx) bool valid = false; /* Compressed attributes should have a valid compression method */ - cmid = VARATT_EXTINFO_GET_COMPRESS_METHOD(toast_ext_data.extinfo); + cmid = toast_ext_data.compress_method; switch (cmid) { /* List of all valid compression method IDs */ diff --git a/src/backend/access/common/detoast.c b/src/backend/access/common/detoast.c index 741421963ba..25140372238 100644 --- a/src/backend/access/common/detoast.c +++ b/src/backend/access/common/detoast.c @@ -227,12 +227,12 @@ detoast_attr_slice(varlena *attr, { toast_external_data toast_ext_data; int32 extsize; - uint32 compress_method; + ToastCompressionId compress_method; bool is_compressed; toast_external_info_get(attr, &toast_ext_data); extsize = VARATT_EXTINFO_GET_EXTSIZE(toast_ext_data.extinfo); - compress_method = VARATT_EXTINFO_GET_COMPRESS_METHOD(toast_ext_data.extinfo); + compress_method = toast_ext_data.compress_method; is_compressed = VARATT_EXTINFO_IS_COMPRESSED(toast_ext_data.extinfo, toast_ext_data.rawsize); /* fast path for non-compressed external datums */ diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c index 09cdf880e4f..8bb871c9791 100644 --- a/src/backend/access/common/toast_compression.c +++ b/src/backend/access/common/toast_compression.c @@ -267,7 +267,7 @@ toast_get_compression_id(varlena *attr) toast_external_info_get(attr, &toast_ext_data); if (VARATT_EXTINFO_IS_COMPRESSED(toast_ext_data.extinfo, toast_ext_data.rawsize)) - cmid = VARATT_EXTINFO_GET_COMPRESS_METHOD(toast_ext_data.extinfo); + cmid = toast_ext_data.compress_method; } else if (VARATT_IS_COMPRESSED(attr)) cmid = VARDATA_COMPRESSED_GET_COMPRESS_METHOD(attr); diff --git a/src/include/access/detoast.h b/src/include/access/detoast.h index 93b7a253760..9b9c253432c 100644 --- a/src/include/access/detoast.h +++ b/src/include/access/detoast.h @@ -12,6 +12,7 @@ #ifndef DETOAST_H #define DETOAST_H +#include "access/toast_compression.h" #include "varatt.h" /* @@ -40,12 +41,16 @@ do { \ /* * Decoded contents of an on-disk external TOAST pointer. + * + * compress_method is only meaningful if the value is compressed, that is if + * VARATT_EXTINFO_IS_COMPRESSED(extinfo, rawsize). */ typedef struct toast_external_data { vartag_external tag; /* VARTAG_ONDISK_* */ int32 rawsize; /* original data size (includes header) */ - uint32 extinfo; /* saved size + compression method */ + uint32 extinfo; /* saved size + compression method bits */ + ToastCompressionId compress_method; /* compression method ID */ Oid8 valueid; /* value ID (can be widened from Oid) */ Oid toastrelid; /* OID of the TOAST table containing it */ } toast_external_data; @@ -79,6 +84,9 @@ toast_external_info_get(const struct varlena *attr, toast_external_data *toast_e toast_ext_data->valueid = toast_pointer.va_valueid; toast_ext_data->toastrelid = toast_pointer.va_toastrelid; } + + toast_ext_data->compress_method = (ToastCompressionId) + VARATT_EXTINFO_GET_COMPRESS_METHOD(toast_ext_data->extinfo); } /* ---------- -- 2.54.0 (Apple Git-157)