Subject: [PATCH v10 4/8] Simplify autovacuum's TOAST-to-main-relation reloptions map.

From: Nathan Bossart <[email-masked]>
Date: Fri, 7 Aug 2026 10:55:34 -0500

do_autovacuum() adds an entry to this map for every relation that
has a TOAST table, and uses a flag to mark the entries that have no
reloptions to pass down.  The unconditional entry made sense back
when the payload was the main relation's OID: commit 7d4c9a5793
added the map so that the TOAST pass could find the parent, whose
pg_autovacuum row supplied the settings for a TOAST table that had
none of its own.  Commit 834a6da4f7 replaced that lookup by copying
the parent's reloptions into the entry, which left the OID unread
and called for the flag, since a by-value AutoVacOpts cannot say
"not set".

An entry is now worth creating only when there is something to
inherit, so skip the relations that have no reloptions and let a
successful lookup speak for itself.  Two relations cannot share a
TOAST table, and each pass sees a single catalog snapshot, so an
insertion can never find an existing entry; assert that rather than
quietly ignoring it.

While at it, remove two more leftovers of that same conversion:
ar_relid, unread ever since, and a NULL test on table_toast_map in
table_recheck_autovac(), which used to carry the relkind test for
get_pg_autovacuum_tuple_relid() and has had no NULL to catch since
that function went away.
---
 src/backend/postmaster/autovacuum.c | 26 +++++++-------------------
 1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index c8a1b66ca2e..32efe967890 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -200,8 +200,6 @@ typedef struct avw_dbase
 typedef struct av_relation
 {
 	Oid			ar_toastrelid;	/* hash key - must be first */
-	Oid			ar_relid;
-	bool		ar_hasrelopts;
 	StdRdOptions ar_reloptions; /* copy of main table's reloptions */
 } av_relation;
 
@@ -2097,7 +2095,7 @@ do_autovacuum(void)
 		 * this whether or not the table is going to be vacuumed, because we
 		 * don't automatically vacuum toast tables along the parent table.
 		 */
-		if (OidIsValid(classForm->reltoastrelid))
+		if (OidIsValid(classForm->reltoastrelid) && relopts)
 		{
 			av_relation *hentry;
 			bool		found;
@@ -2105,19 +2103,10 @@ do_autovacuum(void)
 			hentry = hash_search(table_toast_map,
 								 &classForm->reltoastrelid,
 								 HASH_ENTER, &found);
+			Assert(!found);		/* rels cannot share a TOAST table */
 
-			if (!found)
-			{
-				/* hash_search already filled in the key */
-				hentry->ar_relid = relid;
-				hentry->ar_hasrelopts = false;
-				if (relopts != NULL)
-				{
-					hentry->ar_hasrelopts = true;
-					memcpy(&hentry->ar_reloptions, relopts,
-						   sizeof(StdRdOptions));
-				}
-			}
+			/* hash_search already filled in the key */
+			memcpy(&hentry->ar_reloptions, relopts, sizeof(StdRdOptions));
 		}
 
 		/* Release stuff to avoid per-relation leakage */
@@ -2166,7 +2155,7 @@ do_autovacuum(void)
 			bool		found;
 
 			hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
-			if (found && hentry->ar_hasrelopts)
+			if (found)
 				relopts = &hentry->ar_reloptions;
 		}
 
@@ -2809,14 +2798,13 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 	relopts = (StdRdOptions *) extractRelOptions(classTup, pg_class_desc, NULL);
 	if (relopts)
 		free_relopts = true;
-	else if (classForm->relkind == RELKIND_TOASTVALUE &&
-			 table_toast_map != NULL)
+	else if (classForm->relkind == RELKIND_TOASTVALUE)
 	{
 		av_relation *hentry;
 		bool		found;
 
 		hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
-		if (found && hentry->ar_hasrelopts)
+		if (found)
 			relopts = &hentry->ar_reloptions;
 	}
 
-- 
2.50.1 (Apple Git-155)

--WiF/3tUCR6j/q9wa
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
	filename=v10-0005-Give-TOAST-storage-parameters-unsettable-default.patch