From d3b5460ed8a7eaff5e7d422b71740f82ddd2d07e Mon Sep 17 00:00:00 2001
From: David Geier <geidav.pg@gmail.com>
Date: Thu, 15 Oct 2026 21:37:37 +0200
Subject: [PATCH v6 6/7] Pack RelationData to eliminate padding

Reorder a small number of members to fill alignment gaps while retaining the
existing logical groups where they do not introduce padding.

sizeof(RelationData): 256 bytes
---
 src/backend/utils/cache/relcache.c |  2 +-
 src/include/utils/rel_internal.h   | 31 +++++++++++++++---------------
 2 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 7e71ac6e886..00ff0b079a5 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -93,7 +93,7 @@
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
 
-#define RELCACHE_INIT_FILEMAGIC		0x573268	/* version ID value */
+#define RELCACHE_INIT_FILEMAGIC		0x573269	/* version ID value */
 
 /*
  * Whether to bother checking if relation cache memory needs to be freed
diff --git a/src/include/utils/rel_internal.h b/src/include/utils/rel_internal.h
index 54b109ec1f7..040c0e3dee8 100644
--- a/src/include/utils/rel_internal.h
+++ b/src/include/utils/rel_internal.h
@@ -92,7 +92,6 @@ typedef struct RelationData
 
 			/* data managed by RelationGetFKeyList: */
 			List	   *rd_fkeylist;	/* list of ForeignKeyCacheInfo (see below) */
-			bool		rd_fkeyvalid;	/* true if rd_fkeylist has been computed */
 
 			/* data managed by RelationGetIndexList: */
 			List	   *rd_indexlist;	/* list of OIDs of indexes on relation */
@@ -100,11 +99,13 @@ typedef struct RelationData
 			bool		rd_ispkdeferrable;	/* is rd_pkindex a deferrable PK? */
 			bool		rd_indexvalid;	/* is rd_indexlist valid? (also rd_pkindex and
 									 * rd_replidindex) */
+			bool		rd_fkeyvalid;	/* true if rd_fkeylist has been computed */
+			bool		rd_attrsvalid;	/* are bitmaps of attrs valid? (see
+									 * RelationGetIndexAttrBitmap) */
+			bool		rd_statvalid;	/* is rd_statlist valid? */
 			Oid			rd_replidindex; /* OID of replica identity index, if any */
 
 			/* data managed by RelationGetIndexAttrBitmap: */
-			bool		rd_attrsvalid;	/* are bitmaps of attrs valid? (see
-									 * RelationGetIndexAttrBitmap) */
 			Bitmapset  *rd_keyattr;		/* cols that can be ref'd by foreign keys */
 			Bitmapset  *rd_pkattr;		/* cols included in primary key */
 			Bitmapset  *rd_idattr;		/* included in replica identity index */
@@ -113,7 +114,6 @@ typedef struct RelationData
 
 			/* data managed by RelationGetStatExtList: */
 			List	   *rd_statlist;	/* list of OIDs of extended stats */
-			bool		rd_statvalid;	/* is rd_statlist valid? */
 
 			/*
 			 * Table access method.
@@ -186,13 +186,14 @@ typedef struct RelationData
 		};
 	};
 
-	RelFileLocator rd_locator;	/* relation physical identifier */
 	SMgrRelation rd_smgr;		/* cached file handle, or NULL */
+	RelFileLocator rd_locator;	/* relation physical identifier */
 	int			rd_refcnt;		/* reference count */
 	ProcNumber	rd_backend;		/* owning backend's proc number, if temp rel */
 	bool		rd_islocaltemp; /* rel is a temp rel of this session */
 	bool		rd_isnailed;	/* rel is nailed in cache */
 	bool		rd_isvalid;		/* relcache entry is valid */
+	bool		pgstat_enabled; /* should relation stats be counted */
 
 	/*----------
 	 * rd_createSubid is the ID of the highest subtransaction the rel has
@@ -240,6 +241,16 @@ typedef struct RelationData
 	Form_pg_class rd_rel;		/* RELATION tuple */
 	TupleDesc	rd_att;			/* tuple descriptor */
 	Oid			rd_id;			/* relation's object id */
+
+	/*
+	 * Oid of the handler for this relation. For an index this is a function
+	 * returning IndexAmRoutine, for table like relations a function returning
+	 * TableAmRoutine.  This is stored separately from rd_indam, rd_tableam as
+	 * its lookup requires syscache access, but during relcache bootstrap we
+	 * need to be able to initialize rd_tableam without syscache lookups.
+	 */
+	Oid			rd_amhandler;	/* OID of index AM's handler function */
+
 	LockInfoData rd_lockInfo;	/* lock mgr's info for locking relation */
 
 	/*
@@ -256,15 +267,6 @@ typedef struct RelationData
 	 */
 	bytea	   *rd_options;		/* parsed pg_class.reloptions */
 
-	/*
-	 * Oid of the handler for this relation. For an index this is a function
-	 * returning IndexAmRoutine, for table like relations a function returning
-	 * TableAmRoutine.  This is stored separately from rd_indam, rd_tableam as
-	 * its lookup requires syscache access, but during relcache bootstrap we
-	 * need to be able to initialize rd_tableam without syscache lookups.
-	 */
-	Oid			rd_amhandler;	/* OID of index AM's handler function */
-
 	/*
 	 * rd_amcache is available for index and table AMs to cache private data
 	 * about the relation.  This must be just a cache since it may get reset
@@ -276,7 +278,6 @@ typedef struct RelationData
 	 */
 	void	   *rd_amcache;		/* available for use by index/table AM */
 
-	bool		pgstat_enabled; /* should relation stats be counted */
 	/* use "struct" here to avoid needing to include pgstat.h: */
 	struct PgStat_RelationStatus *pgstat_info;	/* statistics collection area */
 } RelationData;
-- 
2.53.0

