From 098dce72e7f73f91ee04447c589da1177ec49bd7 Mon Sep 17 00:00:00 2001
From: Nikhil Kumar Veldanda <veldanda.nikhilkumar17@gmail.com>
Date: Sat, 19 Jul 2025 23:07:41 +0000
Subject: [PATCH v26 14/15] Design to extend the varattrib_4b and toast pointer
 to support of multiple TOAST compression algorithms.

---
 contrib/amcheck/verify_heapam.c             |   5 +-
 src/backend/access/common/detoast.c         |   6 +-
 src/backend/access/common/toast_external.c  | 176 ++++++++++++++++++--
 src/backend/access/common/toast_internals.c |  27 ++-
 src/backend/access/heap/heaptoast.c         |  49 ++----
 src/backend/access/table/toast_helper.c     |  37 +++-
 src/include/access/toast_compression.h      |   6 +
 src/include/access/toast_helper.h           |   4 +-
 src/include/access/toast_internals.h        |  19 +--
 src/include/varatt.h                        | 115 +++++++++++--
 10 files changed, 335 insertions(+), 109 deletions(-)

diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 958b1451b4f..3a23dddcff4 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -1733,7 +1733,10 @@ check_tuple_attribute(HeapCheckContext *ctx)
 	{
 		uint8		va_tag = VARTAG_EXTERNAL(tp + ctx->offset);
 
-		if (va_tag != VARTAG_ONDISK_OID && va_tag != VARTAG_ONDISK_INT8)
+		if (va_tag != VARTAG_ONDISK_OID &&
+			va_tag != VARTAG_ONDISK_INT8 &&
+			va_tag != VARTAG_ONDISK_CE_INT8 &&
+			va_tag != VARTAG_ONDISK_CE_OID)
 		{
 			report_corruption(ctx,
 							  psprintf("toasted attribute has unexpected TOAST tag %u",
diff --git a/src/backend/access/common/detoast.c b/src/backend/access/common/detoast.c
index 684e1b0b7d3..34a3f7c6694 100644
--- a/src/backend/access/common/detoast.c
+++ b/src/backend/access/common/detoast.c
@@ -484,7 +484,7 @@ toast_decompress_datum(struct varlena *attr)
 	 * Fetch the compression method id stored in the compression header and
 	 * decompress the data using the appropriate decompression routine.
 	 */
-	cmid = TOAST_COMPRESS_METHOD(attr);
+	cmid = VARDATA_COMPRESSED_GET_COMPRESS_METHOD(attr);
 	switch (cmid)
 	{
 		case TOAST_PGLZ_COMPRESSION_ID:
@@ -520,14 +520,14 @@ toast_decompress_datum_slice(struct varlena *attr, int32 slicelength)
 	 * have been seen to give wrong results if passed an output size that is
 	 * more than the data's true decompressed size.
 	 */
-	if ((uint32) slicelength >= TOAST_COMPRESS_EXTSIZE(attr))
+	if ((uint32) slicelength >= VARDATA_COMPRESSED_GET_EXTSIZE(attr))
 		return toast_decompress_datum(attr);
 
 	/*
 	 * Fetch the compression method id stored in the compression header and
 	 * decompress the data slice using the appropriate decompression routine.
 	 */
-	cmid = TOAST_COMPRESS_METHOD(attr);
+	cmid = VARDATA_COMPRESSED_GET_COMPRESS_METHOD(attr);
 	switch (cmid)
 	{
 		case TOAST_PGLZ_COMPRESSION_ID:
diff --git a/src/backend/access/common/toast_external.c b/src/backend/access/common/toast_external.c
index 0e79ac8acae..5bf17ed7182 100644
--- a/src/backend/access/common/toast_external.c
+++ b/src/backend/access/common/toast_external.c
@@ -38,6 +38,15 @@ static struct varlena *ondisk_oid_create_external_data(toast_external_data data)
 static uint64 ondisk_oid_get_new_value(Relation toastrel, Oid indexid,
 									   AttrNumber attnum);
 
+/* Callbacks for VARTAG_ONDISK_CE_OID */
+static void ondisk_ce_oid_to_external_data(struct varlena *attr,
+										   toast_external_data *data);
+static struct varlena *ondisk_ce_oid_create_external_data(toast_external_data data);
+
+/* Callbacks for VARTAG_ONDISK_CE_INT8 */
+static void ondisk_ce_int8_to_external_data(struct varlena *attr,
+											toast_external_data *data);
+static struct varlena *ondisk_ce_int8_create_external_data(toast_external_data data);
 
 /*
  * Size of an EXTERNAL datum that contains a standard TOAST pointer
@@ -51,6 +60,18 @@ static uint64 ondisk_oid_get_new_value(Relation toastrel, Oid indexid,
  */
 #define TOAST_POINTER_OID_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external_oid))
 
+/*
+ * Size of an EXTERNAL datum that contains a TOAST pointer which supports extended compression methods
+ * (OID value).
+ */
+#define TOAST_POINTER_CE_OID_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external_ce_oid))
+
+/*
+ * Size of an EXTERNAL datum that contains a TOAST pointer which supports extended compression methods
+ * (int8 value).
+ */
+#define TOAST_POINTER_CE_INT8_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external_ce_int8))
+
 /*
  * For now there are only two types, all defined in this file.  For now this
  * is the maximum value of vartag_external, which is a historical choice.
@@ -72,6 +93,13 @@ static const toast_external_info toast_external_infos[TOAST_EXTERNAL_INFO_SIZE]
 		.create_external_data = ondisk_int8_create_external_data,
 		.get_new_value = ondisk_int8_get_new_value,
 	},
+	[VARTAG_ONDISK_CE_INT8] = {
+		.toast_pointer_size = TOAST_POINTER_CE_INT8_SIZE,
+		.maximum_chunk_size = TOAST_MAX_CHUNK_SIZE_INT8,
+		.to_external_data = ondisk_ce_int8_to_external_data,
+		.create_external_data = ondisk_ce_int8_create_external_data,
+		.get_new_value = ondisk_int8_get_new_value,
+	},
 	[VARTAG_ONDISK_OID] = {
 		.toast_pointer_size = TOAST_POINTER_OID_SIZE,
 		.maximum_chunk_size = TOAST_MAX_CHUNK_SIZE_OID,
@@ -79,6 +107,13 @@ static const toast_external_info toast_external_infos[TOAST_EXTERNAL_INFO_SIZE]
 		.create_external_data = ondisk_oid_create_external_data,
 		.get_new_value = ondisk_oid_get_new_value,
 	},
+	[VARTAG_ONDISK_CE_OID] = {
+		.toast_pointer_size = TOAST_POINTER_CE_OID_SIZE,
+		.maximum_chunk_size = TOAST_MAX_CHUNK_SIZE_OID,
+		.to_external_data = ondisk_ce_oid_to_external_data,
+		.create_external_data = ondisk_ce_oid_create_external_data,
+		.get_new_value = ondisk_oid_get_new_value,
+	},
 };
 
 
@@ -108,7 +143,7 @@ toast_external_info_get_pointer_size(uint8 tag)
 static void
 ondisk_int8_to_external_data(struct varlena *attr, toast_external_data *data)
 {
-	varatt_external_int8	external;
+	varatt_external_int8 external;
 
 	VARATT_EXTERNAL_GET_POINTER(external, attr);
 	data->rawsize = external.va_rawsize;
@@ -117,7 +152,7 @@ ondisk_int8_to_external_data(struct varlena *attr, toast_external_data *data)
 	if (VARATT_EXTERNAL_IS_COMPRESSED(external))
 	{
 		data->extsize = VARATT_EXTERNAL_GET_EXTSIZE(external);
-		data->compression_method = VARATT_EXTERNAL_GET_COMPRESS_METHOD(external);
+		data->compression_method = external.va_extinfo >> VARLENA_EXTSIZE_BITS;
 	}
 	else
 	{
@@ -141,10 +176,10 @@ ondisk_int8_create_external_data(toast_external_data data)
 
 	if (data.compression_method != TOAST_INVALID_COMPRESSION_ID)
 	{
+		/* Regular variants only support basic compression methods */
+		Assert(!CompressionMethodIdIsExtended(data.compression_method));
 		/* Set size and compression method, in a single field. */
-		VARATT_EXTERNAL_SET_SIZE_AND_COMPRESS_METHOD(external,
-													 data.extsize,
-													 data.compression_method);
+		external.va_extinfo = (uint32) data.extsize | ((uint32) data.compression_method << VARLENA_EXTSIZE_BITS);
 	}
 	else
 		external.va_extinfo = data.extsize;
@@ -165,8 +200,8 @@ ondisk_int8_get_new_value(Relation toastrel, Oid indexid,
 						  AttrNumber attnum)
 {
 	uint64		new_value;
-	SysScanDesc	scan;
-	ScanKeyData	key;
+	SysScanDesc scan;
+	ScanKeyData key;
 	bool		collides = false;
 
 retry:
@@ -181,8 +216,8 @@ retry:
 	CHECK_FOR_INTERRUPTS();
 
 	/*
-	 * Check if the new value picked already exists in the toast relation.
-	 * If there is a conflict, retry.
+	 * Check if the new value picked already exists in the toast relation. If
+	 * there is a conflict, retry.
 	 */
 	ScanKeyInit(&key,
 				attnum,
@@ -206,7 +241,7 @@ retry:
 static void
 ondisk_oid_to_external_data(struct varlena *attr, toast_external_data *data)
 {
-	varatt_external_oid		external;
+	varatt_external_oid external;
 
 	VARATT_EXTERNAL_GET_POINTER(external, attr);
 	data->rawsize = external.va_rawsize;
@@ -218,7 +253,7 @@ ondisk_oid_to_external_data(struct varlena *attr, toast_external_data *data)
 	if (VARATT_EXTERNAL_IS_COMPRESSED(external))
 	{
 		data->extsize = VARATT_EXTERNAL_GET_EXTSIZE(external);
-		data->compression_method = VARATT_EXTERNAL_GET_COMPRESS_METHOD(external);
+		data->compression_method = external.va_extinfo >> VARLENA_EXTSIZE_BITS;
 	}
 	else
 	{
@@ -240,10 +275,10 @@ ondisk_oid_create_external_data(toast_external_data data)
 
 	if (data.compression_method != TOAST_INVALID_COMPRESSION_ID)
 	{
+		/* Regular variants only support basic compression methods */
+		Assert(!CompressionMethodIdIsExtended(data.compression_method));
 		/* Set size and compression method, in a single field. */
-		VARATT_EXTERNAL_SET_SIZE_AND_COMPRESS_METHOD(external,
-													 data.extsize,
-													 data.compression_method);
+		external.va_extinfo = (uint32) data.extsize | ((uint32) data.compression_method << VARLENA_EXTSIZE_BITS);
 	}
 	else
 		external.va_extinfo = data.extsize;
@@ -264,3 +299,116 @@ ondisk_oid_get_new_value(Relation toastrel, Oid indexid,
 {
 	return GetNewOidWithIndex(toastrel, indexid, attnum);
 }
+
+/* Callbacks for VARTAG_ONDISK_CE_OID */
+static void
+ondisk_ce_oid_to_external_data(struct varlena *attr, toast_external_data *data)
+{
+	varatt_external_ce_oid external;
+
+	VARATT_EXTERNAL_GET_POINTER(external, attr);
+	data->rawsize = external.va_rawsize;
+
+	/*
+	 * External size and compression methods are stored in the different
+	 * fields, extract.
+	 */
+	if (VARATT_EXTERNAL_IS_COMPRESSED(external))
+	{
+		data->extsize = VARATT_EXTERNAL_GET_EXTSIZE(external);
+		data->compression_method = VARATT_CE_GET_COMPRESS_METHOD(external.va_ecinfo);
+	}
+	else
+	{
+		data->extsize = external.va_extinfo;
+		data->compression_method = TOAST_INVALID_COMPRESSION_ID;
+	}
+
+	data->value = (uint64) external.va_valueid;
+	data->toastrelid = external.va_toastrelid;
+}
+
+static struct varlena *
+ondisk_ce_oid_create_external_data(toast_external_data data)
+{
+	struct varlena *result = NULL;
+	varatt_external_ce_oid external;
+
+	external.va_rawsize = data.rawsize;
+
+	if (data.compression_method != TOAST_INVALID_COMPRESSION_ID)
+	{
+		Assert(CompressionMethodIdIsExtended(data.compression_method));
+		/* Set size and compression method. */
+		external.va_extinfo = (uint32) data.extsize | (VARATT_CE_FLAG << VARLENA_EXTSIZE_BITS);
+		VARATT_CE_SET_COMPRESS_METHOD(external.va_ecinfo, data.compression_method);
+	}
+	else
+		external.va_extinfo = data.extsize;
+
+	external.va_toastrelid = data.toastrelid;
+	external.va_valueid = (Oid) data.value;
+
+	result = (struct varlena *) palloc(TOAST_POINTER_CE_OID_SIZE);
+	SET_VARTAG_EXTERNAL(result, VARTAG_ONDISK_CE_OID);
+	memcpy(VARDATA_EXTERNAL(result), &external, sizeof(external));
+
+	return result;
+}
+
+/* Callbacks for VARTAG_ONDISK_CE_INT8 */
+static void
+ondisk_ce_int8_to_external_data(struct varlena *attr, toast_external_data *data)
+{
+	varatt_external_ce_int8 external;
+
+	VARATT_EXTERNAL_GET_POINTER(external, attr);
+	data->rawsize = external.va_rawsize;
+
+	/*
+	 * External size and compression methods are stored in the different
+	 * fields
+	 */
+	if (VARATT_EXTERNAL_IS_COMPRESSED(external))
+	{
+		data->extsize = VARATT_EXTERNAL_GET_EXTSIZE(external);
+		data->compression_method = VARATT_CE_GET_COMPRESS_METHOD(external.va_ecinfo);
+	}
+	else
+	{
+		data->extsize = external.va_extinfo;
+		data->compression_method = TOAST_INVALID_COMPRESSION_ID;
+	}
+
+	data->value = (((uint64) external.va_valueid_hi) << 32) |
+		external.va_valueid_lo;
+	data->toastrelid = external.va_toastrelid;
+}
+
+static struct varlena *
+ondisk_ce_int8_create_external_data(toast_external_data data)
+{
+	struct varlena *result = NULL;
+	varatt_external_ce_int8 external;
+
+	external.va_rawsize = data.rawsize;
+
+	if (data.compression_method != TOAST_INVALID_COMPRESSION_ID)
+	{
+		/* Set size and compression method. */
+		external.va_extinfo = (uint32) data.extsize | (VARATT_CE_FLAG << VARLENA_EXTSIZE_BITS);
+		VARATT_CE_SET_COMPRESS_METHOD(external.va_ecinfo, data.compression_method);
+	}
+	else
+		external.va_extinfo = data.extsize;
+
+	external.va_toastrelid = data.toastrelid;
+	external.va_valueid_hi = (((uint64) data.value) >> 32);
+	external.va_valueid_lo = (uint32) data.value;
+
+	result = (struct varlena *) palloc(TOAST_POINTER_CE_INT8_SIZE);
+	SET_VARTAG_EXTERNAL(result, VARTAG_ONDISK_CE_INT8);
+	memcpy(VARDATA_EXTERNAL(result), &external, sizeof(external));
+
+	return result;
+}
diff --git a/src/backend/access/common/toast_internals.c b/src/backend/access/common/toast_internals.c
index c6b2d1522ce..468aae64676 100644
--- a/src/backend/access/common/toast_internals.c
+++ b/src/backend/access/common/toast_internals.c
@@ -160,18 +160,6 @@ toast_save_datum(Relation rel, Datum value,
 	toast_typid = TupleDescAttr(toasttupDesc, 0)->atttypid;
 	Assert(toast_typid == OIDOID || toast_typid == INT8OID);
 
-	/*
-	 * Grab the information for toast_external_data.
-	 *
-	 * Note: if we support multiple external vartags for a single value
-	 * type, we would need to be smarter in the vartag selection.
-	 */
-	if (toast_typid == OIDOID)
-		tag = VARTAG_ONDISK_OID;
-	else if (toast_typid == INT8OID)
-		tag = VARTAG_ONDISK_INT8;
-	info = toast_external_get_info(tag);
-
 	/* Open all the toast indexes and look for the valid one */
 	validIndex = toast_open_indexes(toastrel,
 									RowExclusiveLock,
@@ -242,6 +230,18 @@ toast_save_datum(Relation rel, Datum value,
 	else
 		toast_pointer.toastrelid = RelationGetRelid(toastrel);
 
+	/*
+	 * Grab the information for toast_external_data.
+	 *
+	 * Note: if we support multiple external vartags for a single value type,
+	 * we would need to be smarter in the vartag selection.
+	 */
+	if (toast_typid == OIDOID)
+		tag = CompressionMethodIdIsExtended(toast_pointer.compression_method) ? VARTAG_ONDISK_CE_OID : VARTAG_ONDISK_OID;
+	else if (toast_typid == INT8OID)
+		tag = CompressionMethodIdIsExtended(toast_pointer.compression_method) ? VARTAG_ONDISK_CE_INT8 : VARTAG_ONDISK_INT8;
+	info = toast_external_get_info(tag);
+
 	/*
 	 * Choose a new value to use as the value ID for this toast value, be it
 	 * for OID or int8-based TOAST relations.
@@ -254,8 +254,7 @@ toast_save_datum(Relation rel, Datum value,
 	 * value (which is a corner case, but possible if the table's attstorage
 	 * options have been changed), we have to pick a value ID that doesn't
 	 * conflict with either new or existing toast value IDs.  If the TOAST
-	 * table uses 8-byte value IDs, we should not really care much about
-	 * that.
+	 * table uses 8-byte value IDs, we should not really care much about that.
 	 */
 	if (!OidIsValid(rel->rd_toastoid))
 	{
diff --git a/src/backend/access/heap/heaptoast.c b/src/backend/access/heap/heaptoast.c
index 87f1630d85f..7b03b27341f 100644
--- a/src/backend/access/heap/heaptoast.c
+++ b/src/backend/access/heap/heaptoast.c
@@ -152,7 +152,7 @@ heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
 	{
 		HeapTuple	atttuple;
 		Form_pg_attribute atttoast;
-		uint8		vartag = VARTAG_ONDISK_OID;
+		ToastTypeId toast_type = TOAST_TYPE_INVALID;
 
 		/*
 		 * XXX: This is very unlikely efficient, but it is not possible to
@@ -166,32 +166,22 @@ heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
 		atttoast = (Form_pg_attribute) GETSTRUCT(atttuple);
 
 		if (atttoast->atttypid == OIDOID)
-			vartag = VARTAG_ONDISK_OID;
+			toast_type = TOAST_TYPE_OID;
 		else if (atttoast->atttypid == INT8OID)
-			vartag = VARTAG_ONDISK_INT8;
+			toast_type = TOAST_TYPE_INT8;
 		else
 			Assert(false);
-		ttc.ttc_toast_pointer_size =
-			toast_external_info_get_pointer_size(vartag);
+		ttc.toast_type = toast_type;
 		ReleaseSysCache(atttuple);
 	}
 	else
 	{
 		/*
-		 * No TOAST relation to rely on, which is a case possible when
-		 * dealing with partitioned tables, for example.  Hence, do a best
-		 * guess based on the GUC default_toast_type.
+		 * No TOAST relation to rely on, which is a case possible when dealing
+		 * with partitioned tables, for example.  Hence, do a best guess based
+		 * on the GUC default_toast_type.
 		 */
-		uint8	vartag = VARTAG_ONDISK_OID;
-
-		if (default_toast_type == TOAST_TYPE_INT8)
-			vartag = VARTAG_ONDISK_INT8;
-		else if (default_toast_type == TOAST_TYPE_OID)
-			vartag = VARTAG_ONDISK_OID;
-		else
-			Assert(false);
-		ttc.ttc_toast_pointer_size =
-			toast_external_info_get_pointer_size(vartag);
+		ttc.toast_type = default_toast_type;
 	}
 
 	ttc.ttc_rel = rel;
@@ -693,9 +683,7 @@ heap_fetch_toast_slice(Relation toastrel, uint64 valueid, int32 attrsize,
 	int			endchunk;
 	int			num_indexes;
 	int			validIndex;
-	int32		max_chunk_size;
-	const toast_external_info *info;
-	uint8		tag = VARTAG_INDIRECT;  /* init value does not matter */
+	int32		max_chunk_size = TOAST_MAX_CHUNK_SIZE_OID;
 	Oid			toast_typid = InvalidOid;
 
 	/* Look for the valid index of toast relation */
@@ -708,26 +696,23 @@ heap_fetch_toast_slice(Relation toastrel, uint64 valueid, int32 attrsize,
 	 * Grab the information for toast_external_data.
 	 *
 	 * Note: there is no access to the vartag of the original varlena from
-	 * which we are trying to retrieve the chunks from the TOAST relation,
-	 * so guess the external TOAST pointer information to use depending
-	 * on the attribute of the TOAST value.  If we begin to support multiple
-	 * external TOAST pointers for a single attribute type, we would need
-	 * to pass down this information from the upper callers.  This is
-	 * currently on required for the maximum chunk_size.
+	 * which we are trying to retrieve the chunks from the TOAST relation, so
+	 * guess the external TOAST pointer information to use depending on the
+	 * attribute of the TOAST value.  If we begin to support multiple external
+	 * TOAST pointers for a single attribute type, we would need to pass down
+	 * this information from the upper callers.  This is currently on required
+	 * for the maximum chunk_size.
 	 */
 	toast_typid = TupleDescAttr(toastrel->rd_att, 0)->atttypid;
 	Assert(toast_typid == OIDOID || toast_typid == INT8OID);
 
 	if (toast_typid == OIDOID)
-		tag = VARTAG_ONDISK_OID;
+		max_chunk_size = TOAST_MAX_CHUNK_SIZE_OID;
 	else if (toast_typid == INT8OID)
-		tag = VARTAG_ONDISK_INT8;
+		max_chunk_size = TOAST_MAX_CHUNK_SIZE_INT8;
 	else
 		Assert(false);
 
-	info = toast_external_get_info(tag);
-	max_chunk_size = info->maximum_chunk_size;
-
 	totalchunks = ((attrsize - 1) / max_chunk_size) + 1;
 	startchunk = sliceoffset / max_chunk_size;
 	endchunk = (sliceoffset + slicelength - 1) / max_chunk_size;
diff --git a/src/backend/access/table/toast_helper.c b/src/backend/access/table/toast_helper.c
index a2b44e093d7..b87d3177bc3 100644
--- a/src/backend/access/table/toast_helper.c
+++ b/src/backend/access/table/toast_helper.c
@@ -15,6 +15,7 @@
 #include "postgres.h"
 
 #include "access/detoast.h"
+#include "access/toast_external.h"
 #include "access/toast_helper.h"
 #include "access/toast_internals.h"
 #include "catalog/pg_type_d.h"
@@ -51,10 +52,19 @@ toast_tuple_init(ToastTupleContext *ttc)
 		Form_pg_attribute att = TupleDescAttr(tupleDesc, i);
 		struct varlena *old_value;
 		struct varlena *new_value;
+		uint8		vartag = VARTAG_ONDISK_OID;
+
+		if (ttc->toast_type == TOAST_TYPE_OID)
+			vartag = CompressionMethodIsExtended(att->attcompression) ? VARTAG_ONDISK_CE_OID : VARTAG_ONDISK_OID;
+		else if (ttc->toast_type == TOAST_TYPE_INT8)
+			vartag = CompressionMethodIsExtended(att->attcompression) ? VARTAG_ONDISK_CE_INT8 : VARTAG_ONDISK_INT8;
+		else
+			Assert(false);
 
 		ttc->ttc_attr[i].tai_colflags = 0;
 		ttc->ttc_attr[i].tai_oldexternal = NULL;
 		ttc->ttc_attr[i].tai_compression = att->attcompression;
+		ttc->ttc_attr[i].toast_pointer_size = toast_external_info_get_pointer_size(vartag);
 
 		if (ttc->ttc_oldvalues != NULL)
 		{
@@ -171,10 +181,10 @@ toast_tuple_init(ToastTupleContext *ttc)
  * The column must have attstorage EXTERNAL or EXTENDED if check_main is
  * false, and must have attstorage MAIN if check_main is true.
  *
- * The column must have a minimum size of MAXALIGN(tcc_toast_pointer_size);
- * if not, no benefit is to be expected by compressing it.  The TOAST
- * pointer size is given by the caller, depending on the type of TOAST
- * table we are dealing with.
+ * Each column must have a minimum size of MAXALIGN(toast_pointer_size) for
+ * that specific column; if not, no benefit is to be expected by compressing it.
+ * The TOAST pointer size varies per column based on the TOAST table type
+ * (OID vs INT8) and different variants used for that specific attribute.
  *
  * The return value is the index of the biggest suitable column, or
  * -1 if there is none.
@@ -190,16 +200,13 @@ toast_tuple_find_biggest_attribute(ToastTupleContext *ttc,
 	int32		skip_colflags = TOASTCOL_IGNORE;
 	int			i;
 
-	/* Define the lower-bound */
-	biggest_size = MAXALIGN(ttc->ttc_toast_pointer_size);
-	Assert(biggest_size != 0);
-
 	if (for_compression)
 		skip_colflags |= TOASTCOL_INCOMPRESSIBLE;
 
 	for (i = 0; i < numAttrs; i++)
 	{
 		Form_pg_attribute att = TupleDescAttr(tupleDesc, i);
+		int32		min_size_for_column;
 
 		if ((ttc->ttc_attr[i].tai_colflags & skip_colflags) != 0)
 			continue;
@@ -214,7 +221,19 @@ toast_tuple_find_biggest_attribute(ToastTupleContext *ttc,
 			att->attstorage != TYPSTORAGE_EXTERNAL)
 			continue;
 
-		if (ttc->ttc_attr[i].tai_size > biggest_size)
+		/*
+		 * Each column has its own minimum size threshold based on its TOAST
+		 * pointer size
+		 */
+		min_size_for_column = MAXALIGN(ttc->ttc_attr[i].toast_pointer_size);
+		Assert(min_size_for_column > 0);
+
+		/*
+		 * Only consider this column if it's bigger than its specific
+		 * threshold AND bigger than current biggest
+		 */
+		if (ttc->ttc_attr[i].tai_size > min_size_for_column &&
+			ttc->ttc_attr[i].tai_size > biggest_size)
 		{
 			biggest_attno = i;
 			biggest_size = ttc->ttc_attr[i].tai_size;
diff --git a/src/include/access/toast_compression.h b/src/include/access/toast_compression.h
index 13c4612ceed..494e1b0dce6 100644
--- a/src/include/access/toast_compression.h
+++ b/src/include/access/toast_compression.h
@@ -51,6 +51,12 @@ typedef enum ToastCompressionId
 #define InvalidCompressionMethod		'\0'
 
 #define CompressionMethodIsValid(cm)  ((cm) != InvalidCompressionMethod)
+#define CompressionMethodIsExtended(cm)	(!(cm == TOAST_PGLZ_COMPRESSION ||		\
+										   cm == TOAST_LZ4_COMPRESSION ||		\
+										   cm == InvalidCompressionMethod))
+#define CompressionMethodIdIsExtended(cmpid)	(!(cmpid == TOAST_PGLZ_COMPRESSION_ID ||	\
+												   cmpid == TOAST_LZ4_COMPRESSION_ID ||		\
+												   cmpid == TOAST_INVALID_COMPRESSION_ID))
 
 
 /* pglz compression/decompression routines */
diff --git a/src/include/access/toast_helper.h b/src/include/access/toast_helper.h
index 729c593afeb..e0ae11a581c 100644
--- a/src/include/access/toast_helper.h
+++ b/src/include/access/toast_helper.h
@@ -14,6 +14,7 @@
 #ifndef TOAST_HELPER_H
 #define TOAST_HELPER_H
 
+#include "access/toast_type.h"
 #include "utils/rel.h"
 
 /*
@@ -33,6 +34,7 @@ typedef struct
 	int32		tai_size;
 	uint8		tai_colflags;
 	char		tai_compression;
+	int32		toast_pointer_size;
 } ToastAttrInfo;
 
 /*
@@ -47,11 +49,11 @@ typedef struct
 	 * should be NULL in the case of an insert.
 	 */
 	Relation	ttc_rel;		/* the relation that contains the tuple */
-	int32		ttc_toast_pointer_size;	/* size of external TOAST pointer */
 	Datum	   *ttc_values;		/* values from the tuple columns */
 	bool	   *ttc_isnull;		/* null flags for the tuple columns */
 	Datum	   *ttc_oldvalues;	/* values from previous tuple */
 	bool	   *ttc_oldisnull;	/* null flags from previous tuple */
+	ToastTypeId toast_type;		/* toast table type */
 
 	/*
 	 * Before calling toast_tuple_init, the caller should set ttc_attr to
diff --git a/src/include/access/toast_internals.h b/src/include/access/toast_internals.h
index 06ae8583c1e..27bc8a0b816 100644
--- a/src/include/access/toast_internals.h
+++ b/src/include/access/toast_internals.h
@@ -17,32 +17,17 @@
 #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); \
+		((varattrib_4b *)(ptr))->va_compressed.va_tcinfo = \
+			((uint32)(len)) | ((uint32)(cm_method) << VARLENA_EXTSIZE_BITS); \
 	} while (0)
 
 extern Datum toast_compress_datum(Datum value, char cmethod);
diff --git a/src/include/varatt.h b/src/include/varatt.h
index aa36e8e1f56..52b17c349c3 100644
--- a/src/include/varatt.h
+++ b/src/include/varatt.h
@@ -53,17 +53,41 @@ typedef struct varatt_external_int8
 	int32		va_rawsize;		/* Original data size (includes header) */
 	uint32		va_extinfo;		/* External saved size (without header) and
 								 * compression method */
+
 	/*
-	 * Unique ID of value within TOAST table, as two uint32 for alignment
-	 * and padding.
-	 * XXX: think for example about the addition of an extra field for
-	 * meta-data and/or more compression data, even if it's OK here).
+	 * Unique ID of value within TOAST table, as two uint32 for alignment and
+	 * padding.
 	 */
 	uint32		va_valueid_lo;
 	uint32		va_valueid_hi;
 	Oid			va_toastrelid;	/* RelID of TOAST table containing it */
 }			varatt_external_int8;
 
+typedef struct varatt_external_ce_oid
+{
+	int32		va_rawsize;		/* Original data size (includes header) */
+	uint32		va_extinfo;		/* External saved size (without header) and
+								 * VARATT_CE_FLAG in top 2 bits */
+	uint32		va_ecinfo;		/* Extended compression info */
+	Oid			va_valueid;		/* Unique ID of value within TOAST table */
+	Oid			va_toastrelid;	/* RelID of TOAST table containing it */
+}			varatt_external_ce_oid;
+
+typedef struct varatt_external_ce_int8
+{
+	int32		va_rawsize;		/* Original data size (includes header) */
+	uint32		va_extinfo;		/* External saved size (without header) and
+								 * VARATT_CE_FLAG in top 2 bits */
+	uint32		va_ecinfo;		/* Extended compression info */
+
+	/*
+	 * Unique ID of value within TOAST table, as two uint32 for alignment and
+	 * padding.
+	 */
+	uint32		va_valueid_lo;
+	uint32		va_valueid_hi;
+	Oid			va_toastrelid;	/* RelID of TOAST table containing it */
+}			varatt_external_ce_int8;
 
 /*
  * These macros define the "saved size" portion of va_extinfo.  Its remaining
@@ -115,6 +139,8 @@ typedef enum vartag_external
 	VARTAG_EXPANDED_RO = 2,
 	VARTAG_EXPANDED_RW = 3,
 	VARTAG_ONDISK_INT8 = 4,
+	VARTAG_ONDISK_CE_OID = 5,
+	VARTAG_ONDISK_CE_INT8 = 6,
 	VARTAG_ONDISK_OID = 18
 } vartag_external;
 
@@ -127,6 +153,8 @@ typedef enum vartag_external
 	 VARTAG_IS_EXPANDED(tag) ? sizeof(varatt_expanded) : \
 	 (tag) == VARTAG_ONDISK_OID ? sizeof(varatt_external_oid) : \
 	 (tag) == VARTAG_ONDISK_INT8 ? sizeof(varatt_external_int8) : \
+	 (tag) == VARTAG_ONDISK_CE_OID ? sizeof(varatt_external_ce_oid): \
+	 (tag) == VARTAG_ONDISK_CE_INT8 ? sizeof(varatt_external_ce_int8): \
 	 (AssertMacro(false), 0))
 
 /*
@@ -152,6 +180,21 @@ typedef union
 								 * compression method; see va_extinfo */
 		char		va_data[FLEXIBLE_ARRAY_MEMBER]; /* Compressed data */
 	}			va_compressed;
+	struct
+	{
+		uint32		va_header;
+		uint32		va_tcinfo;	/* Original data size (excludes header) and
+								 * compression method or VARATT_CE_FLAG flag;
+								 * see va_extinfo */
+		uint32		va_ecinfo;	/* Extended compression info: 32-bit field
+								 * where only the lower 8 bits are used for
+								 * compression method. Upper 24 bits are
+								 * reserved/unused. Lower 8 bits layout: Bits
+								 * 7–1: encode (cmid − 2), so cmid is
+								 * [2…129] Bit 0: flag for extra metadata
+								 */
+		char		va_data[FLEXIBLE_ARRAY_MEMBER];
+	}			va_compressed_ext;
 } varattrib_4b;
 
 typedef struct
@@ -321,8 +364,13 @@ typedef struct
 	(VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_ONDISK_OID)
 #define VARATT_IS_EXTERNAL_ONDISK_INT8(PTR) \
 	(VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_ONDISK_INT8)
+#define VARATT_IS_EXTERNAL_ONDISK_CE_OID(PTR) \
+	(VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_ONDISK_CE_OID)
+#define VARATT_IS_EXTERNAL_ONDISK_CE_INT8(PTR) \
+	(VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_ONDISK_CE_INT8)
 #define VARATT_IS_EXTERNAL_ONDISK(PTR) \
-	(VARATT_IS_EXTERNAL_ONDISK_OID(PTR) || VARATT_IS_EXTERNAL_ONDISK_INT8(PTR))
+	(VARATT_IS_EXTERNAL_ONDISK_OID(PTR) || VARATT_IS_EXTERNAL_ONDISK_INT8(PTR) \
+	 || VARATT_IS_EXTERNAL_ONDISK_CE_OID(PTR) || VARATT_IS_EXTERNAL_ONDISK_CE_INT8(PTR))
 #define VARATT_IS_EXTERNAL_INDIRECT(PTR) \
 	(VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_INDIRECT)
 #define VARATT_IS_EXTERNAL_EXPANDED_RO(PTR) \
@@ -359,10 +407,15 @@ typedef struct
 	 (VARATT_IS_1B(PTR) ? VARDATA_1B(PTR) : VARDATA_4B(PTR))
 
 /* Decompressed size and compression method of a compressed-in-line Datum */
-#define VARDATA_COMPRESSED_GET_EXTSIZE(PTR) \
-	(((varattrib_4b *) (PTR))->va_compressed.va_tcinfo & VARLENA_EXTSIZE_MASK)
+#define VARDATA_COMPRESSED_GET_EXTSIZE(PTR)														\
+	(																							\
+		(VARATT_IS_EXTENDED_COMPRESSED(PTR))													\
+			? ( ((varattrib_4b *)(PTR))->va_compressed_ext.va_tcinfo & VARLENA_EXTSIZE_MASK )	\
+			: ( ((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)
+	( (VARATT_IS_EXTENDED_COMPRESSED(PTR)) ? VARATT_CE_GET_COMPRESS_METHOD(((varattrib_4b *) (PTR))->va_compressed_ext.va_ecinfo) \
+	: (((varattrib_4b *) (PTR))->va_compressed.va_tcinfo >> VARLENA_EXTSIZE_BITS))
 
 /*
  * Same for external Datums; but note argument is a struct
@@ -370,16 +423,6 @@ typedef struct
  */
 #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
@@ -393,5 +436,41 @@ typedef struct
  (VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer) < \
   (toast_pointer).va_rawsize - VARHDRSZ)
 
+/* Extended compression flag (0b11) marks use of extended compression methods */
+#define VARATT_CE_FLAG             0x3
+
+/*
+ * Extended compression info encoding (8-bit layout):
+ *
+ *   bit 7   6   5   4   3   2   1   0
+ *  +---+---+---+---+---+---+---+---+
+ *  |      compression_id       | M |
+ *  +---+---+---+---+---+---+---+---+
+ *
+ * • Bits 7–1: Compression method ID offset (cmid − 2)
+ *   Range: [0…127] maps to compression ID [2…129]
+ *
+ * • Bit 0 (M): Metadata flag (currently unused, always 0)
+ *   Reserved for future use to indicate extra compression metadata
+ */
+#define VARATT_CE_SET_COMPRESS_METHOD(va_ecinfo, cmid)		\
+	do {													\
+		uint8 _cmid = (uint8)(cmid);						\
+		Assert(_cmid >= 2 && _cmid <= 129);					\
+		(va_ecinfo) = (uint32)((_cmid - 2) << 1);			\
+	} while (0)
+
+#define VARATT_CE_GET_COMPRESS_METHOD(ecinfo)	((((uint8)(ecinfo) >> 1) & 0x7F) + 2)
+
+/* Test if varattrib_4b uses extended compression format */
+#define VARATT_IS_EXTENDED_COMPRESSED(ptr) \
+	((((varattrib_4b *)(ptr))->va_compressed_ext.va_tcinfo >> VARLENA_EXTSIZE_BITS) \
+		== VARATT_CE_FLAG)
+
+/* Access compressed data payload in extended format */
+#define VARDATA_EXTENDED_COMPRESSED(ptr) \
+	(((varattrib_4b *)(ptr))->va_compressed_ext.va_data)
+
+#define VARHDRSZ_EXTENDED_COMPRESSED	(offsetof(varattrib_4b, va_compressed_ext.va_data))
 
 #endif
-- 
2.47.1

