Hi,

When detoasting an expanded datum in detoast_attr, we already know it is
an expanded datum, but we use deotast_external_attr function which checks
VARATT_IS_EXTERNAL_ONDISK & VARATT_IS_EXTERNAL_INDIRECT again which I
think it is impossible to true in this case. so I think we should use a
more specific code to handle this, see the attached patch. 

We already have lots of kind of toast type and some of checks have
overlap, this cleanup should make people less confused when reading this
code. 

make check-world passed after applying this patch.

Any thought? 

-- 
Best Regards
Andy Fan

>From 91982d5b55e9f04cb17dd527659d7ecea82436a1 Mon Sep 17 00:00:00 2001
From: Andy Fan <zhihuifan1...@163.com>
Date: Tue, 29 Oct 2024 14:05:05 +0800
Subject: [PATCH v1 1/1] Using more specific code when detoasting an expanded
 datum.

In the detoast_attr function, VARATT_IS_EXTERNAL_ONDISK and
VARATT_IS_EXTERNAL_INDIRECT are checked first, and then
VARATT_IS_EXTERNAL_EXPANDED is checked, However when it's true,
detoast_external_attr is called which checks the two cases again.
The attached patch uses a more specific code to handle this.
---
 src/backend/access/common/detoast.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/common/detoast.c b/src/backend/access/common/detoast.c
index 3547cdba56..af25f589fe 100644
--- a/src/backend/access/common/detoast.c
+++ b/src/backend/access/common/detoast.c
@@ -89,6 +89,7 @@ detoast_external_attr(struct varlena *attr)
 		resultsize = EOH_get_flat_size(eoh);
 		result = (struct varlena *) palloc(resultsize);
 		EOH_flatten_into(eoh, (void *) result, resultsize);
+		Assert(!VARATT_IS_EXTENDED(result));
 	}
 	else
 	{
@@ -161,9 +162,15 @@ detoast_attr(struct varlena *attr)
 		/*
 		 * This is an expanded-object pointer --- get flat format
 		 */
-		attr = detoast_external_attr(attr);
-		/* flatteners are not allowed to produce compressed/short output */
-		Assert(!VARATT_IS_EXTENDED(attr));
+		ExpandedObjectHeader *eoh;
+		Size		resultsize;
+		struct varlena *result;
+
+		eoh = DatumGetEOHP(PointerGetDatum(attr));
+		resultsize = EOH_get_flat_size(eoh);
+		result = (struct varlena *) palloc(resultsize);
+		EOH_flatten_into(eoh, (void *) result, resultsize);
+		attr = result;
 	}
 	else if (VARATT_IS_COMPRESSED(attr))
 	{
-- 
2.45.1

Reply via email to